Ejemplo n.º 1
0
    def load_model(self):
        # Model load #############################################################
        mp_hands = mp.solutions.hands
        hands = mp_hands.Hands(
            static_image_mode=self.use_static_image_mode,
            max_num_hands=1,
            min_detection_confidence=self.min_detection_confidence,
            min_tracking_confidence=self.min_tracking_confidence,
        )

        keypoint_classifier = KeyPointClassifier()
        point_history_classifier = PointHistoryClassifier()

        # Read labels ###########################################################
        with open('model/keypoint_classifier/keypoint_classifier_label.csv',
                  encoding='utf-8-sig') as f:
            keypoint_classifier_labels = csv.reader(f)
            keypoint_classifier_labels = [
                row[0] for row in keypoint_classifier_labels
            ]
        with open(
                'model/point_history_classifier/point_history_classifier_label.csv',
                encoding='utf-8-sig') as f:
            point_history_classifier_labels = csv.reader(f)
            point_history_classifier_labels = [
                row[0] for row in point_history_classifier_labels
            ]

        return hands, keypoint_classifier, keypoint_classifier_labels, \
               point_history_classifier, point_history_classifier_labels
Ejemplo n.º 2
0
    def run(self):
        # Argument parsing #################################################################
        self.stop_flag = False
        args = get_args()

        cap_device = args.device
        cap_width = args.width
        cap_height = args.height

        use_static_image_mode = args.use_static_image_mode
        min_detection_confidence = args.min_detection_confidence
        min_tracking_confidence = args.min_tracking_confidence

        use_brect = True

        # Camera preparation ###############################################################
        cap = cv.VideoCapture(cap_device)
        cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
        cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)

        # Model load #############################################################
        mp_hands = mp.solutions.hands
        hands = mp_hands.Hands(
            static_image_mode=use_static_image_mode,
            max_num_hands=1,
            min_detection_confidence=min_detection_confidence,
            min_tracking_confidence=min_tracking_confidence,
        )

        keypoint_classifier_R = KeyPointClassifier_R(invalid_value=8,
                                                     score_th=0.4)
        keypoint_classifier_L = KeyPointClassifier_L(invalid_value=8,
                                                     score_th=0.4)
        mouse_classifier = MouseClassifier(invalid_value=2, score_th=0.4)
        point_history_classifier = PointHistoryClassifier()

        # Read labels ###########################################################
        with open('model/keypoint_classifier/keypoint_classifier_label.csv',
                  encoding='utf-8-sig') as f:
            keypoint_classifier_labels = csv.reader(f)
            keypoint_classifier_labels = [
                row[0] for row in keypoint_classifier_labels
            ]
        with open(
                'model/point_history_classifier/point_history_classifier_label.csv',
                encoding='utf-8-sig') as f:
            point_history_classifier_labels = csv.reader(f)
            point_history_classifier_labels = [
                row[0] for row in point_history_classifier_labels
            ]

        # FPS Measurement ########################################################
        cvFpsCalc = CvFpsCalc(buffer_len=3)

        # Coordinate history #################################################################
        history_length = 16
        point_history = deque(maxlen=history_length)

        # Finger gesture history ################################################
        finger_gesture_history = deque(maxlen=history_length)
        mouse_id_history = deque(maxlen=40)

        # 靜態手勢最常出現參數初始化
        keypoint_length = 5
        keypoint_R = deque(maxlen=keypoint_length)
        keypoint_L = deque(maxlen=keypoint_length)

        # result deque
        rest_length = 300
        rest_result = deque(maxlen=rest_length)
        speed_up_count = deque(maxlen=3)

        # ========= 使用者自訂姿勢、指令區 =========
        # time.sleep(0.5)
        # keepadd = False

        # ========= 按鍵前置作業 =========
        mode = 0
        presstime = presstime_2 = presstime_3 = resttime = presstime_4 = time.time(
        )

        detect_mode = 2
        what_mode = 'mouse'
        landmark_list = 0
        pyautogui.PAUSE = 0

        # ========= 滑鼠前置作業 =========
        wScr, hScr = pyautogui.size()
        frameR = 100
        smoothening = 7
        plocX, plocY = 0, 0
        clocX, clocY = 0, 0
        mousespeed = 1.5
        clicktime = time.time()
        #關閉 滑鼠移至角落啟動保護措施
        pyautogui.FAILSAFE = False

        # ========= google 小姐 =========
        # speech_0 = gTTS(text="スリープモード", lang='ja')
        # speech_0.save('rest.mp3')
        # speech_0 = gTTS(text="キーボードモード", lang='ja')
        # speech_0.save('keyboard.mp3')
        # speech = gTTS(text="マウスモード", lang='ja')
        # speech.save('mouse.mp3')

        # ===============================
        i = 0
        finger_gesture_id = 0

        # ========= 主程式運作 =========
        while (not self.stop_flag):
            left_id = right_id = -1
            fps = cvFpsCalc.get()

            # Process Key (ESC: end)
            key = cv.waitKey(10)
            if key == 27:  # ESC
                break
            number, mode = select_mode(key, mode)

            # Camera capture
            ret, image = cap.read()
            if not ret:
                break
            image = cv.flip(image, 1)  # Mirror display
            debug_image = copy.deepcopy(image)

            # Detection implementation
            image = cv.cvtColor(image, cv.COLOR_BGR2RGB)

            image.flags.writeable = False
            results = hands.process(image)
            image.flags.writeable = True

            ####rest_result####
            if results.multi_hand_landmarks is None:
                rest_id = 0
                rest_result.append(rest_id)
            if results.multi_hand_landmarks is not None:
                rest_id = 1
                rest_result.append(rest_id)
            most_common_rest_result = Counter(rest_result).most_common()

            # old version for 10 sec to rest mode####################
            #print(most_common_rest_result[0])
            # if most_common_rest_result[0][0] == 0 and most_common_rest_result[0][1] == 300:
            #     if detect_mode != 0:
            #
            #         print('Mode has changed')
            #         detect_mode = 0
            #         what_mode = 'Rest'
            #         print(f'Current mode => {what_mode}')

            # new version for 10 sec to rest mode###################
            if time.time() - resttime > 10:
                if detect_mode != 0:
                    detect_mode = 0
                    what_mode = 'Sleep'
                    print(f'Current mode => {what_mode}')

            ####rest_result####

            #  ####################################################################
            # print(most_common_rest_result)
            if results.multi_hand_landmarks is not None:
                for hand_landmarks, handedness in zip(
                        results.multi_hand_landmarks,
                        results.multi_handedness):

                    # Bounding box calculation
                    brect = calc_bounding_rect(debug_image, hand_landmarks)
                    # Landmark calculation
                    landmark_list = calc_landmark_list(debug_image,
                                                       hand_landmarks)
                    # print(landmark_list)

                    # Conversion to relative coordinates / normalized coordinates
                    pre_processed_landmark_list = pre_process_landmark(
                        landmark_list)
                    pre_processed_point_history_list = pre_process_point_history(
                        debug_image, point_history)
                    # Write to the dataset file
                    logging_csv(number, mode, pre_processed_landmark_list,
                                pre_processed_point_history_list)

                    # 靜態手勢資料預測
                    hand_sign_id_R = keypoint_classifier_R(
                        pre_processed_landmark_list)
                    hand_sign_id_L = keypoint_classifier_L(
                        pre_processed_landmark_list)
                    mouse_id = mouse_classifier(pre_processed_landmark_list)
                    # print(mouse_id)
                    if handedness.classification[0].label[0:] == 'Left':
                        left_id = hand_sign_id_L

                    else:
                        right_id = hand_sign_id_R

                    # 手比one 觸發動態資料抓取
                    if right_id == 1 or left_id == 1:
                        point_history.append(landmark_list[8])
                    else:
                        point_history.append([0, 0])

                    # 動態手勢資料預測
                    finger_gesture_id = 0
                    point_history_len = len(pre_processed_point_history_list)
                    if point_history_len == (history_length * 2):
                        finger_gesture_id = point_history_classifier(
                            pre_processed_point_history_list)
                    # print(finger_gesture_id) # 0 = stop, 1 = clockwise, 2 = counterclockwise, 3 = move,偵測出現的動態手勢

                    # 動態手勢最常出現id #########################################
                    # Calculates the gesture IDs in the latest detection
                    finger_gesture_history.append(finger_gesture_id)
                    most_common_fg_id = Counter(
                        finger_gesture_history).most_common()

                    #滑鼠的deque
                    mouse_id_history.append(mouse_id)
                    most_common_ms_id = Counter(mouse_id_history).most_common()
                    # print(f'finger_gesture_history = {finger_gesture_history}')
                    # print(f'most_common_fg_id = {most_common_fg_id}')

                    # 靜態手勢最常出現id #########################################
                    hand_gesture_id = [right_id, left_id]
                    keypoint_R.append(hand_gesture_id[0])
                    keypoint_L.append(hand_gesture_id[1])
                    # print(keypoint_R) # deque右手的靜態id
                    # print(most_common_keypoint_id) # 右手靜態id最大
                    if right_id != -1:
                        most_common_keypoint_id = Counter(
                            keypoint_R).most_common()
                    else:
                        most_common_keypoint_id = Counter(
                            keypoint_L).most_common()

                    # print(f'keypoint = {keypoint}')
                    # print(f'most_common_keypoint_id = {most_common_keypoint_id}')

                    ###############################################################

                    # Drawing part
                    debug_image = draw_bounding_rect(use_brect, debug_image,
                                                     brect)
                    debug_image = draw_landmarks(debug_image, landmark_list)
                    debug_image = draw_info_text(
                        debug_image,
                        brect,
                        handedness,
                        keypoint_classifier_labels[most_common_keypoint_id[0]
                                                   [0]],
                        point_history_classifier_labels[most_common_fg_id[0]
                                                        [0]],
                    )
                    resttime = time.time()
            else:
                point_history.append([0, 0])

            debug_image = draw_point_history(debug_image, point_history)
            debug_image = draw_info(debug_image, fps, mode, number)

            # 偵測是否有手勢 #########################################

            if left_id + right_id > -2:
                if time.time() - presstime > 1:
                    # change mode
                    if most_common_ms_id[0][0] == 3 and most_common_ms_id[0][
                            1] == 40:  #Gesture six changes to the different mode
                        print('Mode has changed')
                        detect_mode = (detect_mode + 1) % 3
                        if detect_mode == 0:
                            what_mode = 'Sleep'
                            playsound('rest.mp3', block=False)
                        if detect_mode == 1:
                            what_mode = 'Keyboard'
                            playsound('keyboard.mp3', block=False)
                        if detect_mode == 2:
                            what_mode = 'Mouse'
                            playsound('mouse.mp3', block=False)
                        print(f'Current mode => {what_mode}')
                        presstime = time.time() + 1

                    # control keyboard
                    elif detect_mode == 1:
                        if time.time() - presstime_2 > 1:
                            # 靜態手勢控制
                            control_keyboard(most_common_keypoint_id,
                                             2,
                                             'K',
                                             keyboard_TF=True,
                                             print_TF=False)
                            # control_keyboard(most_common_keypoint_id, 0, 'right', keyboard_TF=True, print_TF=False)
                            # control_keyboard(most_common_keypoint_id, 7, 'left', keyboard_TF=True, print_TF=False)
                            control_keyboard(most_common_keypoint_id,
                                             9,
                                             'C',
                                             keyboard_TF=True,
                                             print_TF=False)
                            control_keyboard(most_common_keypoint_id,
                                             5,
                                             'up',
                                             keyboard_TF=True,
                                             print_TF=False)
                            control_keyboard(most_common_keypoint_id,
                                             6,
                                             'down',
                                             keyboard_TF=True,
                                             print_TF=False)
                            presstime_2 = time.time()

                        # right右鍵
                        if most_common_keypoint_id[0][
                                0] == 0 and most_common_keypoint_id[0][1] == 5:
                            # print(i, time.time() - presstime_4)
                            if i == 3 and time.time() - presstime_4 > 0.3:
                                pyautogui.press('right')
                                i = 0
                                presstime_4 = time.time()
                            elif i == 3 and time.time() - presstime_4 > 0.25:
                                pyautogui.press('right')
                                presstime_4 = time.time()
                            elif time.time() - presstime_4 > 1:
                                pyautogui.press('right')
                                i += 1
                                presstime_4 = time.time()

                        # left左鍵
                        if most_common_keypoint_id[0][
                                0] == 7 and most_common_keypoint_id[0][1] == 5:
                            # print(i, time.time() - presstime_4)
                            if i == 3 and time.time() - presstime_4 > 0.3:
                                pyautogui.press('left')
                                i = 0
                                presstime_4 = time.time()
                            elif i == 3 and time.time() - presstime_4 > 0.25:
                                pyautogui.press('left')
                                presstime_4 = time.time()
                            elif time.time() - presstime_4 > 1:
                                pyautogui.press('left')
                                i += 1
                                presstime_4 = time.time()

                        # 動態手勢控制
                        if most_common_fg_id[0][
                                0] == 1 and most_common_fg_id[0][1] > 12:
                            if time.time() - presstime_3 > 1.5:
                                #pyautogui.press(['shift', '>'])
                                pyautogui.hotkey('shift', '>')
                                print('speed up')
                                presstime_3 = time.time()
                        elif most_common_fg_id[0][
                                0] == 2 and most_common_fg_id[0][1] > 12:
                            if time.time() - presstime_3 > 1.5:
                                #pyautogui.press(['shift', '<'])
                                pyautogui.hotkey('shift', '<')
                                print('speed down')
                                presstime_3 = time.time()

                if detect_mode == 2:
                    if mouse_id == 0:  # Point gesture
                        # print(landmark_list[8]) #index finger
                        # print(landmark_list[12]) #middle finger
                        x1, y1 = landmark_list[8]
                        # cv.rectangle(debug_image, (frameR, frameR), (cap_width - frameR, cap_height - frameR),
                        #              (255, 0, 255), 2)
                        cv.rectangle(debug_image, (50, 30),
                                     (cap_width - 50, cap_height - 170),
                                     (255, 0, 255), 2)
                        #座標轉換
                        #x軸: 鏡頭上50~(cap_width - 50)轉至螢幕寬0~wScr
                        #y軸: 鏡頭上30~(cap_height - 170)轉至螢幕長0~hScr
                        x3 = np.interp(x1, (50, (cap_width - 50)), (0, wScr))
                        y3 = np.interp(y1, (30, (cap_height - 170)), (0, hScr))
                        # print(x3, y3)

                        # 6. Smoothen Values
                        clocX = plocX + (x3 - plocX) / smoothening
                        clocY = plocY + (y3 - plocY) / smoothening
                        # 7. Move Mouse
                        pyautogui.moveTo(clocX, clocY)
                        cv.circle(debug_image, (x1, y1), 15, (255, 0, 255),
                                  cv.FILLED)
                        plocX, plocY = clocX, clocY

                    if mouse_id == 1:
                        length, img, lineInfo = findDistance(
                            landmark_list[8], landmark_list[12], debug_image)

                        # 10. Click mouse if distance short
                        if time.time() - clicktime > 0.5:
                            if length < 40:
                                cv.circle(img, (lineInfo[4], lineInfo[5]), 15,
                                          (0, 255, 0), cv.FILLED)
                                pyautogui.click()
                                print('click')
                                clicktime = time.time()

                            # if length > 70:
                            #     cv.circle(img, (lineInfo[4], lineInfo[5]),
                            #               15, (0, 255, 0), cv.FILLED)
                            # pyautogui.click(clicks=2)
                            # print('click*2')
                            # clicktime = time.time()

                    if most_common_keypoint_id[0][
                            0] == 5 and most_common_keypoint_id[0][1] == 5:
                        pyautogui.scroll(20)

                    if most_common_keypoint_id[0][
                            0] == 6 and most_common_keypoint_id[0][1] == 5:
                        pyautogui.scroll(-20)

                    #if left_id == 7 or right_id == 7:
                    if most_common_keypoint_id[0][
                            0] == 0 and most_common_keypoint_id[0][1] == 5:
                        if time.time() - clicktime > 1:
                            pyautogui.click(clicks=2)
                            clicktime = time.time()

                    if most_common_keypoint_id[0][
                            0] == 9 and most_common_keypoint_id[0][1] == 5:
                        if time.time() - clicktime > 2:
                            pyautogui.hotkey('alt', 'left')
                            clicktime = time.time()

            cv.putText(debug_image, what_mode, (400, 30),
                       cv.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 4, cv.LINE_AA)
            # Screen reflection ###################################JL##########################
            cv.imshow('Hand Gesture Recognition', debug_image)

            self.trigger.emit(detect_mode)

        cap.release()
        cv.destroyAllWindows()
