1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
| # -*- coding: utf-8 -*-
import sys
from PyQt5 import QtGui
from UI.mainWindow import MainWindow as mWindow
import UI.uiFunction as uiFunction
import Controller.functions as cFunctions
import _pickle as cPickle
import random
class Silhouette(mWindow):
def __init__(self, app):
self.app = app # виджет приложения
self.window = mWindow() # окно программы
uiFunction.connect_signal_to_widget(widget=self.window, signalName='startWork',
function=self._start_work) # привязка сигнала startWork и функции self._start_work к виджету окна
uiFunction.connect_signal_to_widget(widget=self.window, signalName='saveToBase',
function=self._save_to_base) # привязка сигнала saveToBase и функции self._save_to_base к виджету окна
uiFunction.connect_signal_to_widget(widget=self.window.userImage, signalName='imageLoaded',
function=self._image_loaded_event) # привязка сигнала imageLoaded и функции self._image_loaded к виджету картинки пользователя
uiFunction.connect_signal_to_widget(widget=self.window, signalName='drawNewContour',
function=self._draw_new_contour) # привязка сигнала drawNewContour и функции self._draw_new_contour к виджету окна
def start(self):
"""
Запуск окна программы
"""
self.window.show() # отображение окна программы
def _image_loaded_event(self):
"""
Дополнительная настройка, выполняющаяся после того, как пользователь загрузит картинку
срабатывает при загрузке новой картинки
"""
self.window.labelContourNumber.setText(u'Контур № 1') # отображение первого номера контура
if self.window.userImage.contours is None: # если контуры не нашлись, то выходим
return
contoursCount = len(self.window.userImage.contours) - 1 # определяем количество контуров (нумерация с 0)
if contoursCount < 0: # если значение количества контуров отрицаетльное, значит контуры не были найдены
uiFunction.show_warning_dialog(self.window,
text=u'Контуры не найдены.') # показываем сообщение с ощибкой и выходим из функции
return
self.window.sliderContourNumber.setMaximum(contoursCount) # выставляем в слайдере нужное количество контуров
if contoursCount >= 1: # если контуров много ставим по умолчанию первый (0 - скорее всего будет втнутренним контуром фигуры)
self.window.sliderContourNumber.setValue(1)
self.window.userWord.clear() # очистка названия картинки программы
def _draw_new_contour(self):
"""
Отрисовка нового контура
"""
self.window.userImage.draw_contour(contourNumber=self.window.get_contour_number(),
size=5) # рисуем выбранный контур
self.window.userImage.draw_image_on_ui() # отрисовываем картинку с новым контуром
def _start_work(self):
"""
Фунция начала работы над картинкой
"""
imageName, imageSource = self._get_user_image_data() # получение данных о картинке
checkImageName, checkImageSource = self._check_image_data(imageName, imageSource) # проверка полученных данных
if checkImageName and not checkImageSource: # условие на поиск картинки по имени
imageDataFromBase = cFunctions.get_image_from_base(imageName) # получаем картинку из базы
if imageDataFromBase is not None: # проверка на пустой ответ из базы
image = imageDataFromBase[random.randint(0, len(imageDataFromBase) - 1)] # берем сдучайную картинку
self.window.userImage.listOfControlPoint = cPickle.loads(
str(image['imageData'])) # получаем данные о 360 точках для отрисовки
self.window.userImage.load_image(blob=image['imageSource']) # загружаем картинку в форму
else:
uiFunction.show_warning_dialog(self.window,
text=u'Ничего не нашлось.') # если из базы ничего не пришло, нужно сообщить об этом
if not checkImageName and checkImageSource: # условие на поиск имени по картинке
imageData = self._get_image_data() # получаем опорные точки загруженной картинки
imageName = cFunctions.get_name_by_image(imageData) # ищем в базе название похожей картинки
if imageName is not None: # если что-то нашлось
self.window.userWord.setText(imageName) # выводим найденное название
else:
uiFunction.show_warning_dialog(self.window,
text=u'Ничего не нашлось.\nСкорее всего база пустая.') # если из базы ничего не пришло, нужно сообщить об этом
def _save_to_base(self):
"""
Сохранение загруженной картинки в базу
"""
imageName, imageSource = self._get_user_image_data() # получение данных о картинке
checkImageName, checkImageSource = self._check_image_data(imageName, imageSource,
fullCheck=True) # полная проверка полученных данных
if checkImageName and checkImageSource: # если все данные введены
imageData = self._get_image_data() # получаем опорные точки загруженной картинки
cFunctions.add_to_base(imageName, imageSource, imageData) # добавляем новую картинку в базу
def _get_image_data(self):
"""
Возвращает нужные для анализа картинки данные
@return: list
"""
contourCoordinates = uiFunction.get_image_contour_coordinates(self.window.userImage.cvImage,
self.window.get_contour_number()) # получаем координаты контура
gravityCenter = uiFunction.get_image_gravity_center(
self.window.userImage.cvImage) # получаем центр масс картинки
imageSize = self.window.userImage.get_image_size() # получаем размеры картинки
imageData = cFunctions.get_image_data(contourCoordinates, gravityCenter,
imageSize) # находим интересующие нас данные для картинки
return imageData
def _get_user_image_data(self):
"""
Возвращает информацию которую ввел пользоваель
"""
imageName = self.window.get_user_image_name() # получаем название, которое ввел пользователь
imageSource = self.window.userImage.imageBlob # получаем бинарные данные картинки пользователя
return imageName, imageSource
def _check_image_data(self, imageName, imageSource, fullCheck=False):
"""
Определение какие данные были введены и сообщение о не введенных данных
@param imageName: string = название картинки
@param imageSource: blob = бинарные данные картинки
@param fullCheck: True | False = полная проверка ввседенных данных
@return: bool, bool = непустое название, непустые данные
"""
checkImageName = True # флаг проверки названия картиинки
checkImageSource = True # флаг проверки данных картиинки
if imageName == '' or imageName is None: # проверка на пустое значение названия картинки
if fullCheck: # если используется полная проверка
uiFunction.show_warning_dialog(self.window,
text=u'Название картинки не должно быть пустым.') # если название пустое, то показать окно с ошибкой и выйти
checkImageName = False # проверка названия не пройдена
if imageSource is None: # проверка на пустое значение картинки
if fullCheck: # если используется полная проверка
uiFunction.show_warning_dialog(self.window,
text=u'Картинка не загружена.') # если название пустое, то показать окно с ошибкой и выйти
checkImageSource = False # проверка данных не пройдена
if not (checkImageName or checkImageSource) and not fullCheck: # если обе проверки не пройдены
uiFunction.show_warning_dialog(self.window,
text=u'Нет данных для работы.') # если название пустое, то показать окно с ошибкой и вый
if checkImageName and checkImageSource and not fullCheck: # если обе проверки пройдены и используем кнопку "work"
uiFunction.show_warning_dialog(self.window,
text=u'Данных слишом много, нужно ввести что-то одно\nкартинку или название.') # если название пустое, то показать окно с ошибкой и вый
return checkImageName, checkImageSource |