Esempio n. 1
0
    def update_preview_state(self, frame, contours):
        """
        Get the average color value for the contour for every X amount of frames
        to prevent flickering and more precise results.
        """
        max_average_rounds = 8
        for index, (x, y, w, h) in enumerate(contours):
            if index in self.average_sticker_colors and len(
                    self.average_sticker_colors[index]) == max_average_rounds:
                sorted_items = {}
                for bgr in self.average_sticker_colors[index]:
                    key = str(bgr)
                    if key in sorted_items:
                        sorted_items[key] += 1
                    else:
                        sorted_items[key] = 1
                most_common_color = max(sorted_items,
                                        key=lambda i: sorted_items[i])
                self.average_sticker_colors[index] = []
                self.preview_state[index] = eval(most_common_color)
                break

            roi = frame[y + 7:y + h - 7, x + 14:x + w - 14]
            avg_bgr = ColorDetector.get_dominant_color(roi)
            closest_color = ColorDetector.get_closest_color(
                avg_bgr)['color_bgr']
            self.preview_state[index] = closest_color
            if index in self.average_sticker_colors:
                self.average_sticker_colors[index].append(closest_color)
            else:
                self.average_sticker_colors[index] = [closest_color]
Esempio n. 2
0
    def run(self):
        """
        Open up the webcam and present the user with the Qbr user interface.

        Returns a string of the scanned state in rubik's cube notation.
        """
        while True:
            _, frame = self.cam.read()
            key = cv2.waitKey(10) & 0xff

            # Quit on escape.
            if key == 27:
                break

            # Update the snapshot when space bar is pressed.
            if key == 32 and not self.calibrate_mode:
                self.update_snapshot_state(frame)

            # Toggle calibrate mode.
            if key == ord(CALIBRATE_MODE_KEY):
                self.reset_calibrate_mode()
                self.calibrate_mode = not self.calibrate_mode

            grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            blurredFrame = cv2.blur(grayFrame, (5, 5))
            cannyFrame = cv2.Canny(blurredFrame, 30, 60, 3)
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
            dilatedFrame = cv2.dilate(cannyFrame, kernel)

            contours = self.find_contours(dilatedFrame)
            if len(contours) == 9:
                self.draw_contours(frame, contours)
                if not self.calibrate_mode:
                    self.update_preview_state(frame, contours)
                elif key == 32 and self.done_calibrating == False:
                    current_color = self.cube_sides[
                        self.current_color_to_calibrate_index]
                    (x, y, w, h) = contours[4]
                    roi = frame[y + 7:y + h - 7, x + 14:x + w - 14]
                    avg_bgr = ColorDetector.get_dominant_color(roi)
                    self.calibrated_colors[current_color] = avg_bgr
                    self.current_color_to_calibrate_index += 1
                    self.done_calibrating = self.current_color_to_calibrate_index == len(
                        self.cube_sides)
                    if self.done_calibrating:
                        ColorDetector.set_cube_color_pallete(
                            self.calibrated_colors)

            if self.calibrate_mode:
                self.display_current_color_to_calibrate(frame)
                self.display_calibrated_colors(frame)
            else:
                self.draw_preview_stickers(frame)
                self.draw_snapshot_stickers(frame)
                self.display_scanned_sides(frame)

            cv2.imshow('default', frame)

        self.cam.release()
        cv2.destroyAllWindows()

        if len(self.sides.keys()) != 6:
            return False

        if not self.scanned_successfully():
            return False

        # Convert all the sides and their BGR colors to cube notation.
        notation = dict(self.sides)
        for side, preview in notation.items():
            for sticker_index, bgr in enumerate(preview):
                notation[side][
                    sticker_index] = ColorDetector.convert_bgr_to_notation(bgr)

        # Join all the sides together into one single string.
        # Order must be URFDLB (white, red, green, yellow, orange, blue)
        combined = ''
        for side in ['white', 'red', 'green', 'yellow', 'orange', 'blue']:
            combined += ''.join(notation[side])
        return combined