Ejemplo n.º 3
0
    def run(self):
        # 重写线程执行的run函数
        # 触发自定义信号
        self.stop_flag = False
        # Argument parsing #################################################################
        args = get_args()

        cap_device = args.device
        cap_width = args.width
        cap_height = args.height

        use_static_image_mode = args.use_static_image_mode
        min_detection_confidence = args.min_detection_confidence
        min_tracking_confidence = args.min_tracking_confidence

        use_brect = True

        # Camera preparation ###############################################################
        cap = cv.VideoCapture(cap_device)
        cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
        cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)

        # Model load #############################################################
        mp_hands = mp.solutions.hands
        hands = mp_hands.Hands(
            static_image_mode=use_static_image_mode,
            max_num_hands=1,
            min_detection_confidence=min_detection_confidence,
            min_tracking_confidence=min_tracking_confidence,
        )

        mouse_classifier = MouseClassifier(invalid_value=2, score_th=0.4)
        point_history_classifier = PointHistoryClassifier()

        # Read labels ###########################################################

        with open(
                'model/point_history_classifier/point_history_classifier_label.csv',
                encoding='utf-8-sig') as f:
            point_history_classifier_labels = csv.reader(f)
            point_history_classifier_labels = [
                row[0] for row in point_history_classifier_labels
            ]
        with open('model/mouse_classifier/mouse_classifier_label.csv',
                  encoding='utf-8-sig') as f:
            mouse_classifier_labels = csv.reader(f)
            mouse_classifier_labels = [
                row[0] for row in mouse_classifier_labels
            ]
        # FPS Measurement ########################################################
        cvFpsCalc = CvFpsCalc(buffer_len=3)

        # Coordinate history #################################################################
        history_length = 16
        point_history = deque(maxlen=history_length)

        # Finger gesture history ################################################
        finger_gesture_history = deque(maxlen=history_length)
        mouse_id_history = deque(maxlen=30)
        m_id_history = deque(maxlen=6)

        # ========= 按鍵前置作業 =========
        mode = 0
        presstime = resttime = time.time()

        mode_change = False
        detect_mode = 0
        what_mode = 'Sleep'
        landmark_list = 0
        pyautogui.PAUSE = 0
        i = 0

        # ========= 滑鼠前置作業 =========
        wScr, hScr = pyautogui.size()
        frameR = 100
        smoothening = 10
        plocX, plocY = 0, 0
        clocX, clocY = 0, 0
        # 關閉 滑鼠移至角落啟動保護措施
        pyautogui.FAILSAFE = False

        # ========= 主程式運作 =========
        while self.stop_flag == False:
            mouse_id = -1
            fps = cvFpsCalc.get()

            # Process Key (ESC: end)
            key = cv.waitKey(10)
            if key == 27:  # ESC
                break
            number, mode = select_mode(key, mode)

            # Camera capture
            ret, image = cap.read()
            if not ret:
                break
            image = cv.flip(image, 1)  # Mirror display
            debug_image = copy.deepcopy(image)

            # Detection implementation
            image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
            # image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

            image.flags.writeable = False
            results = hands.process(image)
            image.flags.writeable = True

            #  ####################################################################
            if results.multi_hand_landmarks is not None:
                for hand_landmarks, handedness in zip(
                        results.multi_hand_landmarks,
                        results.multi_handedness):

                    # Bounding box calculation
                    brect = calc_bounding_rect(debug_image, hand_landmarks)
                    # Landmark calculation
                    landmark_list = calc_landmark_list(debug_image,
                                                       hand_landmarks)
                    # print(landmark_list)

                    # Conversion to relative coordinates / normalized coordinates
                    pre_processed_landmark_list = pre_process_landmark(
                        landmark_list)
                    pre_processed_point_history_list = pre_process_point_history(
                        debug_image, point_history)
                    # Write to the dataset file
                    logging_csv(number, mode, pre_processed_landmark_list,
                                pre_processed_point_history_list)

                    # # 靜態手勢資料預測

                    mouse_id = mouse_classifier(pre_processed_landmark_list)
                    # print(mouse_id)

                    # 手比one 觸發動態資料抓取
                    if mouse_id == 0:
                        point_history.append(landmark_list[8])
                    else:
                        point_history.append([0, 0])

                    # 動態手勢資料預測
                    finger_gesture_id = 0
                    point_history_len = len(pre_processed_point_history_list)
                    if point_history_len == (history_length * 2):
                        finger_gesture_id = point_history_classifier(
                            pre_processed_point_history_list)
                    # print(finger_gesture_id) # 0 = stop, 1 = clockwise, 2 = counterclockwise, 3 = move,偵測出現的動態手勢

                    # 動態手勢最常出現id #########################################
                    # Calculates the gesture IDs in the latest detection
                    finger_gesture_history.append(finger_gesture_id)
                    most_common_fg_id = Counter(
                        finger_gesture_history).most_common()

                    # 滑鼠的deque
                    mouse_id_history.append(mouse_id)
                    most_common_ms_id = Counter(mouse_id_history).most_common()
                    # print(most_common_ms_id)

                    m_id_history.append(mouse_id)
                    m_id = Counter(m_id_history).most_common(2)
                    mouse_id = m_id[0][0] if m_id[0][1] >= 4 else 2

                    # print(f'm_id {m_id}\n, mouse_id {mouse_id}')
                    # ===== 偵測到手時,重製紀錄時間 ==============================
                    resttime = time.time()

                    ###############################################################

                    # Drawing part
                    debug_image = draw_bounding_rect(use_brect, debug_image,
                                                     brect)
                    debug_image = draw_landmarks(debug_image, landmark_list)
                    debug_image = draw_info_text(
                        debug_image, brect, handedness,
                        mouse_classifier_labels[mouse_id],
                        point_history_classifier_labels[most_common_fg_id[0]
                                                        [0]])

            else:
                point_history.append([0, 0])

            debug_image = draw_point_history(debug_image, point_history)
            debug_image = draw_info(debug_image, fps, mode, number)

            # 偵測是否有手勢 #########################################
            if mouse_id > -1:
                # change mode Gesture six changes to the different mode
                if most_common_ms_id[0][0] == 3 and most_common_ms_id[0][
                        1] == 30:
                    if time.time() - presstime > 2:
                        detect_mode = (detect_mode + 1) % 3
                        mode_change = True
                        presstime = time.time()

                    # control keyboard
                elif detect_mode == 2:
                    # 靜態手勢控制
                    presstime = control_keyboard(mouse_id, 1, 'K', presstime)
                    presstime = control_keyboard(mouse_id, 8, 'C', presstime)
                    presstime = control_keyboard(mouse_id, 5, 'up', presstime)
                    presstime = control_keyboard(mouse_id, 6, 'down',
                                                 presstime)
                    # presstime = control_keyboard(most_common_keypoint_id, 0, 'right', presstime)
                    # presstime = control_keyboard(most_common_keypoint_id, 7, 'left', presstime)

                    if mouse_id == 4:
                        # print(i, time.time() - presstime)
                        if i == 3 and time.time() - presstime > 0.3:
                            pyautogui.press('right')
                            i = 0
                            presstime = time.time()
                        elif i == 3 and time.time() - presstime > 0.25:
                            pyautogui.press('right')
                            presstime = time.time()
                        elif time.time() - presstime > 1:
                            pyautogui.press('right')
                            i += 1
                            presstime = time.time()

                    if mouse_id == 7:
                        # print(i, time.time() - presstime)
                        if i == 3 and time.time() - presstime > 0.3:
                            pyautogui.press('left')
                            i = 0
                            presstime = time.time()
                        elif i == 3 and time.time() - presstime > 0.25:
                            pyautogui.press('left')
                            presstime = time.time()
                        elif time.time() - presstime > 1:
                            pyautogui.press('left')
                            i += 1
                            presstime = time.time()

                    # 動態手勢控制
                    if most_common_fg_id[0][
                            0] == 1 and most_common_fg_id[0][1] > 9:
                        if time.time() - presstime > 1.5:
                            pyautogui.hotkey('shift', '>')
                            print('speed up')
                            presstime = time.time()

                    elif most_common_fg_id[0][
                            0] == 2 and most_common_fg_id[0][1] > 12:
                        if time.time() - presstime > 1.5:
                            pyautogui.hotkey('shift', '<')
                            print('speed down')
                            presstime = time.time()

                elif detect_mode == 1:
                    if mouse_id == 0:  # Point gesture
                        x1, y1 = landmark_list[8]
                        cv.rectangle(debug_image, (50, 30),
                                     (cap_width - 50, cap_height - 170),
                                     (255, 0, 255), 2)
                        # 座標轉換
                        # x軸: 鏡頭上50~(cap_width - 50)轉至螢幕寬0~wScr
                        # y軸: 鏡頭上30~(cap_height - 170)轉至螢幕長0~hScr
                        x3 = np.interp(x1, (50, (cap_width - 50)), (0, wScr))
                        y3 = np.interp(y1, (30, (cap_height - 170)), (0, hScr))

                        # 6. Smoothen Values
                        clocX = plocX + (x3 - plocX) / smoothening
                        clocY = plocY + (y3 - plocY) / smoothening

                        # 7. Move Mouse
                        pyautogui.moveTo(clocX, clocY)
                        cv.circle(debug_image, (x1, y1), 15, (255, 0, 255),
                                  cv.FILLED)
                        plocX, plocY = clocX, clocY

                    elif mouse_id == 1:
                        # 10. Click mouse if distance short
                        if time.time() - presstime > 0.5:
                            pyautogui.click()
                            presstime = time.time()

                    if mouse_id == 5:
                        pyautogui.scroll(-20)

                    if mouse_id == 6:
                        pyautogui.scroll(20)

                    if mouse_id == 7:
                        if time.time() - presstime > 1.5:
                            pyautogui.click(clicks=2)
                            presstime = time.time()

                    if mouse_id == 8:
                        if time.time() - presstime > 2:
                            pyautogui.hotkey('alt', 'left')
                            presstime = time.time()

                # 比讚 從休息模式 換成 鍵盤模式
                elif detect_mode == 0:
                    if mouse_id == 5:
                        i += 1
                        if i == 1 or time.time() - presstime > 3:
                            presstime = time.time()
                        elif time.time() - presstime > 2:
                            detect_mode = 2
                            mode_change = True
                            i = 0

            # 距離上次監測到手的時間大於30秒、切回休息模式 =========================
            if time.time() - resttime > 30:
                if detect_mode != 0:
                    detect_mode = 0
                    mode_change = True

            # 檢查模式有沒有更動 ========================
            if mode_change:
                if detect_mode == 0:
                    what_mode = 'Sleep'
                elif detect_mode == 2:
                    what_mode = 'Keyboard'
                elif detect_mode == 1:
                    what_mode = 'Mouse'

                mode_change = False
                print('Mode has changed')
                print(f'Current mode => {what_mode}')

            cv.putText(debug_image, what_mode, (480, 30),
                       cv.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 4, cv.LINE_AA)
            # Screen reflection ###################################JL##########################
            cv.imshow('Hand Gesture Recognition', debug_image)

            self.trigger.emit(detect_mode)

        cap.release()
        cv.destroyAllWindows()
