예제 #1
0
class Drawer:
    @staticmethod
    def label_face(frame, face_rect: tuple, color=(0, 0, 250)):
        x, y, w, h = face_rect
        horizon_line_length = int(w / 8)
        vertical_line_length = int(h / 8)
        center = (int(x + w / 2), int(y + h / 2))
        cv2.line(frame, (x - horizon_line_length, center[1]),
                 (x + horizon_line_length, center[1]), color, 2)
        cv2.line(frame, (x + w - horizon_line_length, center[1]),
                 (x + w + horizon_line_length, center[1]), color, 2)
        cv2.line(frame, (center[0], y - vertical_line_length),
                 (center[0], y + vertical_line_length), color, 2)
        cv2.line(frame, (center[0], y + h - vertical_line_length),
                 (center[0], y + h + vertical_line_length), color, 2)
        cv2.circle(frame, center, int(h / 2), color, 2)


if __name__ == '__main__':
    img = cv2.imread("assets/timg2.jpg")
    face_detector = FaceDetector()
    face_detector.detect_face(img)
    face_list = face_detector.get_face_list()
    if len(face_list) > 0:
        for face in face_list:
            Drawer.label_face(img, face.get_rect(), color=(0, 0, 200))
    cv2.imshow("test Drawer", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
예제 #2
0
class CameraWindow:
    def __init__(self, idx, window):
        self.idx = idx
        self.update_flag = True
        self.info_label = tk.Label(window,
                                   text="Monitor [ %d ] @ %2d (fps)" %
                                   (idx + 1, 0),
                                   font=('Arial', 10))
        self.info_label.grid(row=3, column=idx + 1)
        img = Image.fromarray(np.full((240, 320), 100))
        img_tk = ImageTk.PhotoImage(img)
        self.frame_label = tk.Label(window)
        self.frame_label.configure(image=img_tk)
        self.frame_label.grid(row=4, column=idx + 1, ipadx=5, ipady=10)
        self.start_btn = tk.Button(window,
                                   text='Start',
                                   command=self.click_button,
                                   width=39,
                                   font=('Arial', 10))
        self.start_btn.grid(row=5, column=idx + 1)
        self.split_btn = tk.Button(window,
                                   text='Split This Window',
                                   command=self.split_window,
                                   width=39,
                                   font=('Arial', 10))
        self.split_btn.grid(row=6, column=idx + 1)
        self.face_detect_flag = tk.BooleanVar()
        self.face_detect_checkbutton = tk.Checkbutton(
            window,
            text="Open Face Detection   (Detect face in Split window)",
            variable=self.face_detect_flag)
        self.face_detect_checkbutton.grid(row=7,
                                          column=idx + 1,
                                          sticky='w',
                                          ipadx=2)
        self.face_save_flag = tk.BooleanVar()
        self.face_save_checkbutton = tk.Checkbutton(
            window,
            text="Save Face Image     (Save face when face detected)",
            variable=self.face_save_flag)
        self.face_save_checkbutton.grid(row=8,
                                        column=idx + 1,
                                        sticky='w',
                                        ipadx=2)
        self.face_detector = FaceDetector()
        self.max_face_store_number = 200
        self.thread_list = []
        self.tcp = None

    def update_frame_label(self):
        while self.update_flag:
            frame = self.tcp.frame
            fps = self.tcp.fps
            if frame is not None:
                frame = cv2.resize(frame, (320, 240))
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                img = Image.fromarray(frame)
                img_tk = ImageTk.PhotoImage(img)
                self.frame_label.configure(image=img_tk)
                info_text = "Monitor [ %d ] @ %2d (fps)" % (self.idx + 1, fps)
                self.info_label.configure(text=info_text)
            time.sleep(0.5)

    def run_monitor(self):
        try:
            print("Connecting to the monitor...")
            self.tcp = TCPRequest(MONITOR_ADDR[self.idx])
            t = threading.Thread(target=self.tcp.start)
            print("Connected!")
            print("Waiting for Image...")
            self.thread_list.append(t)
            t.start()

            self.update_flag = True
            t2 = threading.Thread(target=self.update_frame_label)
            self.thread_list.append(t2)
            t2.start()
        except:
            msg.showwarning("Warning", "You must set the monitor before use!")

    def stop_monitor(self):
        self.update_flag = False

        if self.tcp is not None:
            print("Stop the monitor...")
            self.tcp.stop()
            print("Stopped!")
            self.tcp = None
        else:
            msg.showwarning(
                "Warning",
                "Can't stop monitor, no matched monitor is running.")

    def click_button(self):
        text = self.start_btn.cget("text")

        # Start to Run monitor
        if text == "Start":
            self.start_btn.configure(text="Stop")
            self.run_monitor()
        # Stop run monitor
        else:
            self.start_btn.configure(text="Start")
            self.stop_monitor()

    def save_face(self, frame, rect):
        if not os.path.exists("face_history"):
            os.makedirs("face_history")
        # remove img dir if this directory is full of pictures
        if len(os.listdir("face_history")) > self.max_face_store_number:
            os.removedirs("face_history")
            os.mkdir("face_history")
        x, y, w, h = rect
        file_name = os.path.join(
            "face_history",
            datetime.now().strftime("%Y_%m_%d-%H_%M_%S") + ".jpg")
        cv2.imwrite(file_name, frame[y - 10:y + h + 10, x - 10:x + w + 10])
        print("Face Image saved as -> face_history/" + file_name)

    def show_max_window(self):
        while True:
            frame = self.tcp.frame.copy()
            face_detect_bool = self.face_detect_flag.get()
            face_save_bool = self.face_save_flag.get()

            # detect the face and label
            if face_detect_bool:
                self.face_detector.detect_face(frame)
                face_list = self.face_detector.get_face_list()
                if len(face_list) > 0:
                    for face in face_list:
                        Drawer.label_face(frame, face.get_rect())
                        # save face(s)
                        if face_save_bool is True:
                            self.save_face(self.tcp.frame, face.get_rect())
            else:
                if face_save_bool:
                    msg.showwarning(
                        "Warning",
                        "Open Face Detection before save face image!")
                    self.face_save_flag.set(False)

            # Write Text on the frame
            localtime = time.asctime(time.localtime(time.time()))
            width = frame.shape[0]
            cv2.putText(frame, localtime, (int(0.9 * width), 20),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 255, 0))
            if face_detect_bool is True:
                cv2.putText(frame, "Face Detection: True",
                            (int(0.9 * width), 35), cv2.FONT_HERSHEY_SIMPLEX,
                            0.4, (0, 255, 0))
            else:
                cv2.putText(frame, "Face Detection: False",
                            (int(0.9 * width), 35), cv2.FONT_HERSHEY_SIMPLEX,
                            0.4, (0, 0, 255))
            if face_save_bool is True:
                cv2.putText(frame, "Face Save     : True",
                            (int(0.9 * width), 50), cv2.FONT_HERSHEY_SIMPLEX,
                            0.4, (0, 255, 0))
            else:
                cv2.putText(frame, "Face Save     : False",
                            (int(0.9 * width), 50), cv2.FONT_HERSHEY_SIMPLEX,
                            0.4, (0, 0, 255))

            cv2.imshow("Split@Monitor %d" % (self.idx + 1), frame)
            if cv2.waitKey(1) == ord('q'):
                cv2.destroyAllWindows()
                break

    def split_window(self):
        if self.tcp is None:
            msg.showwarning("Warning",
                            "You need to start the monitor at first!")
            return
        t = threading.Thread(target=self.show_max_window)
        self.thread_list.append(t)
        t.start()

    def join_all_threads(self):
        for t in self.thread_list:
            t.join()