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()