Ejemplo n.º 4
0
Archivo: hand.py Proyecto: baho0/HoloPC
def main():

    # Argument parsing #################################################################
    args = get_args()

    cap_device = args.device
    cap_width = 1920
    cap_height = 1080

    use_static_image_mode = args.use_static_image_mode
    min_detection_confidence = args.min_detection_confidence
    min_tracking_confidence = args.min_tracking_confidence

    use_brect = True

    # Camera preparation ###############################################################
    cap = cv.VideoCapture(cap_device)
    cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
    cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)

    # Model load #############################################################
    mp_hands = mp.solutions.hands
    hands = mp_hands.Hands(
        static_image_mode=use_static_image_mode,
        max_num_hands=1,
        min_detection_confidence=min_detection_confidence,
        min_tracking_confidence=min_tracking_confidence,
    )

    keypoint_classifier = KeyPointClassifier()

    point_history_classifier = PointHistoryClassifier()

    # Read labels ###########################################################
    with open('model/keypoint_classifier/keypoint_classifier_label.csv',
              encoding='utf-8-sig') as f:
        keypoint_classifier_labels = csv.reader(f)
        keypoint_classifier_labels = [
            row[0] for row in keypoint_classifier_labels
        ]
    with open(
            'model/point_history_classifier/point_history_classifier_label.csv',
            encoding='utf-8-sig') as f:
        point_history_classifier_labels = csv.reader(f)
        point_history_classifier_labels = [
            row[0] for row in point_history_classifier_labels
        ]

    # FPS Measurement ########################################################
    cvFpsCalc = CvFpsCalc(buffer_len=10)

    # Coordinate history #################################################################
    history_length = 16
    point_history = deque(maxlen=history_length)

    # Finger gesture history ################################################
    finger_gesture_history = deque(maxlen=history_length)

    #  ########################################################################
    mode = 0

    while True:
        fps = cvFpsCalc.get()

        # Process Key (ESC: end) #################################################
        key = cv.waitKey(10)
        if key == 27:  # ESC
            break
        number, mode = select_mode(key, mode)

        # Camera capture #####################################################
        ret, image = cap.read()

        if not ret:
            break
        image = cv.flip(image, 1)  # Mirror display
        debug_image = copy.deepcopy(image)

        # Detection implementation #############################################################
        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)

        image.flags.writeable = False
        results = hands.process(image)
        image.flags.writeable = True

        #  ####################################################################
        if results.multi_hand_landmarks is not None:
            for hand_landmarks, handedness in zip(results.multi_hand_landmarks,
                                                  results.multi_handedness):
                # Bounding box calculation
                brect = calc_bounding_rect(debug_image, hand_landmarks)
                # Landmark calculation
                landmark_list = calc_landmark_list(debug_image, hand_landmarks)

                # Conversion to relative coordinates / normalized coordinates
                pre_processed_landmark_list = pre_process_landmark(
                    landmark_list)
                pre_processed_point_history_list = pre_process_point_history(
                    debug_image, point_history)
                # Write to the dataset file
                logging_csv(number, mode, pre_processed_landmark_list,
                            pre_processed_point_history_list)

                # Hand sign classification
                hand_sign_id = keypoint_classifier(pre_processed_landmark_list)
                if hand_sign_id == 2:  # Point gesture
                    point_history.append(landmark_list[8])
                else:
                    point_history.append([0, 0])

                # Finger gesture classification
                finger_gesture_id = 0
                point_history_len = len(pre_processed_point_history_list)
                if point_history_len == (history_length * 2):
                    finger_gesture_id = point_history_classifier(
                        pre_processed_point_history_list)

                # Calculates the gesture IDs in the latest detection
                finger_gesture_history.append(finger_gesture_id)
                most_common_fg_id = Counter(
                    finger_gesture_history).most_common()

                # Drawing part
                debug_image = draw_bounding_rect(use_brect, debug_image, brect)
                debug_image = draw_landmarks(debug_image, landmark_list)
                debug_image = draw_info_text(
                    debug_image,
                    brect,
                    handedness,
                    keypoint_classifier_labels[hand_sign_id],
                    point_history_classifier_labels[most_common_fg_id[0][0]],
                )
        else:
            point_history.append([0, 0])

        debug_image = draw_point_history(debug_image, point_history)
        debug_image = draw_info(debug_image, fps, mode, number)

        # Screen reflection #############################################################
        cv.imshow('Hand Gesture Recognition', debug_image)

    cap.release()
    cv.destroyAllWindows()
