def Event(self, event, values): # Dobotの接続を行う if event == "-Connect-": # self.connection = self.Connect_Disconnect_click(self.connection, self.api) self.connection = Connect_Disconnect(self.connection, self.api, self.CON_STR) if self.connection == 0: # Dobotの現在の姿勢を画面上に表示 self.current_pose = self.GetPose_UpdateWindow() elif event == "-SetJointPose-": # 移動後の関節角度を指定 DestPose = [ float(values["-JointPoseInput_1-"]), float(values["-JointPoseInput_2-"]), float(values["-JointPoseInput_3-"]), float(values["-JointPoseInput_4-"]), ] response = self.SetJointPose_click() print(response) # ------------------------------------ # # WebCamを選択&接続するイベント # # ------------------------------------ # elif event == "-SetWebCam-": # Webカメラの番号を取得する cam_num = WebCamOption(values["-WebCam_Name-"]) # webカメラの番号が取得できなかった場合 if cam_num is None: sg.popup("選択したデバイスは存在しません。", title="カメラ接続エラー") return # ----------------------------# # カメラを接続するイベント # # --------------------------- # # カメラを初めて接続する場合 if (cam_num != None) and (self.cam_num == None): response, self.cam = WebCam_OnOff(cam_num, cam=self.cam) if response == -1: # カメラが接続されていない場合 sg.popup("WebCameraに接続できません.", title="カメラ接続エラー") elif response == 0: # カメラを開放した場合 sg.popup("WebCameraを開放しました。", title="Camの接続") else: sg.popup("WebCameraに接続しました。", title="Camの接続") # 接続したいカメラが接続していカメラと同じ場合 elif (cam_num != None) and (self.cam_num == cam_num): response, self.cam = WebCam_OnOff(cam_num, cam=self.cam) if response == -1: # カメラが接続されていない場合 sg.popup("WebCameraに接続できません.", title="カメラ接続エラー") elif response == 0: # カメラを開放した場合 sg.popup("WebCameraを開放しました。", title="Camの接続") else: sg.popup("WebCameraに接続しました。", title="Camの接続") # 接続したいカメラと接続しているカメラが違う場合 elif (cam_num != None) and (self.cam_num != cam_num): # まず接続しているカメラを開放する. ch_1, self.cam = WebCam_OnOff(cam_num, cam=self.cam) # 開放できた場合 if ch_1 == 0: sg.popup("WebCameraを開放しました。", title="Camの接続") # 次に新しいカメラを接続する. ch_2, self.cam = WebCam_OnOff(cam_num, cam=self.cam) # カメラが接続されていない場合 if ch_2 == -1: sg.popup("WebCameraに接続できません.", title="カメラ接続エラー") else: sg.popup("WebCameraに接続しました.", title="Camの接続") # 新しいカメラを接続した場合 elif ch_1 == 1: sg.popup("新しくWebCameraに接続しました.", title="Camの接続") # カメラの接続に失敗した場合 else: self.cam = None self.cam_num = cam_num #---------------------------------# # プレビューを表示するイベント # #-------------------------------- # elif event == "-Preview-": window_name = "frame" while True: if type(self.cam) == cv2.VideoCapture: # カメラが接続されている場合 response, img = Snapshot(self.cam) if response: #----------------------------------------# # 画像サイズなどをダイアログ上に表示 # #----------------------------------------# self.Window["-IMAGE_width-"].update(str(img.shape[0])) self.Window["-IMAGE_height-"].update(str(img.shape[1])) self.Window["-IMAGE_channel-"].update(str( img.shape[2])) print("プレビューを表示します。") response = Preview(img, window_name=window_name) if cv2.waitKey(0) & 0xFF == ord("e"): cv2.destroyWindow(window_name) break else: sg.popup("SnapShotを撮影できませんでした.", title="撮影エラー") break else: sg.popup("カメラが接続されていません.", title="カメラ接続エラー") break # ---------------------------------------- # # スナップショットを撮影するイベント # # ---------------------------------------- # elif event == '-Snapshot-': response, img = Snapshot(self.cam) if response != 1: sg.popup("スナップショットを撮影できませんでした。", title="撮影エラー") #----------------------------------------# # 画像サイズなどをダイアログ上に表示 # #----------------------------------------# self.Window["-IMAGE_width-"].update(str(img.shape[0])) self.Window["-IMAGE_height-"].update(str(img.shape[1])) self.Window["-IMAGE_channel-"].update(str(img.shape[2])) # --------------------------- # 撮影した画像を変換する。 # --------------------------- # ノイズ除去 # 濃度変換 if values['-Color_Density-'] != 'なし': img = Contrast_cvt(img, values['-Color_Density-']) # ----------------------------------- # 画面上に撮影した画像を表示する # ----------------------------------- img = scale_box(img, self.Image_width, self.Image_height) imgbytes = cv2.imencode('.png', img)[1].tobytes() self.Window['-IMAGE-'].update(data=imgbytes) # ------------------------------------------------ # 画面上に撮影した画像のヒストグラムを表示する # ------------------------------------------------ canvas_elem = self.Window['-CANVAS-'] canvas = canvas_elem.TKCanvas ticks = [0, 42, 84, 127, 169, 211, 255] fig, ax = plt.subplots(figsize=(3, 2)) ax = Image_hist(img, ax, ticks) if self.fig_agg: # ** IMPORTANT ** Clean up previous drawing before drawing again delete_figure_agg(self.fig_agg) self.fig_agg = draw_figure(canvas, fig) self.fig_agg.draw()
def Event(self, event, values): #--------------------------------------------- # 操作時にウインドウが変化するイベント群 #--------------------------------------------- if event == "-Binarization-": if values["-Binarization-"] != "なし": self.Window['-Color_Space-'].update("Gray") self.Window['-LowerThreshold-'].update(disabled=False) if values["-Binarization-"] == "Adaptive": self.Window['-AdaptiveThreshold_type-'].update(disabled=False, readonly=True) self.Window['-AdaptiveThreshold_BlockSize-'].update( disabled=False) self.Window['-AdaptiveThreshold_Constant-'].update( disabled=False) elif values["-Binarization-"] == "Two": # 各色選択ボタンを有効化 self.Window['-color_R-'].update(disabled=False) self.Window['-color_G-'].update(disabled=False) self.Window['-color_B-'].update(disabled=False) self.Window['-color_W-'].update(disabled=False) self.Window['-color_Bk-'].update(disabled=False) self.Window['-UpperThreshold-'].update(disabled=False) # Dobotの接続を行う if event == "-Connect-": # self.connection = self.Connect_Disconnect_click(self.connection, self.api) self.connection, err = Connect_Disconnect( self.connection, self.api, ) if self.connection: # Dobotの現在の姿勢を画面上に表示 self.current_pose = self.GetPose_UpdateWindow() # --------------------- # # グリッパを動作させる # # --------------------- # elif event == '-Gripper-': if self.connection: # グリッパを開く GripperAutoCtrl(self.api) # ------------------------------------------- # # 現在の姿勢を取得し、画面上のに表示する # # ------------------------------------------- # elif event == "-GetPose-": if self.connection: self.GetPose_UpdateWindow() elif event == "-SetJointPose-": # 移動後の関節角度を指定 DestPose = [ float(values["-JointPoseInput_1-"]), float(values["-JointPoseInput_2-"]), float(values["-JointPoseInput_3-"]), float(values["-JointPoseInput_4-"]), ] response = self.SetJointPose_click() print(response) # ----------------------------------------- # # デカルト座標系で指定位置に動作させる # # ----------------------------------------- # elif event == '-SetCoordinatePose-': if self.connection: if ((values['-CoordinatePose_X-'] is '') and (values['-CoordinatePose_Y-'] is '') and (values['-CoordinatePose_Z-'] is '') and (values['-CoordinatePose_R-'] is '')): # 移動先が1つも入力場合 sg.popup('移動先が入力されていません。', title='入力不良') self.Input_err = 1 return pose = self.GetPose_UpdateWindow() if values['-CoordinatePose_X-'] is '': values['-CoordinatePose_X-'] = pose["x"] if values['-CoordinatePose_Y-'] is '': values['-CoordinatePose_Y-'] = pose["y"] if values['-CoordinatePose_Z-'] is '': values['--CoordinatePose_Z-'] = pose["z"] if values['-CoordinatePose_R-'] is '': values['-CoordinatePose_R-'] = pose["r"] # 移動後の関節角度を指定 pose["x"] = float(values['-CoordinatePose_X-']) pose["y"] = float(values['-CoordinatePose_Y-']) pose["z"] = float(values['--CoordinatePose_Z-']) pose["r"] = float(values['-CoordinatePose_R-']) SetPoseAct(self.api, pose=pose, ptpMoveMode=values["-MoveMode-"]) time.sleep(2) return # ---------------------------------- # # Dobotの動作終了位置を設定する # # ---------------------------------- # elif event == '-Record-': if self.connection: self.GetPose_UpdateWindow() self.Window['-x0-'].update(str(self.CurrentPose["x"])) self.Window['-y0-'].update(str(self.CurrentPose["y"])) self.Window['-z0-'].update(str(self.CurrentPose["z"])) self.Window['-r0-'].update(str(self.CurrentPose["r"])) self.RecordPose = self.CurrentPose # 現在の姿勢を記録 # ----------------------------------------------------------- # # 画像とDobotの座標系の位置合わせ用変数_1をセットする # # ----------------------------------------------------------- # elif event == '-Set_x1-': if self.connection: self.GetPose_UpdateWindow() self.Alignment_1["x"] = self.CurrentPose["x"] self.Alignment_1["y"] = self.CurrentPose["y"] self.Window['-x1-'].update(str(self.Alignment_1["x"])) self.Window['-y1-'].update(str(self.Alignment_1["y"])) # -------------------------------------------------- # # 画像とDobotの座標系の位置合わせ用変数_2をセットする # # -------------------------------------------------- # elif event == '-Set_x2-': if self.connection: self.GetPose_UpdateWindow() self.Alignment_2["x"] = self.CurrentPose["x"] self.Alignment_2["y"] = self.CurrentPose["y"] self.Window['-x2-'].update(str(self.Alignment_2["x"])) self.Window['-y2-'].update(str(self.Alignment_2["y"])) # ------------------------------------ # # WebCamを選択&接続するイベント # # ------------------------------------ # elif event == "-SetWebCam-": # Webカメラの番号を取得する cam_num = WebCamOption(values["-WebCam_Name-"]) # webカメラの番号が取得できなかった場合 if cam_num is None: sg.popup("選択したデバイスは存在しません。", title="カメラ接続エラー") return # ----------------------------# # カメラを接続するイベント # # --------------------------- # # カメラを初めて接続する場合 -> カメラを新規接続 # 接続したいカメラが接続していカメラと同じ場合 -> カメラを解放 if (self.cam_num == None) or (self.cam_num == cam_num): response, self.cam = WebCam_OnOff(cam_num, cam=self.cam) sg.popup(self.WebCam_err[response], title="Camの接続") # 接続したいカメラと接続しているカメラが違う場合 -> 接続しているカメラを解放し、新規接続 elif (self.cam_num != None) and (self.cam_num != cam_num): # まず接続しているカメラを開放する. response, self.cam = WebCam_OnOff(self.cam_num, cam=self.cam) # 開放できた場合 if response == 1: sg.popup(self.WebCam_err[response], title="Camの接続") # 次に新しいカメラを接続する. response, self.cam = WebCam_OnOff(cam_num, cam=self.cam) sg.popup(self.WebCam_err[response], title="Camの接続") # カメラが問題なく見つかった場合 if response != 2: self.cam_num = cam_num else: self.cam_num = None #---------------------------------# # プレビューを表示するイベント # #-------------------------------- # elif event == "-Preview-": window_name = "frame" while True: if type(self.cam) == cv2.VideoCapture: # カメラが接続されている場合 response, img = Snapshot(self.cam) if response: #----------------------------------------# # 画像サイズなどをダイアログ上に表示 # #----------------------------------------# self.Window["-IMAGE_width-"].update(str(img.shape[0])) self.Window["-IMAGE_height-"].update(str(img.shape[1])) self.Window["-IMAGE_channel-"].update(str( img.shape[2])) print("プレビューを表示します。") response = Preview(img, window_name=window_name) if cv2.waitKey(0) & 0xFF == ord("e"): cv2.destroyWindow(window_name) break else: sg.popup("SnapShotを撮影できませんでした.", title="撮影エラー") break else: sg.popup("カメラが接続されていません.", title="カメラ接続エラー") break # --------------------------------------- # # スナップショットを撮影するイベント # # --------------------------------------- # elif event == '-Snapshot-': if type(self.cam) == cv2.VideoCapture: self.IMAGE_Org, self.IMAGE_bin = self.SnapshotBtn(values) else: sg.popup(self.WebCam_err[2], title="カメラ接続エラー") # -------------------------- # # COGを計算するイベント # # ------------------------- # elif event == '-Contours-': if type(self.cam) == cv2.VideoCapture: self.ContoursBtn(values) else: sg.popup(self.WebCam_err[2], title="カメラ接続エラー") # -------------------------------------------------------------- # # オブジェクトの重心位置に移動→掴む→退避 動作を実行する # # -------------------------------------------------------------- # elif event == '-Task-': if values['-TaskNum-'] == "Task_1": if (self.connection == True) and (type(self.cam) == cv2.VideoCapture): if (not self.Alignment_1) or \ (not self.Alignment_2) or \ (not self.RecordPose): sg.popup( "キャリブレーション座標 x1 および x2, \nもしくは 退避位置 がセットされていません。") else: # 画像を撮影 & 重心位置を計算 COG = self.ContoursBtn(values) # 現在のDobotの姿勢を取得 pose = self.GetPose_UpdateWindow( ) # pose -> self.CurrentPose # ------------------------------ # # Dobotの移動後の姿勢を計算 # # ------------------------------ # try: pose["x"] = self.Alignment_1["x"] + COG[0] * \ (self.Alignment_2["x"]-self.Alignment_1["x"]) / float(self.Image_height) pose["y"] = self.Alignment_1["y"] + COG[1] * \ (self.Alignment_2["y"]-self.Alignment_1["y"]) / float(self.Image_width) except ZeroDivisionError: # ゼロ割が発生した場合 sg.popup('画像のサイズが計測されていません', title='エラー') return pose = { "x": 193, "y": -20, "z": 21, "r": 46, "joint1Angle": 0.0, "joint2Angle": 0.0, "joint3Angle": 0.0, "joint4Angle": 0.0, } # Dobotをオブジェクト重心の真上まで移動させる。 SetPoseAct(self.api, pose=pose, ptpMoveMode=values["-MoveMode-"]) # グリッパーを開く。 GripperAutoCtrl(self.api) # DobotをZ=-35の位置まで降下させる。 pose["z"] = -35 SetPoseAct(self.api, pose=pose, ptpMoveMode=values["-MoveMode-"]) # グリッパを閉じる。 GripperAutoCtrl(self.api) # Dobotを上昇させる。 pose["z"] = self.CurrentPose["z"] SetPoseAct(self.api, pose=pose, ptpMoveMode=values["-MoveMode-"]) # 退避位置まで移動させる。 SetPoseAct(self.api, pose=self.RecordPose, ptpMoveMode=values["-MoveMode-"]) else: sg.popup("Dobotかカメラが接続されていません。")
def SnapshotBtn(self, values: list) -> np.ndarray: """スナップショットの撮影から一連の画像処理を行う関数。 Args: values (list): ウインドウ上のボタンの状態などを記録している変数 Returns: dst_org (np.ndarray): オリジナルのスナップショット dst_bin (np.ndarray): 二値化処理後の画像 """ dst_org = dst_bin = None response, img = Snapshot(self.cam) if response != 3: sg.popup(self.WebCam_err[response], title="撮影エラー") return dst_org = img.copy() #--------------------------- # # 画像サイズなどをダイアログ上に表示 # #--------------------------- # self.Window["-IMAGE_width-"].update(str(img.shape[0])) self.Window["-IMAGE_height-"].update(str(img.shape[1])) self.Window["-IMAGE_channel-"].update(str(img.shape[2])) # --------------------------- # 撮影した画像を変換する。 # --------------------------- # 色空間変換 if values['-Color_Space-'] != 'RGB': img = Color_cvt(img, values['-Color_Space-']) # ノイズ除去 # 濃度変換 if values['-Color_Density-'] != 'なし': img = Contrast_cvt(img, values['-Color_Density-']) # ------------ # 画像処理 # ------------ if values['-Binarization-'] != 'なし': # 二値化処理 if values['-Binarization-'] == 'Global': # 大域的二値化処理 img = GlobalThreshold(img, threshold=int( values["-LowerThreshold-"])) elif values['-Binarization-'] == 'Otsu': # 大津の二値化処理 img = GlobalThreshold(img, Type='Otsu') elif values['-Binarization-'] == 'Adaptive': img = AdaptiveThreshold( img=img, method=str(values['-AdaptiveThreshold_type-']), block_size=int(values['-AdaptiveThreshold_BlockSize-']), C=int(values['-AdaptiveThreshold_Constant-'])) elif values['-Binarization-'] == 'Two': # 2つの閾値を用いた二値化処理 # ピックアップする色を番号に変換 if values['-color_R-']: color = 0 elif values['-color_G-']: color = 1 elif values['-color_B-']: color = 2 elif values['-color_W-']: color = 3 elif values['-color_Bk-']: color = 4 img = TwoThreshold( img=img, LowerThreshold=int(values["-LowerThreshold-"]), UpperThreshold=int(values["-UpperThreshold-"]), PickupColor=color) dst_bin = img.copy() # ----------------------- # # 画面上に撮影した画像を表示する # # ----------------------- # img = scale_box(img, self.Image_width, self.Image_height) imgbytes = cv2.imencode('.png', img)[1].tobytes() self.Window['-IMAGE-'].update(data=imgbytes) # --------------------------------- # # 画面上に撮影した画像のヒストグラムを表示する # # --------------------------------- # canvas_elem = self.Window['-CANVAS-'] canvas = canvas_elem.TKCanvas ticks = [0, 42, 84, 127, 169, 211, 255] fig, ax = plt.subplots(figsize=(3, 2)) ax = Image_hist(img, ax, ticks) if self.fig_agg: # ** IMPORTANT ** Clean up previous drawing before drawing again delete_figure_agg(self.fig_agg) self.fig_agg = draw_figure(canvas, fig) self.fig_agg.draw() return dst_org, dst_bin
def Event(self, event, values): #--------------------------------------------- # 操作時にウインドウが変化するイベント群 #--------------------------------------------- if event == "-Binarization-": if values["-Binarization-"] != "なし": self.Window['-LowerThreshold-'].update(disabled=False) if values["-Binarization-"] == "Adaptive": self.Window['-AdaptiveThreshold_type-'].update(disabled=False) self.Window['-AdaptiveThreshold_BlockSize-'].update( disabled=False) self.Window['-AdaptiveThreshold_Constant-'].update( disabled=False) elif values["-Binarization-"] == "Two": # 各色選択ボタンを有効化 self.Window['-color_R-'].update(disabled=False) self.Window['-color_G-'].update(disabled=False) self.Window['-color_B-'].update(disabled=False) self.Window['-color_W-'].update(disabled=False) self.Window['-color_Bk-'].update(disabled=False) self.Window['-UpperThreshold-'].update(disabled=False) # Dobotの接続を行う if event == "-Connect-": # self.connection = self.Connect_Disconnect_click(self.connection, self.api) self.connection, err = Connect_Disconnect( self.connection, self.api, ) if self.connection: # Dobotの現在の姿勢を画面上に表示 self.current_pose = self.GetPose_UpdateWindow() # --------------------- # # グリッパを動作させる # # --------------------- # elif event == '-Gripper-': if self.connection: # グリッパを開く GripperAutoCtrl(self.api) elif event == "-SetJointPose-": # 移動後の関節角度を指定 DestPose = [ float(values["-JointPoseInput_1-"]), float(values["-JointPoseInput_2-"]), float(values["-JointPoseInput_3-"]), float(values["-JointPoseInput_4-"]), ] response = self.SetJointPose_click() print(response) # ------------------------------------ # # WebCamを選択&接続するイベント # # ------------------------------------ # elif event == "-SetWebCam-": # Webカメラの番号を取得する cam_num = WebCamOption(values["-WebCam_Name-"]) # webカメラの番号が取得できなかった場合 if cam_num is None: sg.popup("選択したデバイスは存在しません。", title="カメラ接続エラー") return # ----------------------------# # カメラを接続するイベント # # --------------------------- # # カメラを初めて接続する場合 if (cam_num != None) and (self.cam_num == None): response, self.cam = WebCam_OnOff(cam_num, cam=self.cam) if response == -1: # カメラが接続されていない場合 sg.popup("WebCameraに接続できません.", title="カメラ接続エラー") elif response == 0: # カメラを開放した場合 sg.popup("WebCameraを開放しました。", title="Camの接続") else: sg.popup("WebCameraに接続しました。", title="Camの接続") # 接続したいカメラが接続していカメラと同じ場合 elif (cam_num != None) and (self.cam_num == cam_num): response, self.cam = WebCam_OnOff(cam_num, cam=self.cam) if response == -1: # カメラが接続されていない場合 sg.popup("WebCameraに接続できません.", title="カメラ接続エラー") elif response == 0: # カメラを開放した場合 sg.popup("WebCameraを開放しました。", title="Camの接続") else: sg.popup("WebCameraに接続しました。", title="Camの接続") # 接続したいカメラと接続しているカメラが違う場合 elif (cam_num != None) and (self.cam_num != cam_num): # まず接続しているカメラを開放する. ch_1, self.cam = WebCam_OnOff(cam_num, cam=self.cam) # 開放できた場合 if ch_1 == 0: sg.popup("WebCameraを開放しました。", title="Camの接続") # 次に新しいカメラを接続する. ch_2, self.cam = WebCam_OnOff(cam_num, cam=self.cam) # カメラが接続されていない場合 if ch_2 == -1: sg.popup("WebCameraに接続できません.", title="カメラ接続エラー") else: sg.popup("WebCameraに接続しました.", title="Camの接続") # 新しいカメラを接続した場合 elif ch_1 == 1: sg.popup("新しくWebCameraに接続しました.", title="Camの接続") # カメラの接続に失敗した場合 else: self.cam = None self.cam_num = cam_num #---------------------------------# # プレビューを表示するイベント # #-------------------------------- # elif event == "-Preview-": window_name = "frame" while True: if type(self.cam) == cv2.VideoCapture: # カメラが接続されている場合 response, img = Snapshot(self.cam) if response: #----------------------------------------# # 画像サイズなどをダイアログ上に表示 # #----------------------------------------# self.Window["-IMAGE_width-"].update(str(img.shape[0])) self.Window["-IMAGE_height-"].update(str(img.shape[1])) self.Window["-IMAGE_channel-"].update(str( img.shape[2])) print("プレビューを表示します。") response = Preview(img, window_name=window_name) if cv2.waitKey(0) & 0xFF == ord("e"): cv2.destroyWindow(window_name) break else: sg.popup("SnapShotを撮影できませんでした.", title="撮影エラー") break else: sg.popup("カメラが接続されていません.", title="カメラ接続エラー") break # ---------------------------- # # スナップショットを撮影するイベント # # ---------------------------- # elif event == '-Snapshot-': self.IMAGE_Org, self.IMAGE_bin = self.SnapshotBtn(values) # ------------------- # # COGを計算するイベント # # ------------------- # elif event == '-Contours-': # スナップショットを撮影する self.IMAGE_Org, self.IMAGE_bin = self.SnapshotBtn(values) # 輪郭情報 RetrievalMode = { '親子関係を無視する': cv2.RETR_LIST, '最外の輪郭を検出する': cv2.RETR_EXTERNAL, '2つの階層に分類する': cv2.RETR_CCOMP, '全階層情報を保持する': cv2.RETR_TREE } # 輪郭の中間点情報 ApproximateMode = { '中間点を保持する': cv2.CHAIN_APPROX_NONE, '中間点を保持しない': cv2.CHAIN_APPROX_SIMPLE } if type(self.IMAGE_bin) != np.ndarray: raise TypeError('入力はnumpy配列を使用してください。') COG = CenterOfGravity(bin_img=self.IMAGE_bin, RetrievalMode=RetrievalMode[str( values['-RetrievalMode-'])], ApproximateMode=ApproximateMode[str( values['-ApproximateMode-'])], min_area=100, cal_Method=1) self.Window['-CenterOfGravity_x-'].update(str(COG[0])) self.Window['-CenterOfGravity_y-'].update(str(COG[1]))