class WindowShowUnetFitting(WindowInterface): ############################################################## # ---------------- init stuff -------------------------------- ############################################################## def __init__(self, x_data, y_data, y_predicted): super(WindowShowUnetFitting, self).__init__() with open('config_full_system.json') as config_fp: self.label_size = json.load(config_fp)['gui']['qt_label_size'] self.main_layout = MyGridWidget(hbox_control=self.hbox_control) self.setCentralWidget(self.main_layout) self.showFullScreen() self.update_main_layout(x_data, y_data, y_predicted) def _init_hbox_control(self): self.hbox_control = QtWidgets.QHBoxLayout() self.hbox_control.addStretch(1) self.hbox_control.addWidget( ControlButton("Update", self.update_main_layout)) self.hbox_control.addWidget(ControlButton("Quit", self.quit_default)) ############################################################## # ---------------- gui logic stuff --------------------------- ############################################################## def clear(self): self.main_layout.clear() def update_main_layout(self, x_data, y_data, y_predicted): self.clear() label_list = [] for x, y, y_answer in zip(x_data, y_data, y_predicted): label_list.append( ImageTextLabel(x=x, text='input', label_size=self.label_size)) label_list.append( ImageTextLabel(x=y, text='output', label_size=self.label_size)) label_list.append( ImageTextLabel(x=y_answer, text='U-Net answer', label_size=self.label_size)) x_len = 3 self.main_layout.update_grid( windows_width=self.frameGeometry().width(), window_height=self.frameGeometry().height(), x_len=x_len, y_len=int(x_data.shape[0] * 3 / x_len), label_list=label_list)
class WindowClassificationPicture(WindowInterface): ############################################################## # ---------------- init stuff -------------------------------- ############################################################## def __init__(self): self.already_marked_dir = 'Datasets/legacy_jsons/agro' self.already_marked_list = os.listdir(self.already_marked_dir) super(WindowClassificationPicture, self).__init__() self.setWindowTitle("Plant Disease Recognizer") # TODO some dev stuff # with open(self.choose_json(content_title='config data')) as config_fp: with open('config_create_json.json') as config_fp: config_dict = json.load(config_fp) # self.img_path = self.choose_picture() # self.img_name = os.path.splitext(self.img_path)[0] self.window_shape = config_dict['window_shape'] self.classes = config_dict['classes'] self.default_label_size = config_dict['qt_label_size'] self.img_thumb = config_dict['img_thumb'] self._init_hbox_control() self._init_main_menu() self.main_layout = MyGridWidget(hbox_control=self.hbox_control) self.setCentralWidget(self.main_layout) self.showFullScreen() self.choose_and_render_image() # for offset calculation self.last_x = 0 self.last_y = 0 def choose_and_render_image(self): self.img_path = self.choose_picture() if self.img_path != '': self.clear() self.img_name = os.path.splitext(self.img_path)[0] self._init_images() self._init_label_list() self.update_main_layout() def _init_hbox_control(self): self.hbox_control = QtWidgets.QHBoxLayout() self.zoom_list = [0.25, 0.5, 0.75, 1] self.zoom = self.zoom_list[0] self.zoom_no = 0 self.hbox_control.addWidget( ControlButton("Okay", self.okay_pressed, styleSheet='background-color: #0cdb3c')) self.hbox_control.addWidget( ControlButton("Choose image", self.choose_and_render_image, styleSheet='background-color: #ffbe25')) self.hbox_control.addWidget( ControlButton("Quit", self.quit_default, styleSheet='background-color: #e84a1a')) def _init_main_menu(self): mainMenu = self.menuBar() zoomMenu = mainMenu.addMenu('Zoom') def add_zoom_to_menu(new_zoom): newAct = QAction('Zoom %d %%' % (zoom * 100), self) newAct.triggered.connect(lambda: self.change_zoom(new_zoom)) zoomMenu.addAction(newAct) for zoom in self.zoom_list: add_zoom_to_menu(zoom) #################################################################################### # ------------------------ MOUSE DRAGGING PART ------------------------------------- #################################################################################### def mousePressEvent(self, event): # TODO to fix if hasattr(self, 'img_name'): rect = list( map(lambda x: x * self.zoom_list[self.zoom_no], self.full_img.size)) self.first_x = max(0, min(int(rect[0]), event.x() + self.last_x)) self.first_y = max(0, min(int(rect[1]), event.y() + self.last_y)) print("event ", event.x(), event.y()) print("last ", self.last_x, self.last_y) print("press offset ", self.first_x, self.first_y) def mouseMoveEvent(self, event): if hasattr(self, 'img_name'): self.v_bar = self.main_layout.left_scroll_area.verticalScrollBar() self.h_bar = self.main_layout.left_scroll_area.horizontalScrollBar( ) rect = list( map(lambda x: x * self.zoom_list[self.zoom_no], self.full_img.size)) if self.main_layout.width() < rect[0]: x = self.first_x - event.x() y = self.first_y - event.y() self.last_x = x self.last_y = y print("\n\nDRAG OFFSET:", x, y) self.main_layout.set_offset(x, y) #################################################################################### # ------------------------ WHEEL PART ---------------------------------------------- #################################################################################### # mouse wheel event scrollо def wheelEvent(self, event): if hasattr(self, 'img_name'): modifiers = QApplication.keyboardModifiers() if modifiers == QtCore.Qt.ControlModifier: if event.angleDelta().y() > 0: if self.zoom_no < len(self.zoom_list) - 1: self.zoom_no += 1 else: if self.zoom_no > 0: self.zoom_no -= 1 self.change_zoom(self.zoom_list[self.zoom_no]) self.move_by_cursor() def move_by_cursor(self): cursor_x = QtGui.QCursor.pos().x() cursor_y = QtGui.QCursor.pos().y() window_width = self.main_layout.width() window_height = self.main_layout.height() rect = list( map(lambda x: x * self.zoom_list[self.zoom_no], self.full_img.size)) real_image_width = int(rect[0]) real_image_height = int(rect[1]) print("x coor ", cursor_x, window_width, real_image_width) if (real_image_width < window_width | real_image_height < window_height): print("nothing to move") else: koef_x = (cursor_x) / real_image_width koef_y = (cursor_y) / real_image_height offset_x = (real_image_width - window_width) * koef_x offset_y = (real_image_height - window_height) * koef_y # TODO famous math constant 4 and 2 x = int(offset_x * 4) y = int(offset_y * 2) print("\n\nZOOM OFFSET:", x, y) self.main_layout.set_offset(x, y) # TODO maybe someday zoom will work # self.last_x = x # self.last_y = y #################################################################################### # ------------------------ ZOOM PART ----------------------------------------------- #################################################################################### def change_zoom(self, new_zoom): self.zoom = new_zoom print('new zoom = %d' % self.zoom) self.update_main_layout() def _init_images(self): def get_marked_indexes(): marked_indexes = [] pref_path = self.img_path.split('.')[0].split('/')[-1] if pref_path in list( map(lambda repeat_file: repeat_file.split('.')[0], self.already_marked_list)): with open("%s/%s.json" % (self.already_marked_dir, pref_path)) as repeat_fp: x_repeated = np.array(json.load(repeat_fp)['x_data'], dtype='uint8') mae_threshold = 1.2 # experimental for i, x in enumerate(self.x_data_full['x_data']): for rep_i, rep_x in enumerate(x_repeated): mae = abs((x - rep_x).astype('int8')).mean() if mae < mae_threshold: print('%d->%d:mae = %.3f' % (rep_i, i, mae)) marked_indexes.append(i) break if len(marked_indexes) != len(x_repeated): raise Exception('bad threshold') return marked_indexes self.pre_rendered_img_dict = {} QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) print("rendering image...") self.x_data_full, self.full_img = \ dmk.get_x_from_croped_img( path_to_img=self.img_path, window_shape=self.window_shape, step=1.0, verbose=True ) print("ok") self.marked_indexes = get_marked_indexes() QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) print("ok") def _init_label_list(self): self.label_list = [] for i, x in enumerate(self.x_data_full['x_data']): if i in self.marked_indexes: img_data = x * 10 else: img_data = x self.label_list.append( MergedTrainExLabel(x_data=img_data, classes=self.classes, label_size=self.default_label_size)) ############################################################## # ---------------- gui logic stuff --------------------------- ############################################################## def clear(self): self.main_layout.clear() def update_main_layout(self): self.clear() for label in self.label_list: label.updateImage(label_size=list( map(lambda x: x * self.zoom, self.default_label_size))) self.main_layout.update_grid( windows_width=self.main_layout.max_width, window_height=self.main_layout.max_height, x_len=int(self.full_img.size[0] / self.x_data_full["x_data"].shape[1]), y_len=int(self.full_img.size[1] / self.x_data_full["x_data"].shape[2]), label_list=self.label_list) print("img_size = %s\nex_num = %d\n" % (str(self.full_img.size), len(self.x_data_full['x_data']))) def okay_pressed(self): y_data = np.empty(0) for class_name in self.classes.keys(): for sub_class_name in self.classes[class_name]: self.classes[class_name][sub_class_name]['num'] = 0 # Now we're going to store only examples of diseased plants x_data_full = { 'x_data': np.empty(0, dtype='uint8'), 'x_coord': [], 'longitudes': [], 'latitudes': [] } ex_num = 0 for x, label in zip(self.x_data_full['x_data'], self.main_layout.label_list): if label.class_name is not None: x_data_full['x_data'] = np.append(x_data_full['x_data'], x) y_data = np.append( y_data, self.classes[label.class_name][ label.sub_class_name]['value']) self.classes[label.class_name][ label.sub_class_name]['num'] += 1 ex_num += 1 x_data_full['x_data'].shape = (ex_num, *self.window_shape) y_data.shape = (len(x_data_full['x_data']), 1) dmk.json_train_create(path="%s.json" % self.img_name, x_data_full=x_data_full, y_data=y_data, img_shape=self.full_img.size, classes=self.classes) print("OKAY") self.choose_and_render_image()
class WindowShowPredictions(WindowInterface): ############################################################## # ---------------- init stuff -------------------------------- ############################################################## def __init__(self, x_data, y_data, y_predicted, classes): super(WindowShowPredictions, self).__init__() config_dict = self.load_dict_from_json_with_keys( key_list=['qt_label_size']) self.label_size = config_dict['qt_label_size'] self.x_data = x_data self.y_data = y_data self.y_predicted = y_predicted self.classes = classes self._define_max_key_len() self.main_layout = MyGridWidget(hbox_control=self.hbox_control) self.setCentralWidget(self.main_layout) self.showFullScreen() self.update_main_layout() def _init_hbox_control(self): self.hbox_control = QtWidgets.QHBoxLayout() self.hbox_control.addStretch(1) self.hbox_control.addWidget( ControlButton("Update", self.update_main_layout)) self.hbox_control.addWidget(ControlButton("Quit", self.quit_default)) def _define_max_key_len(self): self.max_key_len = 0 for key, value in self.classes.items(): if len(key) > self.max_key_len: self.max_key_len = len(key) ############################################################## # ---------------- gui logic stuff --------------------------- ############################################################## def clear(self): self.main_layout.clear() def update_main_layout(self): self.clear() def get_key_by_answer(pos_code): answer = {'mae': 9999, 'key': None, 'value': 0} for key in self.classes.keys(): mae = np.average(abs((self.classes[key]['value'] - pos_code))) if mae < answer['mae']: answer['mae'] = mae answer['key'] = key answer['value'] = max(pos_code) return answer def add_spaces(word, new_size): # TODO fix gui label alignment while len(word) < new_size: word += '_' return word label_list = [] for x, y, y_answer in zip(self.x_data, self.y_data, self.y_predicted): answer = get_key_by_answer(pos_code=y_answer) right_ans = get_key_by_answer(pos_code=y) is_right_ans = True if answer['key'] == right_ans['key'] else False answer['key'] = add_spaces(answer['key'], new_size=self.max_key_len) label_list.append( ImageTextLabel(x=x, text='%s %.2f' % (answer['key'], answer['value']), label_size=self.label_size)) if is_right_ans: label_list[-1].text_label.setStyleSheet( 'background-color: green') else: label_list[-1].text_label.setStyleSheet( 'background-color: red') rect_len = int(np.sqrt(len(self.x_data))) self.main_layout.update_grid( windows_width=self.frameGeometry().width(), window_height=self.frameGeometry().height(), x_len=rect_len, y_len=rect_len, label_list=label_list)
class WindowPredictOnImage(WindowInterface): ############################################################## # ---------------- init stuff -------------------------------- ############################################################## def __init__(self): super(WindowPredictOnImage, self).__init__() with open(os.path.abspath('config_full_system.json')) as config_fp: self.config_dict = json.load(config_fp) # load layers self.clusterer = get_clusterer_by_name( self.config_dict['clusterer']['name'], self.config_dict['clusterer']['args']) if self.config_dict['preprocessor']['use']: self.segmentator = get_preprocessor_by_name( self.config_dict['preprocessor']['name'], self.config_dict['preprocessor']['args']) self.classifier = get_classifier_by_name( self.config_dict['classifier']['name'], self.config_dict['classifier']['args']) self.bad_key = self.config_dict['classifier']['bad_key'] self._define_max_key_len() self._parse_image() self.main_layout = MyGridWidget(hbox_control=self.hbox_control) self.pbar = QProgressBar(self) self.main_layout.layout.addWidget(self.pbar) self.right_text_labels = [] self.setCentralWidget(self.main_layout) self.showFullScreen() self.update_main_layout() def _init_hbox_control(self): self.hbox_control = QtWidgets.QHBoxLayout() self.hbox_control.addStretch(1) self.hbox_control.addWidget( ControlButton("Predict", self.update_main_layout)) self.hbox_control.addWidget( ControlButton("Choose model", self.choose_NN)) self.hbox_control.addWidget( ControlButton("Choose image", self._parse_image)) self.hbox_control.addWidget(ControlButton("Quit", self.quit_default)) def _parse_image(self): self.picture_path = self.choose_picture() x_cropped = self.clusterer.cluster(self.picture_path) self.x_data = x_cropped['x_data'] def _define_max_key_len(self): self.max_key_len = 0 for key, value in self.classifier.classes.items(): if len(key) > self.max_key_len: self.max_key_len = len(key) def clear(self): self.main_layout.clear() for text_label in self.right_text_labels: text_label.setParent(None) def update_main_layout(self): self.clear() self.predict_thread = PredictThread(self) fake_timer = FakeTimer(self) fake_timer.valueChanged.connect(self.predict_thread.valueChanged.emit) self.predict_thread.valueChanged.connect(self.pbar.setValue) self.predict_thread.canDraw.connect(self.draw_result) self.predict_thread.fakeTimerToStop.connect(fake_timer.terminate) self.main_layout.update_scroll( windows_width=self.frameGeometry().width(), window_height=self.frameGeometry().height(), ) # self.x_data = self.x_data[:4] self.predict_thread.start() fake_timer.start() def draw_result(self): def get_key_by_answer(pos_code, bad_key): answer = {'mae': 9999, 'key': bad_key, 'value': 0} if sum(pos_code) > 0: for key in self.classifier.classes.keys(): mae = np.average( abs((self.classifier.classes[key]['value'] - pos_code))) if mae < answer['mae']: answer['mae'] = mae answer['key'] = key answer['value'] = max(pos_code) return answer label_list = [] classes_dict = self.classifier.classes.copy() classes_dict[self.bad_key] = {} for key in [*classes_dict.keys(), self.bad_key]: classes_dict[key]['num'] = 0 classes_dict[key]['indexes'] = [] for i, (x, y_answer) in enumerate( zip(self.x_data, self.predict_thread.y_answer)): answer = get_key_by_answer(pos_code=y_answer, bad_key=self.bad_key) classes_dict[answer['key']]['num'] += 1 classes_dict[answer['key']]['indexes'].append(i) answer['key'] += (self.max_key_len - len(answer['key'])) * " " answer['key'] = "%d: %s" % (i, answer['key']) label_list.append( ImageTextLabel( x=x, text='%s %.2f' % (answer['key'], answer['value']), label_size=self.config_dict['gui']['qt_label_size'])) self.right_text_labels = [] for key in classes_dict: text_label = QLabel() text_label.setText("%s: %d" % (key, classes_dict[key]['num'])) text_label.setAlignment(QtCore.Qt.AlignLeft) print("%s: %s" % (key, str(classes_dict[key]['indexes']))) self.right_text_labels.append(text_label) self.main_layout.right_layout.addWidget(text_label) rect_len = int(np.sqrt(len(self.x_data))) self.main_layout.update_grid( windows_width=self.frameGeometry().width(), window_height=self.frameGeometry().height(), x_len=rect_len, y_len=rect_len, label_list=label_list) def choose_NN(self): self.weights_path = str( QtWidgets.QFileDialog.getOpenFileName(self, "Open *.h5 with NN weights", "models", "*.h5 *.H5")[0]) self.structure_path = str( QtWidgets.QFileDialog.getOpenFileName( self, "Open *.json with NN structure", "models", "*.json *.JSON")[0]) if os.path.isfile(self.weights_path) and os.path.isfile( self.structure_path): self.classifier = get_full_model(json_path=self.structure_path, h5_path=self.weights_path) else: print( "Files with model weights and model structure does't choosed")
class WindowMultipleExamples(WindowInterface): ############################################################## # ---------------- init stuff -------------------------------- ############################################################## def __init__(self, json_list): super(WindowMultipleExamples, self).__init__() self.postfix = 'joined' self.label_size = (224, 224) # TODO maybe will be restored someday # with open(self.choose_json(content_title='config augmentation data')) as aug_config_fp: with open('config_data_augmentation.json') as aug_config_fp: aug_config_dict = json.load(aug_config_fp) alghs_dict = aug_config_dict['algorithms'] self.max_aug_part = aug_config_dict['aug_part'] self.augment_all = aug_config_dict['augment_all'] self.output_json = aug_config_dict['output_json'] self.save_data_binary = aug_config_dict['save_data_to_binary'] self.save_data_dir = aug_config_dict['save_data_to_dir'] for key, value in alghs_dict.items(): if value['use'] and len( value['val_list']) != self.max_aug_part: raise Exception('bad val_list size for %s' % key) self.arg_dict = { 'use_noise': alghs_dict['noise']['use'], 'intensity_noise_list': alghs_dict['noise']['val_list'], 'use_deform': alghs_dict['deform']['use'], 'k_deform_list': alghs_dict['deform']['val_list'], 'use_blur': alghs_dict['blur']['use'], 'rad_list': alghs_dict['blur']['val_list'], 'use_affine': alghs_dict['affine']['use'], 'affine_list': alghs_dict['affine']['val_list'], 'use_contrast': alghs_dict['contrast']['use'], 'contrast_list': alghs_dict['contrast']['val_list'] } if json_list == None: raise Exception('No passed json') self.json_name = os.path.splitext(json_list[0])[0] if len(json_list) == 1: print('Parsing preprocessed json') self.classes, img_shape, self.x_data, self.y_data = \ dmk.json_big_load(json_list[0]) self.x_data = np.array(self.x_data, dtype='uint8') self.y_data = np.array(self.y_data, dtype='uint8') else: print('Parsing json list') self.classes, self.x_data, self.y_data = dmk.get_data_from_json_list( json_list=json_list, # remove_classes=None, # TODO some dev stuff remove_classes=[ 'альтернариоз', 'прочие инфекции', 'морщинистая мозаика', 'полосатая мозаика' ]) self.init_size = len(self.x_data) self.img_shape = self.x_data.shape[1:] # TODO some dev stuff # self.classes['здоровый куст'] = self.classes['марь белая'] # del self.classes['марь белая'] # self.classes['мозаика'] = self.classes['прочие мозаики'] # del self.classes['прочие мозаики'] # self.classes['сорняк'] = self.classes['прочие сорняки'] # del self.classes['прочие сорняки'] self._define_max_class() self.main_layout = MyGridWidget(hbox_control=self.hbox_control) self.setCentralWidget(self.main_layout) self.showFullScreen() self.show_full() print("---------------------------------") print('classes = %s' % str(self.classes)) print('max_classes = %s' % str(self.max_aug_for_classes)) print('ex_num = %d' % sum(map(lambda x: x['num'], self.classes.values()))) print("---------------------------------") self.show_histogram(labels=list(self.classes.keys()), values=list( map(lambda val: val['num'], self.classes.values()))) def _init_hbox_control(self): self.hbox_control = QtWidgets.QHBoxLayout() self.hbox_control.addStretch(1) self.hbox_control.addWidget(ControlButton("Okay", self.okay_pressed)) self.hbox_control.addWidget(ControlButton("Show Full", self.show_full)) self.hbox_control.addWidget( ControlButton("Multiple", self.multiple_pressed)) self.hbox_control.addWidget(ControlButton("Quit", self.quit_default)) def _define_max_class(self): self.max_class = {'name': None, 'num': 0, 'value': None} self.max_key_len = 0 self.max_aug_for_classes = {} for key, value in self.classes.items(): if self.classes[key]['num'] > self.max_class['num']: self.max_class['name'] = key self.max_class['num'] = self.classes[key]['num'] self.max_class['value'] = self.classes[key]['value'] if len(key) > self.max_key_len: self.max_key_len = len(key) self.max_aug_for_classes[key] = self.classes[key]['num'] \ + int(self.classes[key]['num'] * self.max_aug_part) ############################################################## # ---------------- gui logic stuff --------------------------- ############################################################## def show_histogram(self, labels, values, title='Diseases distribution'): import matplotlib.pyplot as plt import numpy as np x = np.arange(len(labels)) # the label locations width = 0.35 # the width of the bars fig, ax = plt.subplots() rects1 = ax.bar(x - width / 2, values, width, label='Examples num') # Add some text for labels, title and custom x-axis tick labels, etc. ax.set_ylabel('Num') ax.set_title(title) ax.set_xticks(x) ax.set_xticklabels(labels) ax.legend() def autolabel(rects): """Attach a text label above each bar in *rects*, displaying its height.""" for rect in rects: height = rect.get_height() ax.annotate( '{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), # 3 points vertical offset textcoords="offset points", ha='center', va='bottom') autolabel(rects1) fig.tight_layout() plt.xticks(rotation=45) plt.show() def clear(self): self.main_layout.clear() def show_full(self): self.clear() def get_key_by_value(value): for key in self.classes.keys(): if (self.classes[key]['value'] == value).all(): return key raise Exception('No value == %s' % str(value)) label_list = [] for x, y in zip(self.x_data, self.y_data): label_text = get_key_by_value(value=y) label_text += (self.max_key_len - len(label_text)) * " " label_list.append( ImageTextLabel(x=x, text=label_text, label_size=self.label_size)) rect_len = int(np.sqrt(len(self.x_data))) self.main_layout.update_grid(windows_width=self.main_layout.max_width, window_height=self.main_layout.max_height, x_len=rect_len, y_len=rect_len, label_list=label_list) def okay_pressed(self): print("Save to %s" % self.output_json) for key in self.classes.keys(): self.classes[key]['value'] = list( self.classes[key]['value'].flatten()) if self.save_data_binary: ################################################################################### # ------------------------ be aware of SIGKILL ------------------------------------ ################################################################################### binary_path = dir_path = "/".join(self.output_json.split('/')[:-1]) + "/" \ + self.output_json.split('/')[-1][:-5] + ".hd5f" dmk.json_big_create(json_path=self.output_json, h5_path=binary_path, x_data=self.x_data, y_data=self.y_data, longitudes=None, latitudes=None, img_shape=None, classes=self.classes) elif self.save_data_dir: ################################################################################### # we can not pass array with size 10_000 * 256 * 256 * 3 to function, shout SIGKILL ################################################################################### dir_path = "/".join(self.output_json.split('/')[:-1]) \ + "/" + self.output_json.split('/')[-1][:-5] id = [] label = [] if not dir_path: raise Exception("Data directory %s need to be existed" % dir_path) for key in self.classes.keys(): self.classes[key]['value_num'] = dmk.get_num_from_pos( self.classes[key]['value']) self.classes[key]['saved_num'] = 0 for i, (x, y) in enumerate(zip(self.x_data, self.y_data)): for key in self.classes.keys(): if (self.classes[key]['value'] == y).all(): file_path = "%s/%d.JPG" % (dir_path, i + 1) Image.fromarray(x).save(file_path) print("%s saved" % file_path) id.append(file_path) label.append(key) with open(self.output_json, "w") as fp: json.dump( { "classes": self.classes, "img_shape": None, "dir_path": dir_path, "longitudes": None, "latitudes": None, "dataframe": { "id": id, "label": label } }, fp) fp.close() self.quit_default() def multiple_pressed(self): if self.augment_all: if sum(map(lambda x: x['num'], self.classes.values()) ) < self.init_size * self.max_aug_part: # ----------------------------------- augment all ----------------------------------------------------- old_class_size = len(self.x_data) x_data_new, y_data_new = dmk.multiple_class_examples( x_train=self.x_data[:self.init_size], y_train=self.y_data[:self.init_size], **self.arg_dict, max_class_num=self.init_size * self.max_aug_part, mode='all') self.x_data = np.append(self.x_data, x_data_new) self.y_data = np.append(self.y_data, y_data_new) ex_num = int(self.y_data.shape[0] / len(self.classes)) self.x_data.shape = (ex_num, *self.img_shape) self.y_data.shape = (ex_num, len(self.classes)) for key, value in self.classes.items(): new_ex_num = len(self.x_data) - old_class_size print('%s : generated %d new examples' % (key, new_ex_num)) self.classes[key]['num'] = 0 for y in self.y_data: if ((y.__eq__(self.classes[key]['value'])).all()): self.classes[key]['num'] += 1 else: print('ex_num = max_num') else: # ----------------------------------- augment by classes --------------------------------------------- for key, value in self.classes.items(): if self.classes[key]['num'] < self.max_aug_for_classes[key]: max_class_num = self.max_aug_for_classes[key] old_class_size = len(self.x_data) x_data_new, y_data_new = dmk.multiple_class_examples( x_train=self.x_data[:self.init_size], y_train=self.y_data[:self.init_size], class_for_mult=self.classes[key]['value'], **self.arg_dict, max_class_num=max_class_num) self.x_data = np.append(self.x_data, x_data_new) self.y_data = np.append(self.y_data, y_data_new) ex_num = int(self.y_data.shape[0] / len(self.classes)) self.x_data.shape = (ex_num, *self.img_shape) self.y_data.shape = (ex_num, len(self.classes)) new_ex_num = len(self.x_data) - old_class_size print('%s : generated %d new examples' % (key, new_ex_num)) self.classes[key]['num'] = 0 for y in self.y_data: if ((y.__eq__(self.classes[key]['value'])).all()): self.classes[key]['num'] += 1 else: print( '%s : generated %d new examples (class_size == max_size)' % (key, 0)) print("---------------------------------") print('classes = %s' % str(self.classes)) print('ex_num = %d' % sum(map(lambda x: x['num'], self.classes.values()))) print("---------------------------------") self.show_histogram(labels=list(self.classes.keys()), values=list( map(lambda val: val['num'], self.classes.values())), title='Diseases distribution after augmentation') self.show_augmentation() def show_augmentation(self): self.clear() label_list = [] for i in [0, 1, 2]: label_list.append( ImageTextLabel(x=self.x_data[i], text='original', label_size=self.label_size)) for j in range(1, int(self.max_aug_part) + 1): label_text = 'aug %.2f' % self.arg_dict['contrast_list'][j - 1] label_list.append( ImageTextLabel(x=self.x_data[i + j * self.init_size], text=label_text, label_size=self.label_size), ) x_len = j + 1 y_len = int(len(label_list) / x_len) self.main_layout.update_grid(windows_width=self.main_layout.max_width, window_height=self.main_layout.max_height, x_len=x_len, y_len=y_len, label_list=label_list)