Ejemplo n.º 5
0
def main():
    # 引数解析 #################################################################
    args = get_args()

    cap_device = args.device
    cap_width = args.width
    cap_height = args.height

    use_static_image_mode = args.use_static_image_mode
    min_detection_confidence = args.min_detection_confidence
    min_tracking_confidence = args.min_tracking_confidence

    use_brect = True

    # カメラ準備 ###############################################################
    cap = cv.VideoCapture(cap_device)
    cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
    cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)

    # モデルロード #############################################################
    mp_hands = mp.solutions.hands
    hands = mp_hands.Hands(
        static_image_mode=use_static_image_mode,
        max_num_hands=1,
        min_detection_confidence=min_detection_confidence,
        min_tracking_confidence=min_tracking_confidence,
    )

    keypoint_classifier = KeyPointClassifier()

    point_history_classifier = PointHistoryClassifier()

    # ラベル読み込み ###########################################################
    with open('model/keypoint_classifier/keypoint_classifier_label.csv',
              encoding='utf-8-sig') as f:
        keypoint_classifier_labels = csv.reader(f)
        keypoint_classifier_labels = [
            row[0] for row in keypoint_classifier_labels
        ]
    with open(
            'model/point_history_classifier/point_history_classifier_label.csv',
            encoding='utf-8-sig') as f:
        point_history_classifier_labels = csv.reader(f)
        point_history_classifier_labels = [
            row[0] for row in point_history_classifier_labels
        ]

    # FPS計測モジュール ########################################################
    cvFpsCalc = CvFpsCalc(buffer_len=10)

    # 座標履歴 #################################################################
    history_length = 16
    point_history = deque(maxlen=history_length)

    # フィンガージェスチャー履歴 ################################################
    finger_gesture_history = deque(maxlen=history_length)

    #  ########################################################################
    mode = 0

    while True:
        fps = cvFpsCalc.get()

        # キー処理(ESC:終了) #################################################
        key = cv.waitKey(10)
        if key == 27:  # ESC
            break
        number, mode = select_mode(key, mode)

        # カメラキャプチャ #####################################################
        ret, image = cap.read()
        if not ret:
            break
        image = cv.flip(image, 1)  # ミラー表示
        debug_image = copy.deepcopy(image)

        # 検出実施 #############################################################
        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)

        image.flags.writeable = False
        results = hands.process(image)
        image.flags.writeable = True

        #  ####################################################################
        if results.multi_hand_landmarks is not None:
            for hand_landmarks, handedness in zip(results.multi_hand_landmarks,
                                                  results.multi_handedness):
                # 外接矩形の計算
                brect = calc_bounding_rect(debug_image, hand_landmarks)
                # ランドマークの計算
                landmark_list = calc_landmark_list(debug_image, hand_landmarks)

                # 相対座標・正規化座標への変換
                pre_processed_landmark_list = pre_process_landmark(
                    landmark_list)
                pre_processed_point_history_list = pre_process_point_history(
                    debug_image, point_history)
                # 学習データ保存
                logging_csv(number, mode, pre_processed_landmark_list,
                            pre_processed_point_history_list)

                # ハンドサイン分類
                hand_sign_id = keypoint_classifier(pre_processed_landmark_list)
                if hand_sign_id == 2:  # 指差しサイン
                    point_history.append(landmark_list[8])  # 人差指座標
                else:
                    point_history.append([0, 0])

                # フィンガージェスチャー分類
                finger_gesture_id = 0
                point_history_len = len(pre_processed_point_history_list)
                if point_history_len == (history_length * 2):
                    finger_gesture_id = point_history_classifier(
                        pre_processed_point_history_list)

                # 直近検出の中で最多のジェスチャーIDを算出
                finger_gesture_history.append(finger_gesture_id)
                most_common_fg_id = Counter(
                    finger_gesture_history).most_common()

                # 描画
                debug_image = draw_bounding_rect(use_brect, debug_image, brect)
                debug_image = draw_landmarks(debug_image, landmark_list)
                debug_image = draw_info_text(
                    debug_image,
                    brect,
                    handedness,
                    keypoint_classifier_labels[hand_sign_id],
                    point_history_classifier_labels[most_common_fg_id[0][0]],
                )
        else:
            point_history.append([0, 0])

        debug_image = draw_point_history(debug_image, point_history)
        debug_image = draw_info(debug_image, fps, mode, number)

        # 画面反映 #############################################################
        cv.imshow('Hand Gesture Recognition', debug_image)

    cap.release()
    cv.destroyAllWindows()
