From 25c68aa0aaf9b045ed6651e466606ecc56141728 Mon Sep 17 00:00:00 2001 From: karakurai Date: Thu, 5 Sep 2024 22:48:43 +0900 Subject: [PATCH] v1.3.0 --- camera_setting_screen.kv | 4 +- inspection_setting_screen.kv | 4 +- main_screen.kv | 107 ++++++++++++++++++++++++++++++++++- main_screen.py | 99 +++++++++++++++++++++++++++++++- making_dataset_screen.py | 9 +-- target_area_screen.kv | 4 +- target_area_screen.py | 2 +- text.ini | 18 +++++- 8 files changed, 232 insertions(+), 15 deletions(-) diff --git a/camera_setting_screen.kv b/camera_setting_screen.kv index 5be9d00..f21a9db 100644 --- a/camera_setting_screen.kv +++ b/camera_setting_screen.kv @@ -10,7 +10,7 @@ id: message halign: "center" size_hint: 1, .1 - color: 1, 1, 1, 1 + color: 1, 1, 1, 1 text: app.textini[app.lang]["camera_settings"] + " " + app.textini[app.lang]["step"] + " 1/2 : " + app.textini[app.lang]["cs_camera_choice"] padding: "4dp", "4dp" MDBoxLayout: @@ -154,7 +154,7 @@ title: app.textini[app.lang]["label_copyright"] icon: "close" type: "bottom" - mode: "end" + mode: "end" on_action_button: app.popup_open() CameraView: id: camera_view diff --git a/inspection_setting_screen.kv b/inspection_setting_screen.kv index ac050b1..e43a604 100644 --- a/inspection_setting_screen.kv +++ b/inspection_setting_screen.kv @@ -10,7 +10,7 @@ id: message halign: "center" size_hint: 1, .1 - color: 1, 1, 1, 1 + color: 1, 1, 1, 1 text: app.textini[app.lang]["inspection_settings"] + " " + app.textini[app.lang]["is_top_message"] padding: "4dp", "4dp" MDLabel: @@ -36,7 +36,7 @@ title: app.textini[app.lang]["label_copyright"] icon: "close" type: "bottom" - mode: "end" + mode: "end" on_action_button: app.popup_open() MDFloatLayout: MDGridLayout: diff --git a/main_screen.kv b/main_screen.kv index 33a467b..742c726 100644 --- a/main_screen.kv +++ b/main_screen.kv @@ -90,6 +90,7 @@ background_color: "blue" font_size: "22sp" text: app.textini[app.lang]["main_inspect_image"] + disabled: True on_release: main_image_view.get_images(-1) MDFloatLayout: @@ -194,13 +195,22 @@ pos: 1000, 500 size_hint: .4, .3 rows: 6 - cols: 2 + cols: 3 MDLabel: text: app.textini[app.lang]["main_inspected_image"] font_size: "14sp" + size_hint_x: None + width: 270 MDLabel: text: app.textini[app.lang]["main_result"] font_size: "14sp" + size_hint_x: None + width: 110 + MDLabel: + id : text_save_train_image + text: app.textini[app.lang]["main_save_train_image"] + font_size: "14sp" + opacity: 0 MDLabel: id: preprocessing_0 font_size: "14sp" @@ -210,6 +220,15 @@ md_bg_color: "black" font_size: "14sp" on_release: main_image_view.show_image(0) + MDRaisedButton: + id: save_0 + text: app.textini[app.lang]["main_save"] + text_color: "white" + md_bg_color: "black" + font_size: "14sp" + on_release: main_image_view.show_save_image(0) + disabled: True + opacity: 0 MDLabel: id: preprocessing_1 font_size: "14sp" @@ -219,6 +238,15 @@ md_bg_color: "black" font_size: "14sp" on_release: main_image_view.show_image(1) + MDRaisedButton: + id: save_1 + text: app.textini[app.lang]["main_save"] + text_color: "white" + md_bg_color: "black" + font_size: "14sp" + on_release: main_image_view.show_save_image(1) + disabled: True + opacity: 0 MDLabel: id: preprocessing_2 font_size: "14sp" @@ -228,6 +256,15 @@ md_bg_color: "black" font_size: "14sp" on_release: main_image_view.show_image(2) + MDRaisedButton: + id: save_2 + text: app.textini[app.lang]["main_save"] + text_color: "white" + md_bg_color: "black" + font_size: "14sp" + on_release: main_image_view.show_save_image(2) + disabled: True + opacity: 0 MDLabel: id: preprocessing_3 font_size: "14sp" @@ -237,6 +274,15 @@ md_bg_color: "black" font_size: "14sp" on_release: main_image_view.show_image(3) + MDRaisedButton: + id: save_3 + text: app.textini[app.lang]["main_save"] + text_color: "white" + md_bg_color: "black" + font_size: "14sp" + on_release: main_image_view.show_save_image(3) + disabled: True + opacity: 0 MDLabel: id: preprocessing_4 font_size: "14sp" @@ -246,6 +292,15 @@ md_bg_color: "black" font_size: "14sp" on_release: main_image_view.show_image(4) + MDRaisedButton: + id: save_4 + text: app.textini[app.lang]["main_save"] + text_color: "white" + md_bg_color: "black" + font_size: "14sp" + on_release: main_image_view.show_save_image(4) + disabled: True + opacity: 0 MDFloatLayout: MDRaisedButton: id: message @@ -254,7 +309,7 @@ text_color: "white" md_bg_color: "black" font_size: "18sp" - text: app.textini[app.lang]["main_massage_no_inspection"] + text: app.textini[app.lang]["main_massage_loading_camera"] id: popup_image_screen @@ -286,4 +341,52 @@ size_hint: 1, .1 MDFillRoundFlatButton: text: app.textini[app.lang]["ok_a"] + on_release: root.dismiss_popup() + + + id: popup_save_image_screen + orientation: 'vertical' + MDBoxLayout: + size_hint: 1, .05 + MDLabel: + id: popup_save_title + size_hint: .8, .1 + halign: "center" + adaptive_height: True + text: app.textini[app.lang]["main_save_image_title"] + MDBoxLayout: + size_hint: 1, .05 + MDLabel: + id: popup_save_dir_path + size_hint: .8, .1 + halign: "center" + adaptive_height: True + MDLabel: + size_hint: 1, .05 + text: "" + MDBoxLayout: + size_hint: 1, .75 + Image: + id: popup_save_image + size: 800, 800 + allow_stretch: True + keep_ratio: True + MDBoxLayout: + size_hint: 1, .1 + MDRaisedButton: + id: normal + text: app.textini[app.lang]["main_save_normal"] + text_color: "white" + md_bg_color: "blue" + on_release: root.save_image(0) + MDRaisedButton: + id: anomaly + text: app.textini[app.lang]["main_save_anomaly"] + text_color: "white" + md_bg_color: "red" + on_release: root.save_image(1) + MDLabel: + text: "" + MDFillRoundFlatButton: + text: app.textini[app.lang]["main_save_cancel"] on_release: root.dismiss_popup() \ No newline at end of file diff --git a/main_screen.py b/main_screen.py index 98b06df..687321a 100644 --- a/main_screen.py +++ b/main_screen.py @@ -75,14 +75,33 @@ def start_screen(self): self.ids["get_image_button_" + str(i)].disabled = False if api_info_num > 1: self.ids["change_button"].disabled = False + else: + self.ids["message"].text = self.app.textini[self.app.lang][ + "main_massage_no_inspection" + ] + self.ids["message"].text_color = "white" + self.ids["message"].md_bg_color = "black" def leave_screen(self): self.ids["main_image_view"].stop_clock() self.ids["main_image_view"].clear() self.app.release_cameras() self.ids["message"].text = self.app.textini[self.app.lang][ - "main_massage_no_inspection" + "main_massage_loading_camera" ] + self.ids["message"].text_color = "white" + self.ids["message"].md_bg_color = "black" + self.ids["get_image_button"].disabled = True + self.ids["get_image_button_0"].disabled = True + self.ids["get_image_button_1"].disabled = True + self.ids["get_image_button_2"].disabled = True + self.ids["get_image_button_3"].disabled = True + self.ids["get_image_button_4"].disabled = True + self.ids["save_0"].disabled = True + self.ids["save_1"].disabled = True + self.ids["save_2"].disabled = True + self.ids["save_3"].disabled = True + self.ids["save_4"].disabled = True self.api_list = [] self.aimodel_list = [] for i in range(5): @@ -197,6 +216,22 @@ def show_image_popup(self, image_path, title="Image", result=None): self.app.popup_is_open = True self.popup.open() + def show_save_image_popup(self, image_path, index): + if self.popup is None: + title = "Save Image " + str(index) + ":" + self.api_list[int(index)]["NAME"] + new_popup = Popup( + title=title, + content=PopupSaveImageScreen(dismiss_popup=self.dismiss_popup), + size_hint=(0.9, 0.9), + ) + new_popup.content.set_image_path_and_name( + image_path, self.api_list[int(index)]["NAME"] + ) + new_popup.title = title + self.popup = new_popup + self.app.popup_is_open = True + self.popup.open() + def dismiss_popup(self): self.popup.dismiss() self.popup = None @@ -491,8 +526,14 @@ def do_inspection( if not save_image_flg: os.remove(save_image_path) self.inspection_image_path_list[int(index)] = None + self.screen.ids["text_save_train_image"].opacity = 0 + self.screen.ids["save_" + str(index)].opacity = 0 + self.screen.ids["save_" + str(index)].disabled = True else: self.inspection_image_path_list[int(index)] = save_image_path + self.screen.ids["text_save_train_image"].opacity = 1 + self.screen.ids["save_" + str(index)].opacity = 1 + self.screen.ids["save_" + str(index)].disabled = False if result_json is not None: with open(result_csv_path, "a", newline="") as f: writer = csv.writer(f) @@ -523,6 +564,14 @@ def show_result_image(self, result_num, result_img_path, result=None): result_img_path, title="Result Image " + str(result_num), result=result ) + def show_save_image(self, result_num): + inspection_img_path = self.inspection_image_path_list[int(result_num)] + if inspection_img_path is not None and os.path.exists(inspection_img_path): + self.screen.show_save_image_popup( + inspection_img_path, + result_num, + ) + class PopupImageScreen(MDBoxLayout): dismiss_popup = ObjectProperty(None) @@ -534,6 +583,54 @@ def set_image_path(self, value): print(f"Image path does not exist: {value}") +class PopupSaveImageScreen(MDBoxLayout): + dismiss_popup = ObjectProperty(None) + original_image = None + aimodel_name = None + + def __init__(self, **kwargs): + super(PopupSaveImageScreen, self).__init__(**kwargs) + self.app = MDApp.get_running_app() + + def set_image_path_and_name(self, value, name): + if os.path.exists(value): + self.ids.popup_save_image.source = value + self.original_image = cv2.imread(value) + self.aimodel_name = name + self.ids.popup_save_dir_path.text = os.path.abspath( + self.app.confini["settings"]["dataset_dir"] + ) + else: + print(f"Image path does not exist: {value}") + + def save_image(self, class_label=0): + current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M_%S") + if self.original_image is not None and self.aimodel_name is not None: + dataset_dir = self.app.confini["settings"]["dataset_dir"] + if not os.path.exists(dataset_dir): + os.makedirs(dataset_dir) + filename = str(current_time) + ".png" + if class_label == 0: + save_dataset_dir = ( + dataset_dir + "/Inspection_" + self.aimodel_name + "_Normal" + ) + filename = "Normal_" + filename + else: + save_dataset_dir = ( + dataset_dir + "/Inspection_" + self.aimodel_name + "_Anomaly" + ) + filename = "Anomaly_" + filename + if not os.path.exists(save_dataset_dir): + os.makedirs(save_dataset_dir) + save_image_path = save_dataset_dir + "/" + filename + cv2.imwrite( + save_image_path, + self.original_image, + ) + toast(self.app.textini[self.app.lang]["main_toast_save_image"]) + self.dismiss_popup() + + def open_image(image_path): try: image_path = os.path.abspath(image_path) diff --git a/making_dataset_screen.py b/making_dataset_screen.py index 2e61b92..09b58be 100644 --- a/making_dataset_screen.py +++ b/making_dataset_screen.py @@ -238,13 +238,14 @@ def get_image_count(self, class_label=0): return image_count def save_images(self, class_label=0): - current_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M_%S") if self.app.current_inspection_dict is not None: dataset_dir = self.app.confini["settings"]["dataset_dir"] if not os.path.exists(dataset_dir): os.makedirs(dataset_dir) if any(self.image_dict): for key, value in self.image_dict.items(): + filename = str(current_time) + ".png" if class_label == 0: save_dataset_dir = ( dataset_dir @@ -253,6 +254,7 @@ def save_images(self, class_label=0): + "_Normal_" + key ) + filename = "Normal_" + filename else: save_dataset_dir = ( dataset_dir @@ -261,11 +263,10 @@ def save_images(self, class_label=0): + "_Anomaly_" + key ) + filename = "Anomaly_" + filename if not os.path.exists(save_dataset_dir): os.makedirs(save_dataset_dir) - save_image_path = ( - save_dataset_dir + "/" + str(current_time) + ".png" - ) + save_image_path = save_dataset_dir + "/" + filename cv2.imwrite( save_image_path, value, diff --git a/target_area_screen.kv b/target_area_screen.kv index c028be5..0680ba7 100644 --- a/target_area_screen.kv +++ b/target_area_screen.kv @@ -10,7 +10,7 @@ id: message halign: "center" size_hint: 1, .1 - color: 1, 1, 1, 1 + color: 1, 1, 1, 1 text: app.textini[app.lang]["camera_settings"] + " " + app.textini[app.lang]["step"] + " 2/2 : " + app.textini[app.lang]["ta_set_area"] padding: "4dp", "4dp" MDBoxLayout: @@ -95,7 +95,7 @@ title: app.textini[app.lang]["label_copyright"] icon: "close" type: "bottom" - mode: "end" + mode: "end" on_action_button: app.popup_open() ImageView: id: image_view diff --git a/target_area_screen.py b/target_area_screen.py index 809c0ce..a69b4be 100644 --- a/target_area_screen.py +++ b/target_area_screen.py @@ -267,7 +267,7 @@ def _check_ratio(self, ratio1, ratio2): ret_flg = False return ret_flg - def _change_coord_to_ratio(self, coordinate, texture_size, digit=3): + def _change_coord_to_ratio(self, coordinate, texture_size, digit=2): width_ratio = round(int(coordinate[0]) / int(texture_size[0]), digit) height_ratio = round(int(coordinate[1]) / int(texture_size[1]), digit) return [width_ratio, height_ratio] diff --git a/text.ini b/text.ini index 58f74ab..649e16f 100644 --- a/text.ini +++ b/text.ini @@ -1,5 +1,5 @@ [DEFAULT] -version = 1.2.1 +version = 1.3.0 adfi_app_name = Visual Inspection Application for ADFI label_copyright = Copyright (c) 2023 ADFI, AI Robotics LTD. All rights reserved. label_adfi = Visual Inspection Application for ADFI @@ -170,8 +170,16 @@ main_inspect_image = Inspect (A key) main_change = Change Displayed Image main_save_inspected_image = Save Inspected Image main_save_inspection_results = Save Inspection Result Image +main_save_train_image = As Training Image +main_save = Save +main_save_image_title = Save this image as a training image in the following directory. Select the correct answer (Normal or Anomaly). +main_save_normal = Save it As Normal +main_save_anomaly = Save it As Anomaly +main_save_cancel = Cancel +main_toast_save_image = Image saved. main_inspected_image = AI model (Preprocessing name) main_result = Inspection Result +main_massage_loading_camera = Loading camera settings. main_massage_no_inspection = No inspection running. Run your inspection in Inspection Settings. main_message_run_inspection = Please click Inspect button. main_message_no_api_info = Please set API Key, Model Type and Model ID in AI Model Settings. @@ -363,8 +371,16 @@ main_inspect_image = 検査実行 (「A」キー) main_change = 表示画像を変更 main_save_inspected_image = 検査した画像を保存 main_save_inspection_results = 検査結果画像を保存 +main_save_train_image = 学習用画像 +main_save = 保存 +main_save_image_title = 下記ディレクトリ内に学習用画像として保存します。正解(正常または異常)を選択してください。 +main_save_normal = 正常として保存 +main_save_anomaly = 異常として保存 +main_save_cancel = キャンセル +main_toast_save_image = 画像を保存しました。 main_inspected_image = AIモデル(前処理名) main_result = 検査結果 +main_massage_loading_camera = カメラ設定をロード中。 main_massage_no_inspection = 実行中の検査がありません。検査設定画面で検査を実行してください。 main_message_run_inspection = 「検査実行」ボタンを押してください。 main_message_no_api_info = 「AIモデル設定」でAPI Key、Model Type、Model IDを設定してください。