Example #1
0
class OWCamera(OWWidget, ConcurrentWidgetMixin):
    name = "Camera"
    icon = "icons/WebcamCapture.svg"

    want_main_area = False

    class Outputs:
        DominantColors = Output("DominantColors", list)
        BouncingBalls = Output("BouncingBalls", list)

    def __init__(self):
        OWWidget.__init__(self)
        ConcurrentWidgetMixin.__init__(self)

        # self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)

        self.vc = cv.VideoCapture(0)
        self.vc.set(3, 640)  # set width
        self.vc.set(4, 480)  # set height

        self.image_label = QLabel()
        # self.image_label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.controlArea.layout().addWidget(self.image_label)
        # self.resize(pixmap.width(), pixmap.height())
        #
        # self.frame_timer = QTimer()
        # self.frame_timer.timeout.connect(self.update_frame)
        # self.frame_timer.start(0)
        #
        # self.output_timer = QTimer()
        # self.output_timer.timeout.connect(self.commit)
        # self.output_timer.start(0)

        # self.current_frame = None
        self.start(self.worker)
        self.setBlocking(False)

    def worker(self, state: TaskState):
        while True:
            state.set_partial_result(self.update_frame())
            time.sleep(1 / 10)

    def on_partial_result(self, result):
        dominant, bb = result
        self.Outputs.DominantColors.send(dominant)
        self.Outputs.BouncingBalls.send(bb)

    def remap(self, x, in_min, in_max, out_min, out_max):
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

    def update_frame(self):
        # read pixle values from camera
        _, frame = self.vc.read()
        balls = [None, None]

        if frame.size:
            # display image in orange widget
            image = QImage(frame[:, :, ::-1].copy(), frame.shape[1],
                           frame.shape[0], QImage.Format_RGB888)
            pix = QPixmap.fromImage(image).scaled(
                self.image_label.size(),
                Qt.KeepAspectRatio | Qt.FastTransformation)
            self.image_label.setPixmap(pix)

        # Convert BGR to HSV
        hsv_image = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
        # accumulated_mask = np.zeros(hsv_image.shape[:2], dtype='uint8')

        for index, (lower, upper) in enumerate(BOUNDARIES):
            mask = cv.inRange(hsv_image, lower, upper)
            size = self.remap(np.count_nonzero(mask), 0, mask.size, 0.2, 1)

            rgb_value = (cv.cvtColor(
                np.uint8([[cv.mean(hsv_image, mask)[:3]]]),
                cv.COLOR_HSV2RGB).flatten())
            balls[index] = (tuple(rgb_value) if rgb_value.any() else None,
                            size)

            # accumulated_mask = cv.bitwise_or(accumulated_mask, mask)

        dominant_colors = find_image_colors(hsv_image,
                                            image_processing_size=(100, 100))
        # accumulated_mask = cv.bitwise_not(accumulated_mask)
        # res = cv.bitwise_and(frame, frame, mask=accumulated_mask)

        # print(res.reshape((res.shape[0] * res.shape[1], 3)).shape)
        # print(cv.mean(hsv_image, accumulated_mask))

        # res = cv.resize(res, (100, 100), interpolation=cv.INTER_AREA)

        # if res.size:
        #     # display image in orange widget
        #     image = QImage(res[:, :, ::-1].copy(), res.shape[1], res.shape[0], QImage.Format_RGB888)
        #     pix = QPixmap.fromImage(image).scaled(self.image_label.size(), Qt.KeepAspectRatio | Qt.FastTransformation)
        #     self.image_label.setPixmap(pix)

        # res = res.reshape((res.shape[0] * res.shape[1], 3))
        # res = res[~(res == 0).all(1)]
        # # # print(res)
        #
        # colors = find_image_colors(res, k=6, image_processing_size=(150, 150))

        return dominant_colors, balls

    def onDeleteWidget(self):
        self.vc.release()
        super().onDeleteWidget()