Ejemplo n.º 6
0
def HandTracking(cap, width, height, conf_flg=0):
    # ×ボタンが押されたかのフラグ(hand_gui.py内の変数、flg_closePush)の初期化
    hand_gui.close_switch_py(0)
    # 引数解析 #################################################################
    args = get_args()

    flg_video = 0  #「1」でカメラが接続されていない
    flg_break = 0  #「1」で最初のループを抜け終了する⇒正常終了
    name_pose = "Unknown"
    focus_flg = 1  #index.html の表示・非表示の切り替え、「0」:Main.pyで開いた場合、「1」:HandTracking.pyで開いた場合
    namePose_flg = 1  #complete_old.htmlの開始・終了フラグ
    potision_flg = 0
    #flg_closePush = 0
    global ShortCutList
    ShortCutList = config_sys_set()
    cap_device = args.device
    cap_width = args.width
    cap_height = args.height

    use_static_image_mode = args.use_static_image_mode
    min_detection_confidence = args.min_detection_confidence
    min_tracking_confidence = args.min_tracking_confidence

    use_brect = True
    #width,height = autopy.screen.size() #eel で立ち上げた際の表示位置を指定するために取得

    while (True):  #カメラが再度接続するまでループ処理
        #カメラが接続されていないフラグの場合
        if (flg_video == 1):
            #カメラが接続されているか確認
            cap = cv.VideoCapture(cap_device)
            cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
            cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)
            ret, frame = cap.read()
            if (ret is True):
                flg_video = 0
                name_pose = "Unknown"
                focus_flg = 1
                namePose_flg = 1
                cap.release()
                eel.overlay_controll(True)
                eel.object_change("demo2.html", True)
                #eel.sleep(1)
                sel_cam_before = 999

                while (True):
                    if (decideFlgHT == 1):
                        if (sel_camHT != sel_cam_before):
                            cap = cv.VideoCapture(sel_camHT)
                            cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
                            cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)
                            ret, frame = cap.read(sel_camHT)
                            if (ret is False):
                                eel.alert_mess()
                                cap.release()
                                decide_camHT_py(999)
                                decide_flgHT_py(0)
                                sel_cam_before = sel_camHT
                                continue
                            else:
                                decide_flgHT_py(0)
                                break
                        decide_flgHT_py(0)
                        break
                    if (sel_camHT != 999):
                        eel.sleep(0.01)
                        if (sel_camHT != sel_cam_before):
                            if (sel_cam_before != 999):
                                cap.release()
                            cap = cv.VideoCapture(sel_camHT)
                            cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
                            cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)
                            sel_cam_before = sel_camHT
                        ret, frame = cap.read()
                        if (ret is True):
                            # UI側へ転送(画像) #####################################################
                            _, imencode_image = cv.imencode('.jpg', frame)
                            base64_image = base64.b64encode(imencode_image)
                            eel.set_base64image("data:image/jpg;base64," +
                                                base64_image.decode("ascii"))
                            continue
                        else:
                            eel.alert_mess()
                            cap.release()
                            decide_camHT_py(999)
                            sel_cam_before = sel_camHT
                            if (decideFlgHT == 1):
                                decide_flgHT_py(0)
                            continue
                    else:
                        eel.sleep(0.01)
                        continue  #最初の while に戻る
            else:
                #カメラが接続されていない場合
                #print("webcamないよ!!!")
                eel.sleep(0.01)
                time.sleep(0.01)
                continue  #最初の while に戻る
        elif (flg_break == 1):
            decide_camHT_py(999)
            decide_flgHT_py(0)
            break  #最初の while を抜けて正常終了

        # カメラ準備 ###############################################################
        #cap = cv.VideoCapture(cap_device)
        #cap.set(cv.CAP_PROP_FRAME_WIDTH, cap_width)
        #cap.set(cv.CAP_PROP_FRAME_HEIGHT, cap_height)

        # モデルロード #############################################################
        mp_hands = mp.solutions.hands
        hands = mp_hands.Hands(
            static_image_mode=use_static_image_mode,
            max_num_hands=1,
            min_detection_confidence=min_detection_confidence,
            min_tracking_confidence=min_tracking_confidence,
        )

        keypoint_classifier = KeyPointClassifier()

        point_history_classifier = PointHistoryClassifier()

        # ラベル読み込み ###########################################################
        with open('model/keypoint_classifier/keypoint_classifier_label.csv',
                  encoding='utf-8-sig') as f:
            keypoint_classifier_labels = csv.reader(f)
            keypoint_classifier_labels = [
                row[0] for row in keypoint_classifier_labels
            ]
        with open(
                'model/point_history_classifier/point_history_classifier_label.csv',
                encoding='utf-8-sig') as f:
            point_history_classifier_labels = csv.reader(f)
            point_history_classifier_labels = [
                row[0] for row in point_history_classifier_labels
            ]

        # FPS計測モジュール ########################################################
        cvFpsCalc = CvFpsCalc(buffer_len=10)

        # 座標履歴 #################################################################
        history_length = 16
        point_history = deque(maxlen=history_length)

        # フィンガージェスチャー履歴 ################################################
        finger_gesture_history = deque(maxlen=history_length)

        #  ########################################################################
        mode = 0
        CountPose = [0, 0, 0, 0, 0, 0, 0]
        CountMotion = [0, 0, 0, 0]  # [Top,Right,Down,Left]
        identification = False
        while True:
            fps = cvFpsCalc.get()
            # キー処理(ESC:終了) #################################################
            key = cv.waitKey(10)
            if key == 27:  # ESC
                break
            number, mode = select_mode(key, mode)

            # カメラキャプチャ #####################################################
            ret, image = cap.read()
            if not ret:
                #それぞれのフラグを立てて、システムを終了させ、最初の while に戻る
                flg_video = 1
                focus_flg = 0

                print("【通知】WebCameraが接続されていません。")
                eel.focusSwitch(width, height, focus_flg)
                eel.overlay_controll(True)
                eel.object_change("connect.html", True)
                cap.release()
                cv.destroyAllWindows()
                break

            image = cv.flip(image, 1)  # ミラー表示
            debug_image = copy.deepcopy(image)

            # 検出実施 #############################################################
            image = cv.cvtColor(image, cv.COLOR_BGR2RGB)

            image.flags.writeable = False
            results = hands.process(image)
            image.flags.writeable = True

            #  ####################################################################
            if results.multi_hand_landmarks is not None:
                #j=1
                for hand_landmarks, handedness in zip(
                        results.multi_hand_landmarks,
                        results.multi_handedness):
                    # 外接矩形の計算
                    brect = calc_bounding_rect(debug_image, hand_landmarks)
                    # ランドマークの計算
                    landmark_list = calc_landmark_list(debug_image,
                                                       hand_landmarks)

                    # 相対座標・正規化座標への変換
                    pre_processed_landmark_list = pre_process_landmark(
                        landmark_list)
                    pre_processed_point_history_list = pre_process_point_history(
                        debug_image, point_history)
                    # 学習データ保存
                    logging_csv(number, mode, pre_processed_landmark_list,
                                pre_processed_point_history_list)

                    # ハンドサイン分類
                    hand_sign_id = keypoint_classifier(
                        pre_processed_landmark_list)

                    if hand_sign_id == 1:  # Dangサイン
                        point_history.append(landmark_list[8])  # 人差指座標
                    else:
                        point_history.append([0, 0])

                    # フィンガージェスチャー分類
                    finger_gesture_id = 0
                    point_history_len = len(pre_processed_point_history_list)
                    if point_history_len == (history_length * 2):
                        finger_gesture_id = point_history_classifier(
                            pre_processed_point_history_list)

                    # 直近検出の中で最多のジェスチャーIDを算出
                    finger_gesture_history.append(finger_gesture_id)
                    most_common_fg_id = Counter(
                        finger_gesture_history).most_common()

                    gesture_name = point_history_classifier_labels[
                        most_common_fg_id[0][0]]

                    # 描画
                    debug_image = draw_bounding_rect(use_brect, debug_image,
                                                     brect)
                    debug_image = draw_landmarks(debug_image, landmark_list)
                    debug_image = draw_info_text(
                        debug_image,
                        brect,
                        handedness,
                        keypoint_classifier_labels[hand_sign_id],
                        gesture_name,
                    )

                    #人差し指の先の座標を取得
                    x, y = landmark_list[8]
                    #座標調整
                    x_width = args.width * 0.05
                    x = x - x_width
                    x = x * 1.5
                    y = y * 1.5
                    #ジェスチャーが判定された回数をカウント
                    if gesture_name == 'Stop':
                        CountMotion = [0, 0, 0, 0]
                    elif gesture_name == 'Move_Top':
                        Count_temp = CountMotion[0]
                        Count_temp += 1
                        CountMotion = [Count_temp, 0, 0, 0]
                    elif gesture_name == 'Move_Right':
                        Count_temp = CountMotion[1]
                        Count_temp += 1
                        CountMotion = [0, Count_temp, 0, 0]
                    elif gesture_name == 'Move_Down':
                        Count_temp = CountMotion[2]
                        Count_temp += 1
                        CountMotion = [0, 0, Count_temp, 0]
                    elif gesture_name == 'Move_Left':
                        Count_temp = CountMotion[3]
                        Count_temp += 1
                        CountMotion = [0, 0, 0, Count_temp]

                    #各種操作の実行
                    CountPose, CountMotion = PoseAction.action(
                        hand_sign_id, x, y, CountPose, CountMotion,
                        ShortCutList)
                    name_pose = keypoint_classifier_labels[hand_sign_id]
                    eel.set_posegauge(str(name_pose))
                    identification = True

            else:
                point_history.append([0, 0])
                if identification == True:
                    eel.set_posegauge('None')
                    identification = False
                    eel.shortcut_overlay(False, 0)

            debug_image = draw_point_history(debug_image, point_history)
            debug_image = draw_info(debug_image, fps, mode, number)

            # 画面反映 #############################################################
            debug_image = cv.resize(debug_image, dsize=(520, 260))
            cv.imshow('FOCUS preview', debug_image)
            if potision_flg == 0:
                cv.moveWindow('FOCUS preview', 0, 0)
                potision_flg = 1

            # eel立ち上げ #############################################################
            #cnt_gui, flg_end, flg_restart, flg_start, keep_flg = hand_gui.start_gui(cnt_gui, name_pose, flg_restart, flg_start, keep_flg)

            if (namePose_flg == 1):
                eel.object_change("complete_old.html", True)
                #eel.sleep(0.01)
                #eel.init("GUI/web")
                #eel.start("開きたい上記のフォルダ下のファイル名",~
                #eel.start("html/keeper.html",
                #            port = 0,
                #            mode='chrome',
                #            size=(4, 2),  #サイズ指定(横, 縦)
                #            position=(width,0), #位置指定(left, top)
                #            block=False
                #            )
                eel.sleep(0.01)
                print("【通知】準備完了")
                namePose_flg = 0
            elif (focus_flg == 1 and name_pose != 'Unknown'):
                eel.object_change("complete_old.html", False)
                eel.overlay_controll(False)
                eel.focusSwitch(width, height, focus_flg)
                print("【実行】index.html")
                eel.sleep(0.01)
                #eel.set_posegauge(name_pose,i)
                focus_flg = 0
                #i+=1

            # eel立ち上げ #############################################################
            flg_end = hand_gui.start_gui()
            if (flg_end == 1):
                #正常に終了する処理(中間のループを抜ける)
                flg_break = 1
                eel.endSwitch()  #flg_end の値をもとに戻す関数
                cap.release()
                cv.destroyAllWindows()
                eel.overlay_controll(False)
                eel.object_change("endpage.html", False)
                #eel.windowclose_keeper()
                break