Пример #1
0
    def pickColor(self):
        "pick a color on the screen, part 1"
        # screenshot desktop
        self._img = QApplication.primaryScreen().grabWindow(0)

        self._view = QGraphicsView(self)
        scene = QGraphicsScene(self)  # display screenshot at full size

        self._view.setWindowFlags(Qt.FramelessWindowHint)
        self._view.setWindowFlags(Qt.WindowType_Mask)
        self._view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scene.addPixmap(self._img)  #; self._view.setScene(scene)

        self._mag = magnifier()
        self._mag.setBackground(self._img)
        self._mag.setSize(11, 11)
        scene.addItem(self._mag)
        self._view.setScene(scene)

        self._appview = QApplication
        self._appview.setOverrideCursor(Qt.CrossCursor)

        self._view.showFullScreen()
        self._view.mousePressEvent = self._pickedColor
Пример #2
0
 def change(self, p, out):
     scene = QGraphicsScene()
     scene.addPixmap(
         QPixmap.fromImage(
             p.scaled(self.graphicsView.size() - QtCore.QSize(2, 2))))
     self.graphicsView.setScene(scene)
     if out:
         self.outLabel.setText(out[::-1])
         rows = self.tableWidget.rowCount()
         self.tableWidget.setRowCount(rows + 1)
         item = QtWidgets.QTableWidgetItem()
         self.tableWidget.setVerticalHeaderItem(rows, item)
         self.tableWidget.verticalHeaderItem(rows).setText(str(rows))
         item = QtWidgets.QTableWidgetItem()
         self.tableWidget.setItem(rows, 0, item)
         item = QtWidgets.QTableWidgetItem()
         self.tableWidget.setItem(rows, 1, item)
         item = QtWidgets.QTableWidgetItem()
         self.tableWidget.setItem(rows, 2, item)
         self.tableWidget.item(rows, 0).setText(
             "N/A")  # TODO: get the name from a database
         self.tableWidget.item(rows, 1).setText(out[::-1])
         self.tableWidget.item(rows, 2).setText(
             QtCore.QDateTime().currentDateTime().toString())
         self.tableWidget.scrollToBottom()
Пример #3
0
 def _update_portrait_box(self):
     portrait_service = locator.get_scoped("PortraitService")
     mini_portraits = portrait_service.get_sorted_portraits_for_character(self.selection, "bu")
     if mini_portraits:
         _, texture = mini_portraits[0]
         scene = QGraphicsScene()
         scene.addPixmap(QPixmap.fromImage(texture.image()))
         self.portrait_display.setScene(scene)
     else:
         self.portrait_display.setScene(None)
Пример #4
0
    def _set_portrait_from_current_index(self):
        portrait_name, texture = self._portraits[self._current_index]
        self.portrait_name_label.setText(portrait_name)
        self.current_image_label.setText(
            "%d / %d" % (self._current_index + 1, len(self._portraits)))

        scene = QGraphicsScene()
        scene.addPixmap(QPixmap.fromImage(texture.image()))
        scene.setSceneRect(0.0, 0.0, 128.0, 128.0)
        self.display.setScene(scene)
        self.display.setSceneRect(0.0, 0.0, float(texture.width()),
                                  float(texture.height()))
Пример #5
0
    def generate(self):
        if self.data is None:
            return -1

        scene = QGraphicsScene()
        qr = qrcode.QRCode(version=2,
                           error_correction=qrcode.constants.ERROR_CORRECT_M,
                           border=1)
        qr.add_data(self.data)
        qr.make()
        self.img_file = qr.make_image()
        qim = ImageQt(self.img_file)
        pixmap = QPixmap.fromImage(qim).scaled(256, 256)
        scene.addPixmap(pixmap)
        self.ui.graphicsView.setScene(scene)
Пример #6
0
class CaptchaDialogue(QDialog):
    def __init__(self, *args, **kwargs):
        super(CaptchaDialogue, self).__init__(*args, **kwargs)

        self.ui = ui.CaptchaDialogue()
        self.ui.setupUi(self)

        self.captcha_generator = ImageCaptcha()
        self.scene = QGraphicsScene()
        self.ui.captcha_view.setScene(self.scene)

        self.text = None

        self.ui.buttons.accepted.connect(self.accept)
        self.ui.buttons.rejected.connect(self.reject)

    def open(self):
        self.generate_captcha()
        super().open()

    def done(self, result: QDialog.DialogCode):
        if result == QDialog.Accepted and self.ui.captcha_input.text(
        ) != self.text:
            self.ui.input_label.setText("Incorrect CAPTCHA given. Try again:")
            self.ui.input_label.setStyleSheet("color: red")
            self.generate_captcha()
        else:
            self.ui.input_label.setText(
                "Enter the characters displayed above:")
            self.ui.input_label.setStyleSheet("")
            self.ui.captcha_input.clear()
            super().done(result)

    def generate_captcha(self):
        self.text = self._generate_text()
        image_bytes = self.captcha_generator.generate(self.text).getvalue()
        image = QByteArray(image_bytes)

        pixmap = QPixmap()
        pixmap.loadFromData(image, "png")
        self.scene.clear()
        self.scene.addPixmap(pixmap)

    @staticmethod
    def _generate_text() -> str:
        """Return a string of random characters to be used for CAPTCHA generation."""
        sample = random.sample(CHARACTERS, 6)
        return "".join(sample)
Пример #7
0
 def relationship_pixmap(self, str_object_class_name_list):
     """A pixmap for the given object_class name list,
     created by rendering several object pixmaps next to each other."""
     if not str_object_class_name_list:
         engine = CharIconEngine("\uf1b3", 0)
         return engine.pixmap(self.ICON_SIZE)
     object_class_name_list = tuple(str_object_class_name_list.split(","))
     if object_class_name_list in self.rel_cls_pixmap_cache:
         return self.rel_cls_pixmap_cache[object_class_name_list]
     scene = QGraphicsScene()
     x = 0
     for j, object_class_name in enumerate(object_class_name_list):
         pixmap = self.object_pixmap(object_class_name)
         pixmap_item = scene.addPixmap(pixmap)
         if j % 2 == 0:
             y = 0
         else:
             y = -0.875 * 0.75 * pixmap_item.boundingRect().height()
             pixmap_item.setZValue(-1)
         pixmap_item.setPos(x, y)
         x += 0.875 * 0.5 * pixmap_item.boundingRect().width()
     pixmap = QPixmap(scene.itemsBoundingRect().toRect().size())
     pixmap.fill(Qt.transparent)
     painter = QPainter(pixmap)
     painter.setRenderHint(QPainter.Antialiasing, True)
     scene.render(painter)
     painter.end()
     self.rel_cls_pixmap_cache[object_class_name_list] = pixmap
     return pixmap
Пример #8
0
class ImageViewer(QWidget):
    def __init__(self, image_path):
        super().__init__()

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        layout = QVBoxLayout()
        layout.addWidget(self.view)
        self.setLayout(layout)

        self.load_image(image_path)

    def load_image(self, image_path):
        pixmap = QPixmap(image_path)
        self.scene.addPixmap(pixmap)
        self.view.fitInView(QRectF(0, 0, pixmap.width(), pixmap.height()), Qt.KeepAspectRatio)
        self.scene.update()
Пример #9
0
class ImageViewer(QWidget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        layout = QVBoxLayout()
        layout.addWidget(self.view)

        self.img_width = None
        self.img_height = None

        self.setLayout(layout)

    def load_image(self, image_arr):
        self.clear()

        image_path = QImage(image_arr, image_arr.shape[1], image_arr.shape[0], QImage.Format_RGB888)

        pixmap = QPixmap(image_path)
        self.scene.addPixmap(pixmap)

        self.img_width = pixmap.width()
        self.img_height = pixmap.height()

        self.scale_self()

        self.scene.update()

    def scale_self(self):
        if self.img_width is not None:
            self.view.fitInView(QRectF(0, 0, self.img_width, self.img_height), Qt.KeepAspectRatio)
            self.view.scale(self.img_width / self.scene.width(), self.img_height / self.scene.height())

    def clear(self):
        self.scene.clear()
Пример #10
0
class DynamicView(QGraphicsView):
    viewChanged = Signal(QRect, float, int, int)

    def __init__(self, image, parent=None):
        super(DynamicView, self).__init__(parent)
        self.scene = QGraphicsScene()
        self.scene.setBackgroundBrush(Qt.darkGray)
        self.setScene(self.scene)
        self.set_image(image)
        self.setRenderHint(QPainter.SmoothPixmapTransform)
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.ZOOM_STEP = 0.2
        self.mouse_pressed = False
        self.next_fit = False
        self.fit_scale = 0
        self.zoom_fit()

    def set_image(self, image):
        if type(image) is QPixmap:
            pixmap = image
        elif type(image) is QImage:
            pixmap = QPixmap.fromImage(image)
        elif type(image) is np.ndarray:
            pixmap = QPixmap.fromImage(mat2img(image))
        else:
            raise TypeError(
                self.tr('DynamicView.set_image: Unsupported type: {}'.format(
                    type(image))))
        if not self.scene.items():
            self.scene.addPixmap(pixmap)
        else:
            self.scene.items()[0].setPixmap(pixmap)
        self.scene.setSceneRect(QRectF(pixmap.rect()))

    def zoom_full(self):
        self.set_scaling(1)
        self.next_fit = True
        self.notify_change()

    def zoom_fit(self):
        self.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        self.fit_scale = self.matrix().m11()
        if self.fit_scale > 1:
            self.fit_scale = 1
            self.zoom_full()
        else:
            self.next_fit = False
            self.notify_change()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed = True
        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        QGraphicsView.mouseMoveEvent(self, event)
        if self.mouse_pressed:
            self.notify_change()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed = False
        QGraphicsView.mouseReleaseEvent(self, event)

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            if self.next_fit:
                self.zoom_fit()
            else:
                self.zoom_full()
        QGraphicsView.mouseDoubleClickEvent(self, event)

    def wheelEvent(self, event):
        if event.delta() > 0:
            self.change_zoom(+1)
        else:
            self.change_zoom(-1)

    def resizeEvent(self, event):
        # FIXME: Se la finestra viene massimizzata, il valore di fit_scale non si aggiorna
        if self.matrix().m11() <= self.fit_scale:
            self.zoom_fit()
        else:
            self.notify_change()
        QGraphicsView.resizeEvent(self, event)

    def change_zoom(self, direction):
        level = math.log2(self.matrix().m11())
        if direction > 0:
            level += self.ZOOM_STEP
        else:
            level -= self.ZOOM_STEP
        scaling = 2**level
        if scaling < self.fit_scale:
            scaling = self.fit_scale
            self.next_fit = False
        elif scaling > 1:
            # scaling = 1
            if scaling > 4:
                scaling = 4
            self.next_fit = True
        self.set_scaling(scaling)
        self.notify_change()

    def set_scaling(self, scaling):
        matrix = QMatrix()
        matrix.scale(scaling, scaling)
        self.setMatrix(matrix)

    def change_view(self, _, new_scaling, new_horiz, new_vert):
        old_factor = self.matrix().m11()
        old_horiz = self.horizontalScrollBar().value()
        old_vert = self.verticalScrollBar().value()
        if new_scaling != old_factor or new_horiz != old_horiz or new_vert != old_vert:
            self.set_scaling(new_scaling)
            self.horizontalScrollBar().setValue(new_horiz)
            self.verticalScrollBar().setValue(new_vert)
            self.notify_change()

    def notify_change(self):
        scene_rect = self.get_rect()
        horiz_scroll = self.horizontalScrollBar().value()
        vert_scroll = self.verticalScrollBar().value()
        zoom_factor = self.matrix().m11()
        self.viewChanged.emit(scene_rect, zoom_factor, horiz_scroll,
                              vert_scroll)

    def get_rect(self):
        top_left = self.mapToScene(0, 0).toPoint()
        if top_left.x() < 0:
            top_left.setX(0)
        if top_left.y() < 0:
            top_left.setY(0)
        view_size = self.viewport().size()
        bottom_right = self.mapToScene(view_size.width(),
                                       view_size.height()).toPoint()
        image_size = self.sceneRect().toRect()
        if bottom_right.x() >= image_size.width():
            bottom_right.setX(image_size.width() - 1)
        if bottom_right.y() >= image_size.height():
            bottom_right.setY(image_size.height() - 1)
        return QRect(top_left, bottom_right)
Пример #11
0
    def show_camera(self):

        # ————————————————————原图, 显示在图1————————————————————
        # '''这是图1  label显示的代码'''
        # flag, self.image = self.cap.read()
        # show = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
        # showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0],
        # QtGui.QImage.Format_RGB888)  # QImage::QImage ( uchar * data, int width, int height, Format format )
        # self.ui.label_face.setPixmap(QtGui.QPixmap.fromImage(showImage))
        # self.ui.label_face.setScaledContents(True)
        '''这是图1  QGraphicsView显示的代码'''
        # get a frame  利用摄像头对象的read()函数读取视频的某帧
        flag, self.image = self.cap.read()
        # cv2.imshow('frame', self.image)
        show = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
        showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0],
                                 QtGui.QImage.Format_RGB888)
        # QImage::QImage ( uchar * data, int width, int height, Format format )
        scene1 = QGraphicsScene()  # 创建场景
        scene1.addPixmap(QtGui.QPixmap.fromImage(showImage))  # 给场景添加图元
        self.ui.label_face.setScene(
            scene1
        )  # 给视图窗口设置场景   # 在ui里label_face 以前是Label,后改成QGraphicsView,里面有Scene场景,可以自由缩放

        # ————————————————————灰度图, 显示在图2————————————————————
        '''这是图2  label显示的代码'''
        # gray_opencv = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        # gray_image = QtGui.QImage(gray_opencv.data, show.shape[1], show.shape[0], QtGui.QImage.Format_Grayscale8)
        # self.ui.label_gray.setPixmap(QtGui.QPixmap.fromImage(gray_image))
        # self.ui.label_gray.setScaledContents(True)
        '''这是QGraphicsView显示的代码'''
        gray_opencv = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        gray_image = QtGui.QImage(gray_opencv.data, show.shape[1],
                                  show.shape[0],
                                  QtGui.QImage.Format_Grayscale8)
        scene2 = QGraphicsScene()
        scene2.addPixmap(QtGui.QPixmap.fromImage(gray_image))
        self.ui.label_gray.setScene(scene2)

        # # ————————————————————二值化图,不显示————————————————————
        # bin_opencv = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        # # binary1 = cv2.adaptiveThreshold(bin_opencv, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)
        # # 局部阈值(备选二值化方案)
        # ret, binary2 = cv2.threshold(bin_opencv, 0, 255,
        #                              cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)    # 全局阈值(直方图单一峰,用triangle比较好)
        # binary20 = QtGui.QImage(binary2.data, bin_opencv.shape[1], bin_opencv.shape[0], QtGui.QImage.Format_Grayscale8)
        # # self.ui.label_gray.setPixmap(QtGui.QPixmap.fromImage(binary20))
        # # self.ui.label_gray.setScaledContents(True)

        # # ————————————————————用mask提取特定区域,显示在图3————————————————————
        # mask = np.zeros(show.shape[:2], np.uint8)   # 总报错??????    shape 有三个参数,高,宽,深(位),这里只需要获取前两位
        # mask[200:280, 280:360] = 255  # 获取mask,并赋予颜色
        # gray_mask = cv2.bitwise_and(binary2, binary2, mask=mask)
        # # 通过位运算(与运算)计算带有mask的灰度图片(特别注意:只有opencv输出的图才能用opencv格式的函数,要求是矩阵;、、而QImage格式的图,作为opencv函数的输入就报错了)
        #
        # # ————用HSV设置mask————
        # # RGB转换到HSV
        # hsv = cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV)
        # # 设定绿色的阈值。确定要追踪的颜色为绿色。
        # lower_blue = np.array([26, 50, 50])
        # upper_blue = np.array([99, 255, 255])
        # # 根据阈值构建掩模,构建黑白图
        # # hsv:原图
        # # lower_blue:图像中低于这个lower_blue的值,图像值变为0,即黑色
        # # upper_blue:图像中高于这个upper_blue的值,图像值变为0
        # # 而在lower_blue~upper_blue之间的值变成255,即白色。
        # maskHSV = cv2.inRange(hsv, lower_blue, upper_blue)
        # # 对原图像和掩模进行位运算
        # # 绿色覆盖白色区域,黑色不覆盖,实现了白色转化为要追踪的绿色,也就是追踪效果。
        # res = cv2.bitwise_and(self.image, self.image, mask=maskHSV)
        # cv2.imshow('绿色', res)
        #
        # '''这是图3的label显示的代码'''
        # # gray_opencv_mask = QtGui.QImage(gray_mask.data, gray_opencv.shape[1], gray_opencv.shape[0],
        # #                                 QtGui.QImage.Format_Grayscale8)
        # # self.ui.label_gray_2.setPixmap(QtGui.QPixmap.fromImage(gray_opencv_mask))
        # # self.ui.label_gray_2.setScaledContents(True)
        #
        # '''这是图3的QGraphicsView显示的代码'''
        # gray_opencv_mask = QtGui.QImage(gray_mask.data, gray_opencv.shape[1], gray_opencv.shape[0],
        #                                 QtGui.QImage.Format_Grayscale8)
        # scene3 = QGraphicsScene()
        # scene3.addPixmap(QtGui.QPixmap.fromImage(gray_opencv_mask))
        # self.ui.label_gray_2.setScene(scene3)
        #
        # # 取roi,后续操作只对roi内的进行
        # roi = binary2[200:280, 280:360]

        # # ————计算二值化图roi部分亮点数,作为亮度(用bincount)————
        # h, w = roi.shape[:2]
        # m = np.reshape(roi, [1, w*h]).flatten()    # 将图片转化成numpy一维数组
        # m255 = np.bincount(m)                      # 用 bincount()函数
        # print("m255_Len:", len(m255))

        # # ————计算图1的roi部分亮度————
        # # 调用函数 cacu_brightness
        # roi_brightness = show[200:280, 280:360]
        # imagePIL = Image.fromarray(cv2.cvtColor(roi_brightness, cv2.COLOR_BGR2RGB))    # OpenCV转换成PIL.Image格式
        # brightness = self.cacu_brightness(imagePIL)

        # # ————计算余辉时间————
        # # 从点击拍照时开始计时,如果小于设定的采集阈值下限,并且连续小于10次,则停止计时(这是开始运行起计算,实际从点击采图按钮开始计算,点击采图开始光照并计时,再减去打光时间)
        # if len(m255) == 1:
        #     time_end = time.time()
        #     time_count = time_end - time_start
        #     self.ui.label_time_2.setText(str('%.2f' % time_count))
        #     print("m[255]=1:", m255[0])
        #     self.timer_camera.stop()
        # else:
        #     # self.ui.label_time.setText(str(m255[255]))  # 输出按亮点数算出的亮度值
        #     self.ui.label_time.setText(str('%.2f' % brightness))  # 输出PIL算出的亮度值
        #     print("m[255]=256:", m255[0], m255[255], brightness)  # 输出值为0(黑)的点数,255(白)的点数
        #     while m255[255] < self.ui.spinBox_thre.value():
        #         time_end = time.time()
        #         time_count = time_end - time_start
        #         print('totally cost', '%.2f' % time_count)
        #         # QMessageBox.about(self.ui, '余辉时间为', '%.2f' % time_count, )  # '''{time_count}'''
        #         self.ui.label_time_2.setText(str('%.2f' % time_count))
        #         self.timer_camera.stop()
        #         break

        # ~~~~~~~~~显示图3,灰度roi~~~~~~~~~~
        mask = np.zeros(show.shape[:2],
                        np.uint8)  # shape 有三个参数,高,宽,深(位),这里只需要获取前两位
        mask[200:280, 280:360] = 255  # 获取mask,并赋予颜色
        gray_mask = cv2.bitwise_and(gray_opencv, gray_opencv,
                                    mask=mask)  # 按位与,提取mask位置,其他不显示
        gray_opencv_mask = QtGui.QImage(gray_mask.data, gray_opencv.shape[1],
                                        gray_opencv.shape[0],
                                        QtGui.QImage.Format_Grayscale8)
        scene3 = QGraphicsScene()
        scene3.addPixmap(QtGui.QPixmap.fromImage(gray_opencv_mask))
        self.ui.label_gray_2.setScene(scene3)

        # ~~~~~~~~~用5种方法分别计算roi亮度~~~~~~~~~~~
        roi_brightness = show[200:280, 280:360]
        imagePIL = Image.fromarray(
            cv2.cvtColor(roi_brightness,
                         cv2.COLOR_BGR2RGB))  # OpenCV转换成PIL.Image格式
        brightness1 = self.image_brightness1(imagePIL)
        brightness2 = self.image_brightness2(imagePIL)
        brightness3 = self.image_brightness3(imagePIL)
        brightness4 = self.image_brightness4(imagePIL)

        # ~~~~~~~~~计算余辉时间~~~~~~~~~~
        self.ui.label_time.setText(str('%.2f' % brightness1))  # 输出PIL算出的亮度值
        # print("brightness:", '%.2f' % brightness1, '%.2f' % brightness2, '%.2f' % brightness3, '%.2f' % brightness4)

        # while brightness1 < self.ui.spinBox_thre.value():
        #     brightnessCount += 1
        #     if brightnessCount > 10:
        #         time_end = time.time()
        #         time_count = time_end - time_start
        #         print('totally cost', '%.2f' % time_count)
        #         # QMessageBox.about(self.ui, '余辉时间为', '%.2f' % time_count, )  # '''{time_count}'''
        #         self.ui.label_time_2.setText(str('%.2f' % time_count))
        #         self.timer_camera.stop()
        #         print('brightnessCount:',  brightnessCount)
        #         break

        time_lightoff = time.time()
        time_gap = time_lightoff - self.time_start_compute

        if self.flag_plot:
            time_x = time.time()
            list_time_x = time_x - self.time_start_compute

            self.list_time.append(list_time_x)
            self.list_value.append(brightness1)

        if self.flag_compute and brightness1 < self.ui.spinBox_thre.value(
        ) and time_gap > 5:  #  一旦第一次小于阈值,计算时间的flag为false,就不再有新的time_end,计时就相当于停止了
            time_end = time.time()
            time_count = time_end - self.time_start_compute
            print('totally cost', '%.2f' % time_count)
            # QMessageBox.about(self.ui, '余辉时间为', '%.2f' % time_count, )  # '''{time_count}'''
            self.ui.label_time_2.setText(str('%.2f' % time_count))
            self.flag_compute = False

            self.plot(self.list_time, self.list_value)  # 绘图
            print(self.list_value)
            print(self.list_time)
            # self.saveData(self.list_value)  # 存excel文件
            self.text_Save(self.list_value)  # 存txt文件

            self.list_value.clear()  # 清空列表数据
            self.list_time.clear()
Пример #12
0
class Window(QMainWindow):
    """Class to create main widnow

    Creates main window for displaying frame read from a connected camera.
    The main window contains memu bar, tool bar, status bar, sliders and the
    boxes showing the camera's information. These widget are created and added to
    main window in the instance method of this class.

    """
    def __init__(
            self, device: int = 0, suffix: str = "png", camtype: str = "usb_cam",
            color: str = "RGB", dst: str = ".", param: str = "full",
            rule: str = "Sequential", parent=None):
        super(Window, self).__init__(parent)
        self.device = device
        self.camtype = camtype
        self.colorspace = color
        self.image_suffix = suffix
        self.video_codec = "AVC1"
        self.video_suffix = "avi"
        self.dst = Path(dst)
        self.parent_dir = Path(__file__).parent.resolve()

        self.filename_rule_lst = FileIO.file_save
        self.filename_rule = FileIO.file_save_lst[-1]

        self.is_display = True
        self.param_separate = False

        self.slot = Slot(self)

        cam = self.get_cam()
        self.camera = cam(self.device, self.colorspace, parent=self)
        self.support_params = self.camera.get_supported_params()
        self.current_params = self.camera.get_current_params(param)

        # List of camera properties with temporal initial values
        self.prop_table = [
            ["Fourcc", "aa"],
            ["Width", 640],
            ["Height", 480],
            ["FPS", 30.0],
            ["Bit depth", 8],
            ["File naming style", self.filename_rule]
        ]
        self.setup()
        self.set_timer()

    def get_cam(self) -> str:
        """Return camera object according to current OS.

        Detects what OS you are using, return camera objects  in order to function properly.

            - Linux: LinuxCamera
            - RaspberryPi OS: RaspiCamera
            - Windows: WindowsCamera

        Returns:
            Camera class
        """
        if self.camtype == "raspi":
            return RaspiCamera

        self.system = platform.system()
        if re.search("linux", self.system, re.IGNORECASE):
            return LinuxCamera
        elif re.search("windows", self.system, re.IGNORECASE):
            return WindowsCamera
        else:
            return "Unknown type"

    def setup(self):
        """Setup the main window for displaying frame and widget.

        Creates a QMainWindow object, then add menubar, toolbar, statusbar, widgets and layout
        into the window.
        """
        self.setFocusPolicy(Qt.ClickFocus)
        self.setContentsMargins(20, 0, 20, 0)
        self.information_window_setup()
        self.view_setup()
        self.layout_setup()
        self.image_setup()
        self.toolbar_setup()
        self.setWindowTitle("usbcamGUI")
        self.update_prop_table()
        self.adjust_windowsize()
        self.set_theme()

    def adjust_windowsize(self):
        """Adjusts the main window size
        """
        system = Utility.get_os()
        if system == "linux":
            w, h, _ = self.get_screensize()
            wscale = 0.5
            hscale = 0.7
            self.resize(wscale * w, hscale * h)
        else:
            self.resize(800, 600)

    def set_theme(self):
        """Set color theme of the main window.
        """
        self.style_theme = "light"
        self.style_theme_sheet = ":/{}.qss".format(self.style_theme)
        self.slot.switch_theme()
        self.set_font(self.camera.font_family, self.camera.font_size)

    def set_font(self, family: str = "Yu Gothic", size: int = 14):
        """Sets font-family and size of UI.

        Args:
            family (str, optional): Font-family. Defaults to "Yu Gothic".
            size (int, optional): Font-size. Defaults to 20.
        """
        self.setStyleSheet('font-family: "{}"; font-size: {}px;'.format(family, size))

    def set_timer(self):
        """Set QTimer

        Creates a QTimer object to update frame on view area. The interval is set to the inverse
        of camera FPS.
        """
        self.qtime_factor = 0.8
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer = QTimer()
        self.timer.setInterval(self.msec)
        self.timer.timeout.connect(self.next_frame)
        self.timer.start()

    def stop_timer(self):
        """Deactivate the Qtimer object.
        """
        self.timer.stop()

    def start_timer(self):
        """Activate the Qtimer object.
        """
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer.setInterval(self.msec)
        self.timer.start()

    def toolbar_setup(self):
        """Create toolbar
        """
        self.toolbar = QToolBar("test", self)
        self.addToolBar(self.toolbar)

        current_size = str(self.font().pointSize())
        lst = [str(i) for i in range(6, 14)]
        lst.extend([str(i) for i in range(14, 40, 2)])
        index = lst.index(current_size)

        self.fontsize_combo = QComboBox()
        self.fontsize_combo.addItems(lst)
        self.fontsize_combo.setCurrentIndex(index)
        self.fontsize_combo.currentTextChanged.connect(self.slot.set_fontsize)
        self.fontsize_label = QLabel("Font size")
        self.fontsize_label.setFrameShape(QFrame.Box)

        self.comb = QFontComboBox()

        self.toolbar.addWidget(self.save_button)
        self.toolbar.addWidget(self.stop_button)
        self.toolbar.addWidget(self.rec_button)
        self.toolbar.addWidget(self.close_button)
        self.toolbar.addWidget(self.theme_button)
        self.toolbar.addWidget(self.help_button)
        self.toolbar.addWidget(self.fontsize_label)
        self.toolbar.addWidget(self.fontsize_combo)
        self.toolbar.setStyleSheet(
            """
            QToolBar {spacing:5px;}
            """
            )

    def view_setup(self):
        """Set view area to diplay read frame in part of the main window
        """
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.view.setScene(self.scene)
        self.width = 640
        self.height = 480
        self.scene.setSceneRect(0, 0, self.width, self.height)
        self.view.setMouseTracking(True)
        self.view.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.view.setCacheMode(QGraphicsView.CacheBackground)
        self.view.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate)

    def layout_setup(self):
        """Set layout of objects on the window.
        """
        self.window = QWidget()
        self.setCentralWidget(self.window)
        #self.view.mouseMoveEvent = self.get_coordinates

        self.main_layout = QHBoxLayout()
        self.window.setLayout(self.main_layout)

        self.add_actions()
        self.add_menubar()
        self.add_statusbar()
        self.button_block = self.add_buttons()
        self.slider_group = self.add_params()
        self.prop_block = self.add_prop_window()
        self.create_mainlayout()

    def image_setup(self):
        """Creates a Qimage to assign frame, then initialize with an image which has zero in all pixels.
        """
        self.frame = np.zeros((640, 480, 3), dtype=np.uint8)
        #cinit = np.ctypeslib.as_ctypes(self.frame)
        #self.frame.buffer = sharedctypes.RawArray(cinit._type_, cinit)
        self.qimage = QImage(
            self.frame.data,
            640,
            480,
            640 * 3,
            QImage.Format_RGB888
            )
        self.pixmap = QPixmap.fromImage(self.qimage)

    def add_actions(self):
        """Add actions executed when press each item in the memu window.
        """
        self.save_act = self.create_action("&Save", self.save_frame, "Ctrl+s")
        self.stop_act = self.create_action("&Pause", self.stop_frame, "Ctrl+p", checkable=True)
        self.rec_act = self.create_action("&Record", self.record, "Ctrl+r", True)
        self.quit_act = self.create_action("&Quit", self.slot.quit, "Ctrl+q")

        self.theme_act = self.create_action("Switch &Theme", self.slot.switch_theme, "Ctrl+t")
        self.param_act = self.create_action("Choose parameter slider", self.slot.switch_paramlist, "Ctrl+g")
        self.show_paramlist_act = self.create_action("Parameters &List", self.slot.show_paramlist, "Ctrl+l")
        self.show_shortcut_act = self.create_action("&Keybord shortcut", self.slot.show_shortcut, "Ctrl+k")
        self.font_act = self.create_action("&Font", self.slot.set_font, "Ctrl+f")

        self.usage_act = self.create_action("&Usage", self.slot.usage, "Ctrl+h")
        self.about_act = self.create_action("&About", self.slot.about, "Ctrl+a")

    def create_action(self, text: str, slot: Callable, key: str = None, checkable: bool = False,
        check_defalut: bool = False) -> QAction:
        """Create a QAction object.

        Args:
            text (str): Text shown on menu.
            slot (Callable): A method called when click the menu.
            key (str, optional): Shortcut key. Defaults to None.
            checkable (bool, optional): Add a checkbox into the menu. Defaults to False.
            check_defalut (bool, optional): Check default status. Defaults to False.

        Returns:
            QAction: PySide2 QAction
        """
        act = QAction(text)
        act.setShortcut(key)
        if checkable:
            act.setCheckable(True)
            act.setChecked(check_defalut)
            act.toggled.connect(slot)
        else:
            act.triggered.connect(slot)

        return act

    def add_menubar(self):
        """Create menu bar, then add to the main window.
        """
        self.menubar = QMenuBar()
        self.setMenuBar(self.menubar)

        self.file_tab = QMenu("&File")
        self.file_tab.addAction(self.save_act)
        self.file_tab.addAction(self.stop_act)
        self.file_tab.addAction(self.rec_act)
        self.file_tab.addSeparator()
        self.file_tab.addAction(self.quit_act)
        #self.file_tab.setSizePolicy(policy)

        self.view_tab = QMenu("&View")
        self.view_tab.addAction(self.theme_act)
        self.view_tab.addAction(self.font_act)
        self.view_tab.addAction(self.param_act)
        self.view_tab.addAction(self.show_shortcut_act)
        self.view_tab.addAction(self.show_paramlist_act)

        self.help_tab = QMenu("&Help")
        self.help_tab.addAction(self.usage_act)
        self.help_tab.addAction(self.about_act)

        self.menubar.addMenu(self.file_tab)
        self.menubar.addMenu(self.view_tab)
        self.menubar.addMenu(self.help_tab)
        self.menubar.setStyleSheet(
            """
            QMenuBar {
                    font-size: 16px;
                    spacing:10px;
                    padding-top: 5px;
                    padding-bottom: 10px;
                }
            """
            )

    def add_statusbar(self):
        """Create status bar, then add to the main window.

        The status bar shows the coordinates on the frame where the cursor is located and
        its pixel value. The pixel value has RGB if the format of is color (RGB), does grayscale
        value if grayscale.
        """
        self.statbar_list = []
        if self.colorspace == "rgb":
            self.stat_css = {
                "postion": "color: white",
                "R": "color: white;",
                "G": "color: white;",
                "B": "color: white;",
                "alpha": "color: white;",
            }
        else:
            self.stat_css = {
                "postion": "color: black;",
                "gray": "color: black"
            }

        for s in self.stat_css.values():
            stat = QStatusBar(self)
            stat.setStyleSheet(s)
            self.statbar_list.append(stat)

        first = True
        for stat in self.statbar_list:
            if first:
                self.setStatusBar(stat)
                self.statbar_list[0].reformat()
                first = False
            else:
                self.statbar_list[0].addPermanentWidget(stat)

    def add_buttons(self):
        """Add push buttons on the window.

        Add quit, save stop and usage buttons on the windows. When press each button, the set
        method (called "slot" in Qt framework) are execeuted.
        """
        self.save_button = self.create_button("&Save", self.save_frame, None, None, "Save the frame")
        self.stop_button = self.create_button("&Pause", self.stop_frame, None, None, "Stop reading frame", True)
        self.rec_button = self.create_button("&Rec", self.record, None, None, "Start recording", True)
        self.close_button = self.create_button("&Quit", self.slot.quit, None, None, "Quit the program")
        self.theme_button = self.create_button("Light", self.slot.switch_theme, None, None, "Switche color theme")
        self.help_button = self.create_button("&Usage", self.slot.usage, None, None, "Show usage")

        self.frame_button = self.create_button(
            "Properties",
            self.slot.change_frame_prop,
            None,
            tip="Change properties",
            minsize=(150, 30)
            )
        self.default_button = self.create_button(
            "&Default params",
            self.set_param_default,
            "Ctrl+d",
            tip="Set default parameters",
            minsize=(150, 30)
            )
        self.filerule_button = self.create_button(
            "&Naming style",
            self.slot.set_file_rule,
            "Ctrl+n",
            tip="Change naming style",
            minsize=(150, 30)
            )

        hbox = QHBoxLayout()
        hbox.addWidget(self.save_button)
        hbox.addWidget(self.stop_button)
        hbox.addWidget(self.rec_button)
        hbox.addWidget(self.close_button)
        hbox.addWidget(self.theme_button)
        hbox.addWidget(self.help_button)
        return hbox

    def create_button(self, text: str, slot: Callable, key: str = None, icon: Icon = None,
        tip: str = None, checkable: bool = False, minsize: tuple = None) -> QPushButton:
        """Create a QPushButton object.

        Args:
            text (str): Text shown on the button.
            slot (Callable): A method called when click the button.
            key (str, optional): Shortcut key. Defaults to None.
            icon (Icon, optional): An icon shown on the button. Defaults to None.
            tip (str, optional): A tips shown when position the pointer on the button. Defaults to None.
            checkable (bool, optional): Add button to checkbox. Defaults to False.
            msize (tuple, optional): Minimum size of the button box, (width, height).

        Returns:
            QPushButton: PySide2 QPushButton
        """
        button = QPushButton(text)
        if checkable:
            button.setCheckable(True)
            button.toggled.connect(slot)
        else:
            button.clicked.connect(slot)

        if key:
            button.setShortcut(key)
        if icon:
            button.setIcon(QIcon(icon))
        if tip:
            button.setToolTip(tip)
        if minsize:
            button.setMinimumSize(minsize[0], minsize[1])
        else:
            button.setMinimumSize(80, 30)
        return button

    def add_params(self) -> QGridLayout:
        """Set the properties of camera parameter.

        Set the properties of camera parameter, then add sliders to change each parameter.
        When change value on the slider, the value of paramter also changes by the caller
        function.

        """
        lst = self.current_params
        for key, value in lst.items():
            self.add_slider(key)

        # add sliders
        self.slider_table = QGridLayout()
        self.slider_table.setSpacing(15)
        self.slider_table.setContentsMargins(20, 20, 20, 20)
        for row, param in enumerate(self.current_params):
            self.slider_table.addWidget(self.current_params[param]["slider_label"], row, 0)
            self.slider_table.addWidget(self.current_params[param]["slider"], row, 1)
            self.slider_table.addWidget(self.current_params[param]["slider_value"], row, 2)
        if len(self.current_params) > 15:
            self.param_separate = True
        else:
            self.param_separate = False
        return self.slider_table

    def update_params(self, plist: list) -> QGridLayout:
        """Update camera's paramters and sliders shown on the windows.
        """
        #self.current_params.clear()
        self.current_params = self.camera.get_current_params("selected", plist)
        for key, value in self.current_params.items():
            self.add_slider(key)

        # add sliders
        grid = QGridLayout()
        grid.setSpacing(15)
        grid.setContentsMargins(20, 20, 20, 20)
        for row, param in enumerate(self.current_params):
            grid.addWidget(self.current_params[param]["slider_label"], row, 0)
            grid.addWidget(self.current_params[param]["slider"], row, 1)
            grid.addWidget(self.current_params[param]["slider_value"], row, 2)
        if len(self.current_params) > 15:
            self.param_separate = True
        else:
            self.param_separate = False
        self.slider_group = grid
        self.update_mainlayout()
        self.update_prop_table()
        self.write_text("update sliders")
        return grid

    def add_slider(self, param: str):
        """Creates slider, labels to show pamarater's name and its value.

        Args:
            param (str): A parameter to create slider.
        """
        min_ = self.current_params[param]["min"]
        max_ = self.current_params[param]["max"]
        step = self.current_params[param]["step"]
        value = self.current_params[param]["value"]

        slider = QSlider(Qt.Horizontal)
        if max_:
            slider.setRange(min_, max_)
        else:
            slider.setRange(0, 1)
        slider.setValue(int(value))
        slider.setTickPosition(QSlider.TicksBelow)
        slider.valueChanged.connect(lambda val, p=param: self.set_sliderval(p, val))

        if step:
            if max_ < 5:
                slider.setTickInterval(step)
            else:
                slider.setTickInterval(10)

        slider_label = QLabel(param)
        slider_value = QLabel(str(value))

        slider_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        slider_value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        self.current_params[param]["slider"] = slider
        self.current_params[param]["slider_label"] = slider_label
        self.current_params[param]["slider_value"] = slider_value

    def add_prop_window(self) -> QGridLayout:
        """Create a table to show the current properties of camera.

        Returns:
            QGridLayout: PySide2 QGridLayout
        """
        header = ["property", "value"]
        self.prop_table_widget = QTableWidget(self)
        self.prop_table_widget.setColumnCount(len(header))
        self.prop_table_widget.setRowCount(len(self.prop_table))

        self.prop_table_widget.setHorizontalHeaderLabels(header)
        self.prop_table_widget.verticalHeader().setVisible(False)
        self.prop_table_widget.setAlternatingRowColors(True)
        self.prop_table_widget.horizontalHeader().setStretchLastSection(True)
        self.prop_table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.prop_table_widget.setFocusPolicy(Qt.NoFocus)

        for row, content in enumerate(self.prop_table):
            for col, elem in enumerate(content):
                self.item = QTableWidgetItem(elem)

                self.prop_table_widget.setItem(row, col, self.item)
        self.prop_table_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        #self.prop_table_widget.resizeColumnsToContents()
        #self.prop_table_widget.resizeRowsToContents()
        self.prop_table_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.prop_table_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.prop_table_widget.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.prop_table_widget.setColumnWidth(0, 150)
        self.prop_table_widget.setColumnWidth(1, 150)

        vbox = QVBoxLayout()
        vbox.addWidget(self.prop_table_widget)
        vbox.setContentsMargins(20, 20, 20, 20)
        self.prop_group = QGroupBox("Frame Properties")
        self.prop_group.setLayout(vbox)
        return self.prop_group

    def information_window_setup(self):
        """Creates information window.

        Creates the information window where the event related to camera or window.
        """
        self.text_edit = QTextEdit()
        self.text_edit.setReadOnly(True)
        self.text_edit.show()
        vbox = QVBoxLayout()
        vbox.addWidget(self.text_edit)
        self.text_edit_box = QGroupBox("Information", self)
        self.text_edit_box.setLayout(vbox)
        self.text_edit_box.setAlignment(Qt.AlignLeft)

    def create_mainlayout(self):
        """Create the main layout which consists of view area and information window.
        """
        self.main_layout.addLayout(self.create_view_area_layout())
        self.main_layout.addLayout(self.create_information_layout())

    def update_mainlayout(self):
        """Recreate the main layout.
        """
        self.delete_layout(self.information_layout)
        self.delete_layout(self.upper_right)
        self.add_prop_window()
        self.main_layout.addLayout(self.create_information_layout())

    def delete_layout(self, layout):
        """Delete layout

        Args:
            layout (QBoxLayout): QBoxLayout class object to delete
        """
        while layout.count():
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()
            try:
                child.spacerIitem().deleteLater()
            except:
                pass

    def create_view_area_layout(self) -> QVBoxLayout:
        """Creates view area layout
        """
        self.view_area_layout = QVBoxLayout()
        self.view_area_layout.addWidget(self.view, 2)
        self.view_area_layout.addWidget(self.text_edit_box)
        return self.view_area_layout

    def create_information_layout(self):
        """Creates information part layout

        upper-left: current properties
        upper-right: buttons
        lower: sliders
        """
        if self.param_separate:
            self.entry_box = QVBoxLayout()
            self.entry_box.addWidget(self.frame_button)
            self.entry_box.addWidget(self.filerule_button)
            self.entry_box.addWidget(self.default_button)
            self.entry_box.addStretch(1)
            self.entry_box.setSpacing(20)
            self.entry_box.setContentsMargins(20, 20, 20, 20)

            self.button_group_box = QGroupBox("Buttons", self)
            self.button_group_box.setLayout(self.entry_box)
            self.button_group_box.setAlignment(Qt.AlignLeft)

            self.upper_right = QVBoxLayout()
            self.upper_right.addWidget(self.prop_group, 1)
            self.upper_right.addWidget(self.button_group_box, 1)

            self.slider_group_box = QGroupBox("Parameters")
            self.slider_group_box.setLayout(self.slider_group)
            self.slider_group_box.setContentsMargins(20, 20, 20, 20)

            self.information_layout = QHBoxLayout()
            self.information_layout.addLayout(self.upper_right, 1)
            self.information_layout.addWidget(self.slider_group_box, 2)
            #self.information_layout.addStretch(1)
            return self.information_layout
        else:
            self.entry_box = QVBoxLayout()
            self.entry_box.addWidget(self.frame_button)
            self.entry_box.addWidget(self.filerule_button)
            self.entry_box.addWidget(self.default_button)
            self.entry_box.addStretch(1)
            self.entry_box.setSpacing(20)
            self.entry_box.setContentsMargins(20, 20, 20, 20)

            self.button_group_box = QGroupBox("Buttons", self)
            self.button_group_box.setLayout(self.entry_box)
            self.button_group_box.setAlignment(Qt.AlignLeft)

            self.upper_right = QHBoxLayout()
            self.upper_right.addWidget(self.prop_group)
            self.upper_right.addWidget(self.button_group_box)

            self.slider_group_box = QGroupBox("Parameters")
            self.slider_group_box.setLayout(self.slider_group)
            self.slider_group_box.setContentsMargins(20, 20, 20, 20)

            self.information_layout = QVBoxLayout()
            self.information_layout.addLayout(self.upper_right)
            self.information_layout.addWidget(self.slider_group_box)
            self.information_layout.setSpacing(30)
            return self.information_layout

    # decorator
    def display(func):
        def wrapper(self, *args, **kwargs):
            try:
                self.is_display = False
                self.stop_timer()
                func(self, *args, **kwargs)
            finally:
                self.is_display = True
                self.start_timer()
        return wrapper

    def stop_frame(self, checked: bool):
        """Stop reading next frame.

        Args:
            checked (bool): True when presse the Stop button (toggle on). False when press
                again (toggel off).
        """
        if checked:
            self.write_text("Stop !!")
            self.is_display = False
            self.stop_button.setText('Start')
            self.stop_button.setChecked(True)
            self.stop_act.setText('Start')
            self.stop_act.setChecked(True)
        else:
            self.write_text("Start !!")
            self.is_display = True
            self.stop_button.setText('&Pause')
            self.stop_button.setChecked(False)
            self.stop_act.setText('&Pause')
            self.stop_act.setChecked(False)

    def keyPressEvent(self, event):
        """Exit the program

        This method will be called when press the Escape key on the window.
        """
        if event.key() == Qt.Key_Escape:
            QApplication.quit()

    def get_coordinates(self, event):
        """Show the current coordinates and value in the pixel where the cursor is located.

        The status bar is updates by the obtained values.
        """
        if self.item is self.view.itemAt(event.pos()):
            sp = self.view.mapToScene(event.pos())
            lp = self.item.mapFromScene(sp).toPoint()
            (x, y) = lp.x(), lp.y()
            #color = self.frame.image.pixel(x, y)
            color = self.qimage.pixelColor(x, y)
            if self.colorspace == "rgb":
                value = color.getRgb()
            elif self.colorspace == "gray":
                value = color.value()

            # Return none if the coordinates are out of range
            if x < 0 and self.frame.width < x:
                return
            elif y < 0 and self.frame.height < y:
                return

            if self.frame.img_is_rgb:
                status_list = [
                    "( x : {}, y :{} )".format(x, y),
                    "R : {}".format(value[0]),
                    "G : {}".format(value[1]),
                    "B : {}".format(value[2]),
                    "alpha : {}".format(value[3])
                ]
            else:
                status_list = [
                    "( x : {}, y :{} )".format(x, y),
                    "gray value : {}".format(value),
                ]

            for statbar, stat in zip(self.statbar_list, status_list):
                statbar.showMessage(stat)

    def next_frame(self):
        """Get next frame from the connected camera.

        Get next frame, set it to the view area and update.
        """
        #print("display :", self.is_display)
        if self.is_display:
            self.camera.read_frame()
            self.convert_frame()
            self.scene.clear()
            self.scene.addPixmap(self.pixmap)
            self.update()
            #print("update")

    def convert_frame(self):
        """Convert the class of frame

        Create qimage, qpixmap objects from ndarray frame for displaying on the window.

        """
        if self.colorspace == "rgb":
            self.qimage = QImage(
                self.camera.frame.data,
                self.camera.frame.shape[1],
                self.camera.frame.shape[0],
                self.camera.frame.shape[1] * 3,
                QImage.Format_RGB888
                )
        elif self.colorspace == "gray":
            self.qimage = QImage(
                self.camera.frame.data,
                self.camera.frame.shape[1],
                self.camera.frame.shape[0],
                self.camera.frame.shape[1] * 1,
                QImage.Format_Grayscale8)

        self.pixmap.convertFromImage(self.qimage)

    def save_frame(self):
        """Save the frame on the window as an image.
        """
        if self.filename_rule == "Manual":
            self.save_frame_manual()
            if not self.filename:
                return None
            prm = re.sub(r"\.(.*)", ".csv", str(self.filename))
        else:
            self.filename = FileIO.get_filename(self.filename_rule, self.image_suffix, self.parent_dir)
            prm = str(self.filename).replace(self.image_suffix, "csv")

        if not self.dst.exists():
            self.dst.mkdir(parents=True)
        im = Image.fromarray(self.camera.frame)
        im.save(self.filename)

        # make a parameter file
        with open(prm, "w") as f:
            for name, key in self.current_params.items():
                f.write("{},{}\n".format(name, self.current_params[name]["value"]))

        self.write_text("{:<10}: {}".format("save image", self.filename))
        self.write_text("{:<10}: {}".format("save param", prm))

    def update_prop_table(self):
        """Updates the table that shows the camera properties.
        """
        w, h, cc, f = self.camera.get_properties()
        self.prop_table = [
            ["Fourcc", cc],
            ["Width", int(w)],
            ["Height", int(h)],
            ["FPS", "{:.1f}".format(f)],
            ["Bit depth", 8],
            ["Naming Style", self.filename_rule]
        ]
        col = 1
        for row in range(len(self.prop_table)):
            text = str(self.prop_table[row][col])
            self.prop_table_widget.item(row, col).setText(text)

    def record(self):
        """Start or end recording
        """
        if self.camera.is_recording:
            self.camera.stop_recording()
            self.rec_button.setText('&Rec')
            self.rec_act.setText('&Record')
            self.write_text("save : {}".format(self.video_filename))
        else:
            self.video_filename = FileIO.get_filename(self.filename_rule, self.video_suffix, self.parent_dir)
            self.camera.start_recording(self.video_filename, self.video_codec)
            self.rec_button.setText('Stop rec')
            self.rec_act.setText('Stop record')

    @display
    def save_frame_manual(self) -> bool:
        """Determine file name of image to save with QFileDialog
        """
        self.dialog = QFileDialog()
        self.dialog.setWindowTitle("Save File")
        self.dialog.setNameFilters([
            "image (*.jpg *.png *.tiff *.pgm)",
            "All Files (*)"
            ])
        self.dialog.setAcceptMode(QFileDialog.AcceptSave)
        self.dialog.setOption(QFileDialog.DontUseNativeDialog)

        if self.dialog.exec_():
            r = self.dialog.selectedFiles()

            # If the file name doesn't include supproted suffixes, add to the end.
            if re.search(".pgm$|.png$|.jpg$|.tiff$", r[0]):
                self.filename = r[0]
            else:
                self.filename = "{}.{}".format(r[0], self.image_suffix)
            return True
        else:
            return False

    def get_screensize(self):
        """Get current screen size from the output of linux cmd `xrandr`.
        """
        cmd = ["xrandr"]
        ret = subprocess.check_output(cmd)
        output = ret.decode()
        pattern = r"current(\s+\d+\s+x\s+\d+)"

        m = re.search(pattern, output)
        if m:
            size = re.sub(" ", "", m.group(1))
            w, h = map(int, size.split("x"))
            return w, h, size
        else:
            return None

    def set_sliderval(self, param: str, value: int):
        """Changes a camera parameter.

        Updates the label on the right of the slider if input value is valid.

        Args:
            param (str): A camera parameter
            value (int): its value
        """
        val = self.camera.set_parameter(param, value)
        self.current_params[param]["value"] = str(val)
        self.current_params[param]["slider_value"].setText(str(value))

    def set_param_default(self):
        """Sets all paramters to default.
        """
        for param, values in self.current_params.items():
            default = values["default"]
            self.camera.set_parameter(param, default)
            self.current_params[param]["slider"].setValue(int(default))
            self.current_params[param]["slider_value"].setText(str(default))

    def get_properties(self) -> list:
        """Get the current camera properties.

        Returns:
            list: parameters. fourcc, width, height, fps.
        """
        tmp = []
        for row in range(4):
            tmp.append(self.prop_table[row][1])
        return tmp

    def write_text(self, text: str, level: str = "info", color: str = None):
        """Writes the message into information window.

        Args:
            text (str): A text to write.
            level (str, optional): Log lebel of the message. Defaults to "info".
            color (str, optional): Font color. Defaults to None.
        """
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
        now = now[:-3]
        if color == "red":
            form = f"<font color='red'>[{level.upper():<4} {now}] {text}</font>"
        elif color == "yellow":
            form = f"<font color='yellow'>[{level.upper():<4} {now}] {text}</font>"
        else:
            form = f"[{level.upper():<4} {now}] {text}"
        self.text_edit.append(form)
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.index_districts = index_districts

        self.x1 = ""
        self.x3 = ""
        self.y1 = ""
        self.y3 = ""

        self.scene = QGraphicsScene()
        self.image = QGraphicsView(self.scene)
        self.image.show()
        self.submitButton = QPushButton("Submit")
        self.undoButton = QPushButton("Undo")
        self.nextReport = QPushButton("Next Report")
        self.badButton = QPushButton("BAD")
        self.goodButton = QPushButton("Good")
        self.noDataButton = QPushButton("No Data")
        self.districtText = QLineEdit("")
        self.cattleLabel = QLineEdit("Cattle:")
        self.top = QHBoxLayout()
        self.top.addWidget(self.cattleLabel)
        self.prevPageButton = QPushButton("Previous Page")
        self.nextPageButton = QPushButton("Next Page")
        self.middle = QVBoxLayout()
        self.left = QHBoxLayout()
        self.middle.setMargin(10)
        self.middle.addWidget(self.image)
        self.middle.addLayout(self.top)
        self.middle.addLayout(self.left)
        self.bottom = QHBoxLayout()
        self.left.addWidget(self.prevPageButton)
        self.left.addWidget(self.nextPageButton)
        self.middle.addWidget(self.districtText)
        self.bottom.addWidget(self.badButton)
        self.bottom.addWidget(self.noDataButton)
        self.bottom.addWidget(self.goodButton)
        self.bottom.addWidget(self.nextReport)
        self.bottom.addWidget(self.undoButton)
        self.bottom.addWidget(self.submitButton)
        self.middle.addLayout(self.bottom)

        # QWidget Layout

        self.layout = QHBoxLayout()
        self.layout.addLayout(self.middle)

        # Set the layout to the QWidget
        self.setLayout(self.layout)

        # second
        # self.data_path = "../Crop_Reports/Manual Check Crop Reports/crop_reports_verified.csv"
        # self.data = pd.read_csv(self.data_path)
        self.dir_path = "../Crop_Reports/Bengal Crop Reports PNG/"
        # connect functions
        self.nextReport.clicked.connect(self.ignore)
        self.submitButton.clicked.connect(self.submit)
        self.undoButton.clicked.connect(self.undo)
        self.nextPageButton.clicked.connect(self.nextImage)
        self.prevPageButton.clicked.connect(self.prevImage)

        self.crop_index = 0
        self.page_index = 0
        self.zoom = .2

        self.out_folder = "../Crop_Reports/Bengal Famine Data/"
        self.finished = os.listdir(self.out_folder)
        self.data = pd.read_csv("../Crop_Reports/Manual Check Crop Reports/crop_reports_verified_cleaned_is_good.csv")
        self.data.Date = pd.to_datetime(self.data.Date)
        self.data = self.data[(self.data.Date > start_date) & (self.data.Date < end_date)]

        self.columns = ["District","Date","famine_code"]
        self.bound_data = pd.DataFrame(columns = self.columns)
        self.bound_data_text = ""

        self.ocr_data_list = list()

        data = self.data
        for string in self.finished:
            string = string.split(".")[0]
            data = data[data.Path != string]



        self.reports = list(data.Path)
        self.dates = list(data.Date)
        print(u"Data index:",data.index)


        self.remain_string = "remaining folders " + str(len(self.reports))
        self.remainingLabel = QLabel(self.remain_string)
        self.left.addWidget(self.remainingLabel)

        temp_path = os.path.join(self.dir_path, self.reports[self.crop_index])
        self.report = os.listdir(temp_path)
        #self.forceLastImage()
        self.postImage()



        # Sets up drawing capabilities:
        self.image.setMouseTracking(True)
        self.image.viewport().installEventFilter(self)
        self.start = None
        self.end = None

        #something
        #self.draw_boxes()

    # error here, disregarded bc why not? :)
    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseButtonRelease and source is self.image.viewport():
            if event.button() == Qt.RightButton:
                self.nextImage()

            if event.button() == Qt.MidButton:
                self.ignore()

            if event.button() == Qt.LeftButton:
                self.draw_bounding_box()

            #print(event.pos())
            #print(self.image.mapToScene(event.pos()))






    @Slot()
    def submit(self, famine_code):
        self.postImage()


        ["District", "x1", "y1", "x3", "y3", "Date", "Raw_Text"]
        row = {'District':self.districtText.text(),'Date':self.date,'famine_code': famine_code}
        self.bound_data = self.bound_data.append(row, ignore_index= True)
        print(self.bound_data)

        self.districtText.setText("")
        cattle_label_text = "Length: " + str(len(self.bound_data.famine_code)) + ". " + str(list(self.bound_data.famine_code))
        self.cattleLabel.setText(cattle_label_text)

    @Slot()
    def undo(self):
        print(self.bound_data)
        self.bound_data.drop(self.bound_data.tail(1).index, inplace=True)

        cattle_label_text = "Length: " + str(len(self.bound_data.famine_code)) + ". " + str(list(self.bound_data.famine_code))
        self.cattleLabel.setText(cattle_label_text)

        print(self.bound_data)

    @Slot()
    def ignore(self):
        self.remain_string = "remaining folders " + str(len(self.reports)-self.crop_index-1)
        self.remainingLabel.setText(self.remain_string)

        path = self.out_folder + self.reports[self.crop_index] + ".csv"
        print(u"out path:",path)

        self.bound_data.District = self.index_districts
        self.bound_data.to_csv(path, index= False)
        self.bound_data = pd.DataFrame(columns = self.columns)


        self.crop_index = self.crop_index + 1
        self.page_index = 0
        self.postImage()
        #self.forceLastImage()
        self.postImage()






    @Slot()
    def nextImage(self):
        if ((len(self.report) - 1) > self.page_index):
            self.page_index = self.page_index + 1
        else:
            self.page_index = 0

        self.postImage()

    @Slot()
    def forceLastImage(self):
        self.page_index = (len(self.report) - 1)

    @Slot()
    def prevImage(self):
        if (1 > self.page_index):
            self.page_index = len(self.report) - 1
        else:
            self.page_index = self.page_index - 1

        self.postImage()

    def postImage(self):
        self.date = self.dates[self.crop_index]
        print(u"Date:",self.date)
        print(self.dates)
        temp_path = os.path.join(self.dir_path, self.reports[self.crop_index])
        report = os.listdir(temp_path)
        dt.sort_nicely(report)
        self.report = report
        self.ocr_data_list = dt.report_to_data(self.reports[self.crop_index])

        if (len(self.report) > 0):
            self.page = self.report[self.page_index]
            self.page_df = self.ocr_data_list[self.page_index]
            temp_path = os.path.join(self.dir_path, self.reports[self.crop_index], self.page)
            self.scene.clear()
            self.pixmap = QPixmap(temp_path)
            # adjusts zoom
            self.pixmap = self.pixmap.scaled(self.pixmap.size().width() * self.zoom,
                                             self.pixmap.size().height() * self.zoom,
                                             Qt.KeepAspectRatio)
            self.scene.addPixmap(self.pixmap)
            self.draw_bounding_box()



    # def draw_bounding_box(self, x1, y1, x3, y3):
    #
    #     start = self.image.mapToScene(x1,y1)
    #     end = self.image.mapToScene(x3,y3)
    #     len_x = end.x()-start.x()
    #     len_y = end.y()-start.y()
    #     rectItem = QGraphicsRectItem(start.x(), start.y(), len_x, len_y)
    #     self.scene.addItem(rectItem)



    def draw_bounding_box(self):
        df = self.page_df

        scale = self.zoom
        no_df = df[df.word=="redroverr2"]
        tle_df = df[df.word.str.contains("suf", na = False)]
        catt_df = df[df.word.str.contains("insuf", na=False)]
        rinder_df = df[df.word.str.contains("ind1111er", na=False)]

        for index, row in no_df.iterrows():
            print(row)
            x1 = row.x1*scale
            y1 = row.y1*scale
            x3= row.x3*scale
            y3 = row.y3*scale
            diff_x = x3-x1
            diff_y = y3-y1
            rectItem = QGraphicsRectItem(x1,y1,diff_x,diff_y)
            rectItem.setBrush(QBrush(Qt.green))
            #rectItem = QGraphicsRectItem(0, 0, 100, 100)
            self.scene.addItem(rectItem)

        for index, row in tle_df.iterrows():
            print(row)
            x1 = row.x1 * scale
            y1 = row.y1 * scale
            x3 = row.x3 * scale
            y3 = row.y3 * scale
            diff_x = x3 - x1
            diff_y = y3 - y1
            rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
            rectItem.setBrush(QBrush(Qt.green))
            # rectItem = QGraphicsRectItem(0, 0, 100, 100)
            self.scene.addItem(rectItem)

        for index, row in rinder_df.iterrows():
            print(row)
            x1 = row.x1 * scale
            y1 = row.y1 * scale
            x3 = row.x3 * scale
            y3 = row.y3 * scale
            diff_x = x3 - x1
            diff_y = y3 - y1
            rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
            rectItem.setBrush(QBrush(Qt.red))
            # rectItem = QGraphicsRectItem(0, 0, 100, 100)
            self.scene.addItem(rectItem)

        for index, row in catt_df.iterrows():
            print(row)
            x1 = row.x1 * scale
            y1 = row.y1 * scale
            x3 = row.x3 * scale
            y3 = row.y3 * scale
            diff_x = x3 - x1
            diff_y = y3 - y1
            rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
            rectItem.setBrush(QBrush(Qt.red))
            # rectItem = QGraphicsRectItem(0, 0, 100, 100)
            self.scene.addItem(rectItem)

        # divider_x = (max(df.x3)-min(df.x1))/2
        # week_df = df[df.word.str.contains("icient", na=False)]
        # for index, row in week_df.iterrows():
        #     week_anchor = row
        #
        #     x1 = week_anchor.x1 * scale
        #     y1 = week_anchor.y1 * scale
        #     x3 = week_anchor.x3 * scale
        #     y3 = week_anchor.y3 * scale
        #     diff_x = x3 - x1
        #     diff_y = y3 - y1
        #     rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
        #     rectItem.setBrush(QBrush(Qt.blue))
        #     self.scene.addItem(rectItem)

        # right_df = df[df.x1 > divider_x]
        # right_df = right_df[right_df.y1 > week_anchor.y3]
        # for index, row in right_df.iterrows():
        #     x1 = row.x1 * scale
        #     y1 = row.y1 * scale
        #     x3 = row.x3 * scale
        #     y3 = row.y3 * scale
        #     diff_x = x3 - x1
        #     diff_y = y3 - y1
        #
        #     rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
        #     rectItem.setBrush(QBrush(Qt.red))
        #
        #     self.scene.addItem(rectItem)

        # for district in self.index_districts:
        #     print(district)
        #     row = df[df.word.str.contains(district, na=False)]
        #
        #     if (len(row.word) != 0):
        #         x1 = row.x1 * scale
        #         y1 = row.y1 * scale
        #         x3 = row.x3 * scale
        #         y3 = row.y3 * scale
        #         diff_x = x3 - x1
        #         diff_y = y3 - y1
        #
        #         rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
        #         rectItem.setBrush(QBrush(Qt.red))
        #
        #         self.scene.addItem(rectItem)









    # def write_to_csv(self):
    #     new_row = {'ocr_report_path': self.reports[self.crop_index], 'date': self.districtText.text()}
    #     self.data = self.data.append(new_row, ignore_index=True)
    #     self.data.to_csv(self.data_path, index=False)

    # reformat first half of year 1910 before 10/6
    def keyPressEvent(self, event):

        if event.key() == Qt.Key_A:
            #disease
            self.submit("bad")

        if event.key() == Qt.Key_W:
            # no mention
            self.submit("NR")

        if event.key() == Qt.Key_D:
            ##not bad
            self.submit("not_bad")
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.scene = QGraphicsScene()
        self.image = QGraphicsView(self.scene)
        self.image.show()
        self.submitButton = QPushButton("Submit")
        self.dateText = QLineEdit("")
        self.prevPageButton = QPushButton("Previous Page")
        self.nextPageButton = QPushButton("Next Page")
        self.middle = QVBoxLayout()
        self.left = QHBoxLayout()
        self.middle.setMargin(10)
        self.middle.addWidget(self.image)
        self.middle.addLayout(self.left)
        self.left.addWidget(self.prevPageButton)
        self.left.addWidget(self.nextPageButton)
        self.middle.addWidget(self.dateText)
        self.middle.addWidget(self.submitButton)

        # QWidget Layout

        self.layout = QHBoxLayout()
        self.layout.addLayout(self.middle)

        # Set the layout to the QWidget
        self.setLayout(self.layout)

        #second
        self.data_path = "../Crop_Reports/Manual Check Crop Reports/crop_reports_verified.csv"
        self.data = pd.read_csv(self.data_path)
        self.dir_path = "../Crop_Reports/Bengal Crop Reports PNG/"
        #connect functions
        self.submitButton.clicked.connect(self.submit)
        self.nextPageButton.clicked.connect(self.nextImage)
        self.prevPageButton.clicked.connect(self.prevImage)

        self.crop_index = 0
        self.page_index = 0
        self.zoom = .2
        self.reports = os.listdir(self.dir_path)
        reports_already_done = set(self.data.ocr_report_path)
        lst = self.reports
        for finished in reports_already_done:
            lst.remove(finished)

        self.reports = lst

        remain_string = "remaining folders " + str(len(self.reports))
        self.remainingLabel = QLabel(remain_string)
        self.left.addWidget(self.remainingLabel)

        temp_path = os.path.join(self.dir_path, self.reports[self.crop_index])
        self.report = os.listdir(temp_path)

        if (len(self.report) > 0):
            self.page = self.report[self.page_index]
            temp_path = os.path.join(self.dir_path,
                                     self.reports[self.crop_index], self.page)
            print(temp_path)
            self.pixmap = QPixmap(temp_path)
            self.scene.clear()
            self.pixmap = QPixmap(temp_path)
            #adjusts zoom
            self.pixmap = self.pixmap.scaled(
                self.pixmap.size().width() * self.zoom,
                self.pixmap.size().height() * self.zoom, Qt.KeepAspectRatio)
            self.scene.addPixmap(self.pixmap)

            #key bindings
            def key_press(event):
                key = event.char
                print(key, 'is pressed')

    @Slot()
    def submit(self):
        self.write_to_csv()
        self.page_index = 0

        self.crop_index = self.crop_index + 1

        self.postImage()
        self.dateText.setText("")
        remain_string = "remaining folders " + str(
            len(self.reports) - self.crop_index)
        self.remainingLabel.setText(remain_string)

    @Slot()
    def nextImage(self):
        if ((len(self.report) - 1) > self.page_index):
            self.page_index = self.page_index + 1
        else:
            self.page_index = 0

        self.postImage()

    @Slot()
    def prevImage(self):
        if (1 > self.page_index):
            self.page_index = len(self.report) - 1
        else:
            self.page_index = self.page_index - 1

        self.postImage()

    def postImage(self):
        temp_path = os.path.join(self.dir_path, self.reports[self.crop_index])
        self.report = os.listdir(temp_path)

        if (len(self.report) > 0):
            print(self.page_index)
            self.page = self.report[self.page_index]
            temp_path = os.path.join(self.dir_path,
                                     self.reports[self.crop_index], self.page)
            print(temp_path)
            self.scene.clear()
            self.pixmap = QPixmap(temp_path)
            #adjusts zoom
            self.pixmap = self.pixmap.scaled(
                self.pixmap.size().width() * self.zoom,
                self.pixmap.size().height() * self.zoom, Qt.KeepAspectRatio)
            self.scene.addPixmap(self.pixmap)

    def write_to_csv(self):
        new_row = {
            'ocr_report_path': self.reports[self.crop_index],
            'date': self.dateText.text()
        }
        self.data = self.data.append(new_row, ignore_index=True)
        self.data.to_csv(self.data_path, index=False)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Return:
            self.submit()
Пример #15
0
class ScreenshotView(QGraphicsView):
    def __init__(self, parent, screen, parm, gradient_edit, ramp_sketch):
        super(ScreenshotView, self).__init__(parent)

        self.scene = QGraphicsScene(parent)
        self.setScene(self.scene)

        self.parm = parm  # type: hou.Parm
        self.screen = screen

        geometry = screen.geometry()

        if sys.platform == "darwin":
            self.screen_pixmap = screen.grabWindow(0, geometry.x(),
                                                   geometry.y(),
                                                   geometry.width(),
                                                   geometry.height())
        else:
            self.screen_pixmap = screen.grabWindow(0)

        self.screen_image = self.screen_pixmap.toImage()  # type: QImage

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setFrameStyle(QFrame.NoFrame)
        self.scene.clear()
        self.setGeometry(screen.geometry())

        self.setSceneRect(0, 0, self.screen_pixmap.width(),
                          self.screen_pixmap.height())
        self.scene.addPixmap(self.screen_pixmap)

        self.setMouseTracking(True)
        self.color_info = ColorInformation()
        self.scene.addItem(self.color_info)

        self.gradient_edit = gradient_edit
        self.ramp_sketch = ramp_sketch

        self.path = QPainterPath()
        self.draw_path = False

        self.path_item = QGraphicsPathItem()
        if not self.ramp_sketch:
            self.path_item.setPen(QPen(QColor(0, 200, 100, 200), 2))
        else:
            self.path_item.setPen(QPen(QColor(200, 200, 50, 255), 4))
        self.scene.addItem(self.path_item)

        self.colors = []  # type: list[QColor]
        self.positions = []  # type: list[QPoint]
        self.picked_color = QColor()

        self.disable_gamma_correction = False

        if self.underMouse():
            self.color_info.show()
        else:
            self.color_info.hide()

        self.is_macos = sys.platform == "darwin"

        # TODO: ???
        if self.is_macos:
            self.color_info.show()

        if self.ramp_sketch:
            self.color_info.hide()

    def update_info(self, pos):
        image_pos = pos * self.screen.devicePixelRatio()
        if self.screen_image.rect().contains(image_pos):
            self.color_info.color = QColor(
                self.screen_image.pixel(image_pos.x(), image_pos.y()))
        self.color_info.setPos(pos)
        self.color_info.pos = pos

    def write_ramp_sketch(self):
        if len(self.positions) < 2:
            return

        positions = np.array([(float(p.x()), float(-p.y()))
                              for p in self.positions])

        min_point = positions.min(axis=0)
        max_point = positions.max(axis=0)

        ramp_range = max_point - min_point

        if not np.any((ramp_range == 0.0)):
            norm_positions = (positions - min_point) / ramp_range

            geo_points = []
            geo_points.append(
                hou.Vector3(norm_positions[0][0], norm_positions[0][1], 0.0))
            left = 0.0
            for pt in norm_positions[1:-1]:
                if pt[0] >= left:
                    left = pt[0]
                    geo_points.append(hou.Vector3(pt[0], pt[1], 0.0))

            geo_points.append(
                hou.Vector3(norm_positions[-1][0], norm_positions[-1][1], 0.0))

            ramp_geo = hou.Geometry()  # type: hou.Geometry
            ramp_points = ramp_geo.createPoints(geo_points)
            ramp_geo.createPolygons((ramp_points, ), False)

            resample_verb = hou.sopNodeTypeCategory().nodeVerb(
                "resample")  # type: hou.SopVerb
            resample_verb.setParms({"length": 0.04})

            resample_verb.execute(ramp_geo, [ramp_geo])

            facet_verb = hou.sopNodeTypeCategory().nodeVerb(
                "facet")  # type: hou.SopVerb
            facet_verb.setParms({"inline": 1, "inlinedist": 0.003})

            facet_verb.execute(ramp_geo, [ramp_geo])

            ramp_poly = ramp_geo.prim(0)
            ramp_points = ramp_poly.points()

            ramp_basis = hou.rampBasis.BSpline if self.disable_gamma_correction else hou.rampBasis.Linear

            basis = []
            keys = []
            values = []

            for point in ramp_points:  # type: hou.Point
                basis.append(ramp_basis)
                pos = point.position()
                keys.append(pos.x())
                values.append(pos.y())

            ramp = hou.Ramp(basis, keys, values)
            self.parm.set(ramp)
            self.parm.pressButton()

    def write_color_ramp(self):
        if len(self.colors) < 2:
            return

        color_points = []

        vlast_color = hou.Vector3(hou.qt.fromQColor(self.colors[0])[0].rgb())
        last_color_index = 0

        color_points.append((vlast_color, 0))

        # remove same keys in a row
        for index, color in enumerate(self.colors[1:]):
            color_index = index + 1
            vcolor = hou.Vector3(hou.qt.fromQColor(color)[0].rgb())
            dist = vcolor.distanceTo(vlast_color)

            if dist > TOLERANCE:
                # if color_index - last_color_index > 1 and dist > SHARP_PRECISION:
                #     color_points.append((hou.Vector3(vlast_color), color_index - 1))
                color_points.append((hou.Vector3(vcolor), color_index))
                vlast_color = vcolor
                last_color_index = color_index

        if color_points[-1][1] < (len(self.colors) - 1):
            color_points.append(
                (hou.Vector3(hou.qt.fromQColor(self.colors[-1])[0].rgb()),
                 len(self.colors) - 1))

        # Create a polyline representing ramp and remove inline points with Facet SOP
        points = [color_point[0] for color_point in color_points]
        pos = [color_point[1] for color_point in color_points]

        ramp_geo = hou.Geometry()

        pos_attrib = ramp_geo.addAttrib(hou.attribType.Point,
                                        "ramp_pos",
                                        0.0,
                                        create_local_variable=False)

        ramp_points = ramp_geo.createPoints(points)
        fnum_points = float(len(self.colors) - 1)

        for ptnum, point in enumerate(ramp_points):  # type: (int, hou.Point)
            point.setAttribValue(pos_attrib, float(pos[ptnum]) / fnum_points)

        ramp_poly = ramp_geo.createPolygons((ramp_points, ),
                                            False)[0]  # type: hou.Face

        facet_verb = hou.sopNodeTypeCategory().nodeVerb(
            "facet")  # type: hou.SopVerb

        facet_verb.setParms({"inline": 1, "inlinedist": 0.02})

        facet_verb.execute(ramp_geo, [ramp_geo])

        ramp_poly = ramp_geo.prim(0)
        ramp_points = ramp_poly.points()

        linear = hou.rampBasis.Linear

        basis = []
        keys = []
        values = []

        pos_attrib = ramp_geo.findPointAttrib("ramp_pos")

        for point in ramp_points:  # type: hou.Point
            basis.append(linear)
            keys.append(point.attribValue(pos_attrib))
            values.append(tuple(point.position()))

        if not self.disable_gamma_correction:
            values = [np.power(v, 2.2) for v in values]

        ramp = hou.Ramp(basis, keys, values)
        self.parm.set(ramp)
        self.parm.pressButton()

    def enterEvent(self, event):
        if not self.ramp_sketch:
            self.color_info.show()

    def leaveEvent(self, event):
        self.color_info.hide()

    def mouseMoveEvent(self, event):
        pos = event.pos()  #* self.screen.devicePixelRatio()
        self.update_info(pos)

        # TODO: ???
        if self.is_macos and not self.ramp_sketch:
            self.color_info.show()

        if self.draw_path:
            path = self.path_item.path()
            path.lineTo(pos)
            self.path_item.setPath(path)
            self.colors.append(self.color_info.color)
            self.positions.append(pos)

        return QGraphicsView.mouseMoveEvent(self, event)

    def mousePressEvent(self, event):
        modifiers = QApplication.keyboardModifiers()

        if modifiers & Qt.ShiftModifier:
            self.disable_gamma_correction = True

        if self.gradient_edit or self.ramp_sketch:
            self.draw_path = True
            self.path.moveTo(event.pos())
            self.path_item.setPath(self.path)
        else:
            self.picked_color = self.color_info.color

    def mouseReleaseEvent(self, event):
        if self.gradient_edit and self.draw_path:
            self.write_color_ramp()
        elif self.ramp_sketch and self.draw_path:
            self.write_ramp_sketch()
        elif not self.gradient_edit:
            out_color = hou.qt.fromQColor(self.picked_color)[0].rgb()
            if not self.disable_gamma_correction:
                out_color = np.power(out_color, 2.2)

            if isinstance(self.parm, hou.ParmTuple) and len(self.parm) == 4:
                alpha = self.parm[3].eval()
                out_color = np.append(out_color, alpha)

            self.parm.set(out_color)

        if self.parent() is not None:
            self.parent().mouseReleaseEvent(event)
Пример #16
0
class RawImageEditor(SubWindow):
    def __init__(self, name='RawImageEditor', parent=None):
        super().__init__(name, parent, Ui_ImageEditor(), need_processBar=True)

        self.scene = QGraphicsScene()
        self.imageview = ImageView(self.scene, parent)
        self.img_params = RawImageParams()
        self.img_params = self.load_params(RawImageParams())
        self.img_pipeline = IspPipeline(self.img_params,
                                        process_bar=self.progress_bar)
        self.img = self.img_pipeline.get_image(0)
        self.point_data = 0
        self.scale_ratio = 100
        self.histShow = None
        self.show_img = None
        self.select_awb = False

        # 由于graphicsView被自定义了,需要重新定义一下UI,gridlayout还需要重新加一下widget
        self.ui.graphicsView.addWidget(self.imageview, 0, 1, 3, 1)
        self.imageview.sigDragEvent.connect(self.__init_img)
        self.imageview.sigMouseMovePoint.connect(self.show_point_rgb)
        self.imageview.sigWheelEvent.connect(self.update_wheel_ratio)
        # 回调函数初始化
        self.ui.pipeline.doubleClicked.connect(self.update_img_index)
        self.ui.pipeline_ok.clicked.connect(self.update_pipeline)
        self.ui.open_image.clicked.connect(self.open_image)
        self.ui.analysis_img.clicked.connect(self.openHistView)
        self.ui.select_from_raw.clicked.connect(self.select_awb_from_raw)
        self.imageview.rubberBandChanged.connect(self.update_awb_from_raw)
        self.ui.save_image.clicked.connect(self.save_now_image)
        self.ui.reload.clicked.connect(self.img_pipeline.reload_isp)
        # ISP 处理线程回调
        self.img_pipeline.ispProcthread.doneCB.connect(self.update_img)
        self.img_pipeline.ispProcthread.processRateCB.connect(
            self.update_process_bar)
        self.img_pipeline.ispProcthread.costTimeCB.connect(
            self.update_time_bar)

    def update_img(self):
        """
        func: ISP 处理完成后的显示回调函数
        """
        self.displayImage(self.img_pipeline.get_image(-1))

    def update_process_bar(self, value):
        """
        func: ISP 处理进度回调
        """
        self.progress_bar.setValue(value)

    def update_time_bar(self, value):
        """
        func:ISP 处理时长回调
        """
        self.time_bar.setText(value)

    def show(self):
        """
        func: 显示初始化
        """
        super().show()
        self.img_params.set_img_params_ui(self.ui)
        if (self.img_params.filename != "" and self.img_params.get_width() != 0
                and self.img_params.get_height() != 0
                and self.img_params.get_bit_depth() != 0):
            if (self.img_pipeline.pipeline_reset() == True):
                self.img = self.img_pipeline.get_image(0)
                for i in range(1, self.ui.pipeline.count()):
                    self.ui.pipeline.item(i).setCheckState(Qt.Unchecked)
            self.img.load_image_with_params(self.img_params)
            self.img.set_bayer_pattern(self.img_params.get_pattern())
            self.rect = [0, 0, self.img_params.width, self.img_params.height]
            if (self.img.get_raw_data() is not None):
                self.displayImage(self.img)

    def displayImage(self, img):
        """
        显示图像 输入需要是RawImageInfo
        """
        self.scene.clear()
        self.img = img
        self.show_img = img.get_showimage()
        if (self.show_img is not None):
            showimg = QImage(self.show_img, self.show_img.shape[1],
                             self.show_img.shape[0], QImage.Format_BGR888)
            self.scene.addPixmap(QPixmap(showimg))
            self.ui.photo_title.setTitle(img.get_name())

    def select_awb_from_raw(self):
        """
        func: 进入raw图选择模式,修改鼠标类型
        """
        self.imageview.setDragMode(QGraphicsView.RubberBandDrag)
        self.select_awb = True

    def update_awb_from_raw(self, viewportRect, fromScenePoint, toScenePoint):
        """
        func: 鼠标选中事件的回调:执行AWB的选择区域或者图像分析的选择区域
        """
        if (toScenePoint.x() == 0 and toScenePoint.y() == 0
                and self.rect[2] > self.rect[0]
                and self.rect[3] > self.rect[1]):
            if (self.select_awb == True):
                self.imageview.setDragMode(QGraphicsView.ScrollHandDrag)
                self.select_awb = False
                awb_ratio = self.img.get_raw_img_rect(self.rect)
                if (awb_ratio is not None):
                    self.img_params.set_awb_ratio(awb_ratio)
                    awb_gain = self.img_params.get_awb_gain()
                    self.ui.awb_r.setValue(awb_gain[0])
                    self.ui.awb_g.setValue(awb_gain[1])
                    self.ui.awb_b.setValue(awb_gain[2])
                else:
                    critical("请在raw图上进行选择")
            else:
                if (self.histView is not None):
                    self.histView.update_rect_data(self.show_img, self.rect)
        else:
            self.rect = [
                int(fromScenePoint.x()),
                int(fromScenePoint.y()),
                int(toScenePoint.x()),
                int(toScenePoint.y())
            ]

    def update_pipeline(self):
        """
        func: 运行ISP pipeline
        """
        self.img_params.get_img_params(self.ui)
        self.img_pipeline.pipeline_clear()
        for i in range(self.ui.pipeline.count()):
            if (self.ui.pipeline.item(i).checkState() == Qt.Checked):
                self.img_pipeline.add_pipeline_node(
                    self.ui.pipeline.item(i).data(0))
        self.img_pipeline.run_pipeline()

    def update_img_index(self, item):
        """
        func: 更新当前画面的序号
        """
        if (self.ui.pipeline.item(item.row()).checkState() == Qt.Checked):
            index = self.img_pipeline.get_pipeline_node_index(item.data()) + 1
            self.displayImage(self.img_pipeline.get_image(index))

    def open_image(self):
        """
        func: 打开图片的回调函数
        """
        if (self.img_params.filename != ''):
            now_path = os.path.dirname(self.img_params.filename)
        else:
            now_path = './'
        self.img_params.get_img_params(self.ui)
        imagepath = QFileDialog.getOpenFileName(None, '打开RAW图', now_path,
                                                "raw (*.raw)")
        self.__init_img(imagepath[0])

    def __init_img(self, filename):
        width = self.img_params.get_width()
        height = self.img_params.get_height()
        bit_depth = self.img_params.get_bit_depth()
        if (filename != "" and width != 0 and height != 0 and bit_depth != 0):
            if (self.img_pipeline.pipeline_reset() == True):
                self.img = self.img_pipeline.get_image(0)
                for i in range(1, self.ui.pipeline.count()):
                    self.ui.pipeline.item(i).setCheckState(Qt.Unchecked)
            self.img.load_image(filename, height, width, bit_depth)
            self.img.set_bayer_pattern(self.img_params.get_pattern())
            self.img_params.filename = filename
            self.rect = [0, 0, self.img_params.width, self.img_params.height]
            if (self.img.get_raw_data() is not None):
                self.displayImage(self.img)
            else:
                critical("打开图片失败,图片格式错误")
        else:
            critical("打开图片失败,图片格式错误")

    def save_now_image(self):
        """
        func: 保存图片的回调
        """
        if (self.img.get_raw_data() is not None):
            imagepath = QFileDialog.getSaveFileName(None, '保存图片', './',
                                                    "Images (*.jpg)")
            if (imagepath[0] != ""):
                self.img.save_image(imagepath[0])

    def show_point_rgb(self, point):
        """
        func: 鼠标移动的回调
        """
        self.x = int(point.x())
        self.y = int(point.y())
        if (self.img.get_raw_data() is not None):
            point_data = self.img.get_img_point(self.x, self.y)
            if (point_data is not None):
                self.point_data = point_data
                self.set_img_info_show()

    def update_wheel_ratio(self, ratio):
        """
        func: 鼠标滚轮的回调
        """
        if (self.img.get_raw_data() is not None):
            self.scale_ratio = int(ratio * 100)
            self.set_img_info_show()

    def set_img_info_show(self):
        """
        func: 显示像素点的值以及缩放比例
        """
        if (self.point_data.size == 1):
            self.info_bar.setText("x:{},y:{} : {}: 亮度:{} 缩放比例:{}%".format(
                self.x, self.y,
                self.img.get_img_point_pattern(self.y, self.x).upper(),
                self.point_data, self.scale_ratio))
        elif (self.point_data.size == 3):
            if (self.img.get_color_space() == 'RGB'):
                self.info_bar.setText(
                    "x:{},y:{} : R:{} G:{} B:{} 缩放比例:{}%".format(
                        self.x, self.y, self.point_data[2], self.point_data[1],
                        self.point_data[0], self.scale_ratio))
            else:
                self.info_bar.setText(
                    "x:{},y:{} : Y:{} Cr:{} Cb:{} 缩放比例:{}%".format(
                        self.x, self.y, self.point_data[0], self.point_data[1],
                        self.point_data[2], self.scale_ratio))

    def openHistView(self):
        self.histView = HistView(self.imageview)
        rect = [0, 0, self.show_img.shape[1], self.show_img.shape[0]]
        self.histView.update_rect_data(self.show_img, rect)
        self.histView.show()
Пример #17
0
class QGameOfLife(QWidget):

    Games = {
        "Game of Life": (GameOfLife, {'fill_rate': 0.50}),
        "Bacteria": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.035, 0.065)}),
        "Coral": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.062, 0.062)}),
        "Fingerprint": (GrayScottDiffusion, {'coeffs': (0.19, 0.05, 0.060, 0.062)}),
        "Spirals": (GrayScottDiffusion, {'coeffs': (0.10, 0.10, 0.018, 0.050)}),
        "Unstable": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.020, 0.055)}),
        "Worms": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.050, 0.065)}),
        "Zebrafish": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.035, 0.060)}),
    }

    def __init__(self, size=(400, 400)):
        super(QGameOfLife, self).__init__()
        self.size = size
        self.game = None
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Game of Life"))
        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.comboBox = QComboBox()
        self.comboBox.addItems([*QGameOfLife.Games.keys()])
        self.comboBox.currentTextChanged.connect(self.select)
        self.layout().addWidget(self.comboBox)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        self.view.setFrameShape(QFrame.NoFrame)
        self.layout().addWidget(self.view)

        self.item = None
        self.timer = QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.tick)
        initialGame = random.choice([*QGameOfLife.Games.keys()])
        self.select(initialGame)
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)
        self.comboBox.setCurrentText(initialGame)

    def select(self, name: str):
        self.timer.stop()
        Game, args = QGameOfLife.Games[name]
        self.game = Game(self.size, **args)
        self.tick()
        self.timer.start()

    def tick(self):
        self.game.tick()
        bitmap = self.game.visualize()
        image = QImage(bitmap.data, bitmap.shape[1], bitmap.shape[0], QImage.Format_Grayscale8)
        self.scene.removeItem(self.item)
        pixmap = QPixmap.fromImage(image)
        self.item = self.scene.addPixmap(pixmap)

    def resizeEvent(self, event: QResizeEvent):
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)

    def sizeHint(self) -> QSize:
        return QSize(self.size[0], self.size[1])
Пример #18
0
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.layout = QVBoxLayout()
        #fix this
        self.scale = 4.16
        self.zoom = 2
        self.anchor_list = []
        self.top_anchor = []
        self.bottom_anchor = []
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)

        # fix this
        #self.filenames = ["../Other Data/Medical Data/nls-data-indiaPapers/91541450/image/" + x for x in os.listdir("../Other Data/Medical Data/nls-data-indiaPapers/91541450/image/")]
        #"91541967.3",
        # use write table no number
        #self.filenames = ["91540775.3","91540907.3","91541048.3","91541159.3","91541336.3"]
        self.filenames = ["91541574.3"]
        self.filenames_full = [
            "../Other Data/Medical Data/nls-data-indiaPapers/91541450/image/" +
            x + ".jpg" for x in self.filenames
        ]
        self.index = 0
        self.jpg_path = self.filenames_full[self.index]
        print(self.jpg_path)
        self.xml = self.jpg_path.split(
            "/image")[0] + "/alto/" + self.jpg_path.split("/image/")[1].split(
                ".")[0] + ".34.xml"

        self.pixmap = QPixmap(self.jpg_path)
        print(u"pixmap width height", self.pixmap.width())
        self.pixmap = self.pixmap.scaled(
            self.pixmap.size().width() * self.zoom,
            self.pixmap.size().height() * self.zoom, Qt.KeepAspectRatio)

        #only for images that need rotate
        self.view.rotate(90)

        self.data = self.getData()
        self.scene.addPixmap(self.pixmap)

        self.layout.addWidget(self.view)

        self.b1 = QHBoxLayout()
        self.b2 = QHBoxLayout()
        self.b3 = QHBoxLayout()
        self.yearLabel = QLabel("Year:")
        self.yearEdit = QLineEdit()
        self.yearSubmit = QPushButton("Submit Year")
        self.b1.addWidget(self.yearLabel)
        self.b1.addWidget(self.yearEdit)
        self.b1.addWidget(self.yearSubmit)
        self.topAnchorLabel = QLabel("Top Anchor: ")
        self.topAnchorButton = QPushButton("Top Anchor")
        self.b2.addWidget(self.topAnchorLabel)
        self.b2.addWidget(self.topAnchorButton)

        self.bottomAnchorLabel = QLabel("Bottom Anchor: ")
        self.bottomAnchorButton = QPushButton("Bottom Anchor")
        self.b3.addWidget(self.bottomAnchorLabel)
        self.b3.addWidget(self.bottomAnchorButton)

        self.layout.addLayout(self.b1)
        self.layout.addLayout(self.b2)
        self.layout.addLayout(self.b3)
        self.submitButton = QPushButton("Submit")
        self.layout.addWidget(self.submitButton)

        self.setLayout(self.layout)
        self.view.show()

        # Sets up drawing capabilities:
        self.view.setMouseTracking(True)
        self.view.viewport().installEventFilter(self)
        self.start = None
        self.end = None

        #connects to function
        self.topAnchorButton.clicked.connect(self.topAnchorFunction)
        self.bottomAnchorButton.clicked.connect(self.bottomAnchorFunction)
        self.submitButton.clicked.connect(self.table_to_csv)

    def eventFilter(self, source, event):
        if event.type(
        ) == QtCore.QEvent.MouseButtonPress and source is self.view.viewport():
            self.start = event.pos()
            self.start = self.view.mapToScene(self.start)
            print(u"mouse", self.start)

        if event.type(
        ) == QtCore.QEvent.MouseButtonRelease and source is self.view.viewport(
        ):
            self.end = event.pos()
            self.end = self.view.mapToScene(self.end)
            self.drawBox()
            self.select_table()

    def select_table(self):
        data = self.data
        data.HPOS = data.HPOS.astype(int)
        data.VPOS = data.VPOS.astype(int)
        x1 = self.start.x() * self.scale * (1 / self.zoom)
        y1 = self.start.y() * self.scale * (1 / self.zoom)
        x3 = self.end.x() * self.scale * (1 / self.zoom)
        y3 = self.end.y() * self.scale * (1 / self.zoom)
        table = data[(data.HPOS > x1) & (data.HPOS < x3) & (data.VPOS > y1) &
                     (data.VPOS < y3)]

        my_list = self.anchor_list
        my_list.append(table.CONTENT[0])
        self.anchor_list = self.anchor_list
        print(self.anchor_list)

    @Slot()
    def topAnchorFunction(self):
        self.top_anchor = self.anchor_list
        self.topAnchorLabel.setText(str(self.top_anchor))
        self.anchor_list = []

    @Slot()
    def bottomAnchorFunction(self):
        self.bottom_anchor = self.anchor_list
        self.bottomAnchorLabel.setText(str(self.bottom_anchor))
        self.anchor_list = []

    @Slot()
    def table_to_csv(self):
        my.write_table_2(self.xml, self.top_anchor, self.bottom_anchor,
                         self.yearEdit.text(), self.jpg_path)

    def drawBox(self):
        x1 = self.start.x()
        y1 = self.start.y()
        x3 = self.end.x()
        y3 = self.end.y()
        diff_x = x3 - x1
        diff_y = y3 - y1
        rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y)
        #rectItem.setBrush(QBrush(Qt.green))
        self.scene.addItem(rectItem)

    def getData(self):
        # will replace with one
        tree = ET.parse(self.xml)

        root = tree.getroot()

        NSMAP = {'mw': 'http://www.loc.gov/standards/alto/v3/alto.xsd'}
        pass
        all_name_elements = tree.findall('.//mw:TextLine', NSMAP)

        base = list(all_name_elements[0].getchildren()[0].attrib.items())
        column_names = pd.DataFrame(base,
                                    columns=['key',
                                             'value']).transpose().iloc[0]
        master_df = pd.DataFrame()
        i = 0
        while i < len(all_name_elements):
            data_list = list(
                all_name_elements[i].getchildren()[0].attrib.items())
            if len(column_names) == len(data_list):
                df = pd.DataFrame(data_list, columns=['key', 'value'])
                row = df.transpose().iloc[1]
                master_df = master_df.append(row)
            else:
                print("Something wrong")
                print(data_list)
            i = i + 1

        master_df = master_df.rename(columns=column_names)

        return (master_df)
Пример #19
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        # self.label = QLabel()

        # image = QPixmap("test_images/002.png")
        # label = QPixmap("test_masks/002.png")

        # canvas = QPixmap(512,512)
        #
        # image = QImage("test_images/002.png")
        # label = QImage("test_masks/002.png")
        #
        # painter = QPainter()
        # painter.begin(canvas)
        # painter.drawImage(QPoint(0,0), label)
        # painter.drawImage(QPoint(0,0), image)
        # painter.end()
        #
        # self.label.setPixmap(canvas)
        # self.setCentralWidget(self.label)
        #
        self.scene = QGraphicsScene(0, 0, 400, 200)

        pixmap = QPixmap("test_images/002.png")
        pixmap_item = self.scene.addPixmap(pixmap)
        pixmap_item.setPos(0, 0)

        view = View(self.scene)
        view.setRenderHint(QPainter.RenderHint.Antialiasing)

        self.view = view
        # self.view.setAlignment(Qt.AlignLeft)
        # self.view.setAlignment(Qt.AlignTop)
        self.view.setMinimumWidth(512)
        self.view.setMinimumHeight(512)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.view.ensureVisible(pixmap_item, 0, 0)

        btn = QPushButton("button")
        btn.clicked.connect(self.list_items())

        hbox = QHBoxLayout(self)
        hbox.addWidget(view)
        hbox.addWidget(btn)

        widget = QWidget()
        widget.setLayout(hbox)

        self.setCentralWidget(widget)

    def list_items(self):
        print(self.scene.items())
        item = self.scene.items()[0]
        pos = item.pos()
        x, y = pos.x(), pos.y()
        item.setPos(x + 10, x + 10)
Пример #20
0
class ImageEditor(SubWindow):
    def __init__(self, name='ImageEditor', parent=None):
        super().__init__(name, parent, Ui_ImageEditor())
        self.scene = QGraphicsScene()
        self.imageview = ImageView(self.scene, parent)
        # 由于graphicsView被自定义了,需要重新定义一下UI,gridlayout还需要重新加一下widget
        self.ui.gridLayout.addWidget(self.imageview, 0, 1, 3, 1)
        self.imageview.sigDragEvent.connect(self.__init_img)
        self.imageview.sigMouseMovePoint.connect(self.show_point_rgb)
        self.imageview.sigWheelEvent.connect(self.update_wheel_ratio)
        self.ui.openimage.triggered.connect(self.on_open_img)
        self.ui.saveimage.triggered.connect(self.save_now_image)
        self.ui.compareimage.triggered.connect(self.compare_image)
        self.ui.boxblur.triggered.connect(self.boxblur_image)
        self.ui.guassian.triggered.connect(self.guassian_image)
        self.ui.medianblur.triggered.connect(self.medianblur_image)
        self.ui.bilateralblur.triggered.connect(self.bilateralblur_image)
        # self.ui.historgram.triggered.connect(self.on_calc_hist)
        self.ui.actionstats.triggered.connect(self.on_calc_stats)
        self.ui.nextphoto.triggered.connect(self.switch_next_photo)
        self.ui.prephoto.triggered.connect(self.switch_pre_photo)
        self.imageview.rubberBandChanged.connect(self.update_stats_range)
        self.ui.watermark.triggered.connect(self.open_watermark_win)
        self.ui.deletephoto.triggered.connect(self.delete_photo)
        self.scale_ratio = 100
        self.img = ImageEffect()
        self.filepath = './'
        self.imgfilename = ''
        self.hist_window = None

    def displayImage(self, img):
        self.scene.clear()
        if img is not None:
            # numpy转qimage的标准流程
            if len(img.shape) == 2:
                bytes_per_line = img.shape[1]
                qimg = QImage(img, img, img.shape[1],
                              img.shape[0], QImage.Format_Grayscale8)
            elif img.shape[2] == 3:
                bytes_per_line = 3 * img.shape[1]
                qimg = QImage(img, img.shape[1],
                              img.shape[0], bytes_per_line, QImage.Format_BGR888)
            elif img.shape[2] == 4:
                bytes_per_line = 4 * img.shape[1]
                qimg = QImage(img, img.shape[1],
                              img.shape[0], bytes_per_line, QImage.Format_RGBA8888)
            else:
                critical("图片格式不能解析")
            self.scene.addPixmap(QPixmap.fromImage(qimg))
            if(self.hist_window is not None and self.hist_window.enable is True):
                self.hist_window.update_rect_data(
                    self.img.nowImage, self.rect)
    
    def delete_photo(self):
        current_photo = join(self.filepath, self.imgfilename)
        next_photo, index, files_nums = self.find_next_photo(self.filepath, 1)
        indexstr = "({}/{})".format(index, files_nums - 1)
        self.__init_img(next_photo, indexstr)
        remove(current_photo)


    def find_next_photo(self, path, nextIndex):
        ret = ''
        index = 0
        filelist = [f for f in listdir(path) if isfile(
            join(path, f)) and f.split('.')[-1] in ["jpg", "png", "bmp"]]
        filelist = sorted(
            filelist,  key=lambda x: getmtime(join(path, x)))
        files_nums = len(filelist)
        if(self.imgfilename in filelist):
            index = filelist.index(self.imgfilename) + nextIndex
            if(index > len(filelist) - 1):
                index = 0
            elif(index < 0):
                index = len(filelist) - 1
            ret = join(path, filelist[index])
        return (ret, index, files_nums)

    def switch_next_photo(self):
        next_photo, index, files_nums = self.find_next_photo(self.filepath, 1)
        indexstr = "({}/{})".format(index + 1, files_nums)
        self.__init_img(next_photo, indexstr)

    def switch_pre_photo(self):
        pre_photo, index, files_nums = self.find_next_photo(self.filepath, -1)
        indexstr = "({}/{})".format(index + 1, files_nums)
        self.__init_img(pre_photo, indexstr)

    def on_open_img(self):
        imagepath = QFileDialog.getOpenFileName(
            None, '打开图片', self.filepath, "Images (*.jpg *.png *.bmp)")
        self.__init_img(imagepath[0])

    def __init_img(self, filename, indexstr=''):
        if (filename != ''):
            self.img.load_image(filename)
            self.filepath = dirname(filename)
            self.imgfilename = basename(filename)
            self.img.imageconvert(0)
            if (self.img.nowImage is not None):
                self.displayImage(self.img.nowImage)
                self.ui.photo_title.setTitle(indexstr + self.imgfilename)
            else:
                rely = QMessageBox.critical(
                    self, '警告', '打开图片失败,', QMessageBox.Yes, QMessageBox.Yes)
                return

    def open_watermark_win(self):
        if(self.img.is_load_image == True):
            self.watermark_win = QDialog(self.imageview)
            self.watermark_ui = Ui_WaterMarkView()
            self.watermark_ui.setupUi(self.watermark_win)
            self.watermark_win.show()
            self.watermark_ui.open_watermark.clicked.connect(
                self.open_watermark_path)
            self.watermark_ui.change_transparent.valueChanged.connect(
                self.set_watermark_params)
            self.watermark_ui.change_watermark_size.valueChanged.connect(
                self.set_watermark_params)
            self.watermark_ui.change_watermark_th.valueChanged.connect(
                self.set_watermark_params)
            self.watermark_ui.change_watermark_type.currentIndexChanged.connect(
                self.set_watermark_params)
            self.watermark_ui.generate.clicked.connect(self.generate_watermark)
            self.watermark_ui.analysis.clicked.connect(
                self.analysis_space_watermark)
        else:
            critical('打开原图片失败,请先导入图片')

    def open_watermark_path(self):
        watermarkpath = QFileDialog.getOpenFileName(
            None, '打开图片', './', "Images (*.jpg *.png *.bmp)")
        self.watermark_path = watermarkpath[0]
        if (self.watermark_path != ''):
            self.watermark_ui.watermark_path.setText(self.watermark_path)
            self.img.set_watermark_img(self.watermark_path)
            self.set_watermark_params()
        else:
            critical('打开水印图片失败')

    def get_watermark_parmas(self):
        watermark_params = WaterMarkParams()
        watermark_params.transparent = self.watermark_ui.change_transparent.value()
        watermark_params.size = self.watermark_ui.change_watermark_size.value()
        watermark_params.threshold = self.watermark_ui.change_watermark_th.value()
        watermark_params.watermark_type = self.watermark_ui.change_watermark_type.currentIndex()
        return watermark_params

    def set_watermark_params(self):
        self.img.set_watermark_show(self.get_watermark_parmas())
        self.img.imageconvert(1)
        self.displayImage(self.img.dstImage)

    def generate_watermark(self):
        self.img.imageconvert(1)
        self.img.generate_watermark(self.get_watermark_parmas())
        self.displayImage(self.img.dstImage)

    def analysis_space_watermark(self):
        self.img.analysis_space_watermark()
        self.img.imageconvert(1)
        self.displayImage(self.img.dstImage)

    def boxblur_image(self):
        if(self.img.is_load_image == True):
            self.img.blur(BlurType.BoxBlur)
            self.img.imageconvert(1)
            self.displayImage(self.img.nowImage)

    def guassian_image(self):
        if(self.img.is_load_image == True):
            self.img.blur(BlurType.GaussianBlur)
            self.img.imageconvert(1)
            self.displayImage(self.img.nowImage)

    def medianblur_image(self):
        if(self.img.is_load_image == True):
            self.img.blur(BlurType.MediaBlur)
            self.img.imageconvert(1)
            self.displayImage(self.img.nowImage)

    def bilateralblur_image(self):
        if(self.img.is_load_image == True):
            self.img.blur(BlurType.BilateralBlur)
            self.img.imageconvert(1)
            self.displayImage(self.img.nowImage)

    def save_now_image(self):
        if(self.img.is_load_image == True):
            imagepath = QFileDialog.getSaveFileName(
                None, '保存图片', './', "Images (*.jpg)")
            if(imagepath[0] != ''):
                self.img.save_image(self.img.nowImage, imagepath[0])

    def compare_image(self):
        if(self.img.is_load_image == True):
            if(self.img.get_img_index() == 0):
                self.img.imageconvert(1)
            else:
                self.img.imageconvert(0)
            self.displayImage(self.img.nowImage)

    def update_stats_range(self, viewportRect, fromScenePoint, toScenePoint):
        if(toScenePoint.x() == 0 and toScenePoint.y() == 0
           and self.rect[2] > self.rect[0] and self.rect[3] > self.rect[1]):
            if(self.hist_window is not None):
                self.hist_window.update_rect_data(self.img.nowImage, self.rect)
        else:
            self.rect = [int(fromScenePoint.x()), int(fromScenePoint.y()), int(
                toScenePoint.x()), int(toScenePoint.y())]
        return

    def show_point_rgb(self, point):
        """
        func: 鼠标移动的回调
        """
        self.x = int(point.x())
        self.y = int(point.y())
        if(self.img.is_load_image == True):
            rgb = self.img.get_img_point(self.x, self.y)
            if (rgb is not None):
                self.rgb = rgb
                self.ui.statusBar.showMessage(
                    "x:{},y:{} : R:{} G:{} B:{} 缩放比例:{}%".format(self.x, self.y, self.rgb[2], self.rgb[1], self.rgb[0], self.scale_ratio))

    def update_wheel_ratio(self, ratio):
        """
        func: 鼠标滚轮的回调
        """
        if(self.img.is_load_image == True):
            self.scale_ratio = int(ratio * 100)
            self.ui.statusBar.showMessage(
                "x:{},y:{} : R:{} G:{} B:{} 缩放比例:{}%".format(self.x, self.y, self.rgb[2], self.rgb[1], self.rgb[0], self.scale_ratio))

    def on_calc_stats(self):
        if(self.img.is_load_image == True):
            self.hist_window = HistView(self.imageview)
            rect = [0, 0, self.img.nowImage.shape[1],
                    self.img.nowImage.shape[0]]
            self.hist_window.update_rect_data(self.img.nowImage, rect)
            self.hist_window.show()
Пример #21
0
class VideoCompareView(object):
    def __init__(self, parent=None):
        self.widget = QWidget()
        self.setting_widget = Ui_video_pre_settings()
        self.setting_widget.setupUi(self.widget)
        self.scene = QGraphicsScene()
        self.imageview = ImageView(self.scene, self.widget)
        self.setting_widget.videoview.addWidget(self.imageview)
        parent.addWidget(self.widget)
        # init params
        self.video_valid = False
        self.process_speed = 33
        self.skip_frames = 0
        self.processing_video = False
        self.video_timer = QTimer()
        self.video_timer.timeout.connect(self.open_frame)
        # init func
        self.setting_widget.openvideo.clicked.connect(self.open_video)
        self.setting_widget.open_rtsp.clicked.connect(self.open_rtsp)
        self.setting_widget.skipframe.valueChanged.connect(self.set_skip_frame)
        self.imageview.sigDragEvent.connect(self.open_video_path)

    def set_skip_frame(self, value):
        # self.skip_frames = self.setting_widget.skipframe.value()
        self.skip_frames = value
        self.vertify_video()

    def open_video(self):
        videopath = QFileDialog.getOpenFileName(None, '打开文件', './',
                                                'video files(*.mp4)')
        if (videopath[0] != ''):
            self.open_video_path(videopath[0])

    def open_video_path(self, string):
        self.setting_widget.path.setText(string)
        self.vertify_video()
        # self.set_ui_enable(True)

    def open_rtsp(self):
        self.rtsp_config_window = QDialog()
        self.rtsp_config_ui = Ui_RtspConfigView()
        self.rtsp_config_ui.setupUi(self.rtsp_config_window)
        self.rtsp_config_window.show()
        self.rtsp_config_ui.buttonBox.clicked.connect(self.rtsp_config)

    def rtsp_config(self):
        username = self.rtsp_config_ui.username.text()
        password = self.rtsp_config_ui.password.text()
        ip = self.rtsp_config_ui.ip.text()
        port = self.rtsp_config_ui.port.text()
        # 移动设备需要通过adb映射端口
        if (self.rtsp_config_ui.isphoto.isChecked() == True):
            command = "forward tcp:" + port + ' ' + "tcp:" + port
            os.system("adb " + command)
            os.system("kdb " + command)
        rtsp_path = "rtsp://" + username + ":" + password + "@" + ip + ":" + port
        self.open_video_path(rtsp_path)

    def vertify_video(self):
        # 输出参数初始化
        # self.frame_count = 0
        self.vidcap = cv2.VideoCapture(self.setting_widget.path.text())
        # 片头调过多少帧
        self.vidcap.set(cv2.CAP_PROP_POS_FRAMES, self.skip_frames)
        success, frame = self.vidcap.read()
        if success:
            self.display(frame)
            self.video_valid = True
        else:
            self.critical_window_show('视频打不开')
            self.video_valid = False
            return

    def display(self, img):
        self.scene.clear()
        self.scene.addPixmap(
            QPixmap(
                QImage(img, img.shape[1], img.shape[0], QImage.Format_BGR888)))

    def open_frame(self):
        success, frame = self.vidcap.read()
        if success:
            # self.frame_count += 1
            self.display(frame)
        else:
            self.video_timer.stop()
            self.processing_video = False
            self.video_valid = False

    def set_speed(self, value):
        speed = value * 33
        if (self.processing_video == True
                and int(speed) != self.process_speed):
            self.process_speed = int(speed)
            self.stop_video()
            self.start_video()

    def start_video(self):
        if (self.video_valid == True):
            self.processing_video = True
            # 增加定时器,每100ms进行一帧的处理
            self.video_timer.start(self.process_speed)

    def stop_video(self):
        self.processing_video = False
        self.video_timer.stop()

    def restart_video(self):
        self.stop_video()
        self.vertify_video()
        self.start_video()

    def critical_window_show(self, str):
        reply = QMessageBox.critical(self.widget, '警告', str, QMessageBox.Yes,
                                     QMessageBox.Yes)
        return
Пример #22
0
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        #Paths
        self.folderPath = "../Crop_Reports/Bengal Crop Reports PNG/"

        self.pixmap = QPixmap()

        #Creates Combobox Choice options
        self.choices = listdir(self.folderPath)

        #Creating widgets
        #Left
        self.choiceCombo = QComboBox()
        self.choiceCombo.addItems(self.choices)
        self.insertionsLabel = QLabel("Insertions")
        self.insertions = QLineEdit("2")
        self.substitutionsLabel = QLabel("Substitutions")
        self.substitutions = QLineEdit("2")
        self.deletionsLabel = QLabel("Deletions")
        self.deletions = QLineEdit("2")
        self.errorsLabel = QLabel("Errors")
        self.errors = QLineEdit("2")
        self.searchTextOutputLabel = QLabel("Search Results")
        self.searchTextOutput = QTextEdit()
        self.searchTextOutput.setReadOnly(True)
        self.searchStringLabel = QLabel("Search for a word")
        self.searchString = QLineEdit()
        self.searchStringButton = QPushButton("Search")
        #middle
        self.nextImage = QPushButton("Next Image")
        self.previousImage = QPushButton("Previous Image")

        self.scene = QGraphicsScene()

        self.image = QGraphicsView(self.scene)
        self.image.show()

        self.zoomIn = QPushButton("Zoom In")
        self.zoomOut = QPushButton("Zoom Out")

        self.left = QVBoxLayout()
        self.left.setMargin(10)
        self.left.addWidget(self.choiceCombo)
        self.left.addWidget(self.insertionsLabel)
        self.left.addWidget(self.insertions)
        self.left.addWidget(self.substitutionsLabel)
        self.left.addWidget(self.substitutions)
        self.left.addWidget(self.deletionsLabel)
        self.left.addWidget(self.deletions)
        self.left.addWidget(self.errorsLabel)
        self.left.addWidget(self.errors)
        self.left.addWidget(self.searchTextOutputLabel)
        self.left.addWidget(self.searchTextOutput)
        self.left.addWidget(self.searchStringLabel)
        self.left.addWidget(self.searchString)
        self.left.addWidget(self.searchStringButton)

        self.middle = QVBoxLayout()
        self.middle.setMargin(10)
        self.middle.addWidget(self.image)
        self.middle.addWidget(self.nextImage)
        self.middle.addWidget(self.previousImage)
        self.middle.addWidget(self.zoomIn)
        self.middle.addWidget(self.zoomOut)

        # QWidget Layout
        self.layout = QHBoxLayout()
        self.layout.addLayout(self.left)
        self.layout.addLayout(self.middle)

        # Set the layout to the QWidget
        self.setLayout(self.layout)

        # Here we connect widgets to functions
        self.searchStringButton.clicked.connect(self.search_data)
        self.nextImage.clicked.connect(self.next_image)
        self.previousImage.clicked.connect(self.previous_image)
        self.zoomIn.clicked.connect(self.zoom_in)
        self.zoomOut.clicked.connect(self.zoom_out)

    # Here we add functions

    @Slot()
    def search_data(self):
        mydata = self.data
        results = (mydata[mydata["word"] == self.searchString.text()])
        output = [
            "(" + word + ", " + img + ") "
            for word, img in zip(results["word"], results["shortName"])
        ]
        print(output)

        #resets search index to 0
        self.searchIndex = 0

        self.searchOutput = results
        print(self.searchOutput)
        self.searchTextOutput.setText(str(output))

    @Slot()
    def next_image(self):
        self.searchIndex += 1

        if self.searchIndex > len(self.searchOutput) - 1:
            self.searchIndex = 0

    @Slot()
    def previous_image(self):
        self.searchIndex -= 1

        if self.searchIndex < 0:
            self.searchIndex = len(self.searchOutput) - 1

    @Slot()
    def zoom_in(self):

        self.scene.clear()
        self.pixmap = self.pixmap.scaled(self.pixmap.size().width() * 1.25,
                                         self.pixmap.size().height() * 1.25,
                                         Qt.KeepAspectRatio)
        self.scene.addPixmap(self.pixmap)

    @Slot()
    def zoom_out(self):

        self.scene.clear()
        self.pixmap = self.pixmap.scaled(self.pixmap.size().width() * 0.8,
                                         self.pixmap.size().height() * 0.8,
                                         Qt.KeepAspectRatio)
        self.scene.addPixmap(self.pixmap)

    @Slot()
    def post_image(self):
        print("filler")
Пример #23
0
class DisplayWidget(QStackedWidget):
    imageClicked = Signal(int, QEvent)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.max_columns = None  # Set when presenter starts # Max cols for multimages
        self.cached_images = {}  # Cache read of image from disk

        self.start()

    def emitter(self, index, event):
        self.imageClicked.emit(index, event)

    def start(self):
        # Layout for single images
        self.single_image = QWidget()
        self.single_image_layout = QGridLayout()
        self.single_image_view = QGraphicsView()
        self.single_image_scene = QGraphicsScene()
        self.single_image_view.setScene(self.single_image_scene)
        self.single_image_layout.addWidget(self.single_image_view)
        self.single_image.setLayout(self.single_image_layout)

        # Layout for multiple images
        self.multiple_image = QWidget()
        self.multiple_image_view_layout = QVBoxLayout()
        self.multiple_image_layout = QGraphicsGridLayout()
        self.multiple_image_view = QGraphicsView()
        self.multiple_image_scene = QGraphicsScene()
        self.multiple_image_view.setScene(self.multiple_image_scene)
        self.panel = QGraphicsWidget()
        self.multiple_image_scene.addItem(self.panel)
        self.multiple_image_view_layout.addWidget(self.multiple_image_view)
        self.panel.setLayout(self.multiple_image_layout)
        self.multiple_image.setLayout(self.multiple_image_view_layout)

        self.addWidget(self.single_image)
        self.addWidget(self.multiple_image)

    def setMaxColumns(self, max_cols):
        self.max_columns = max_cols

    def images_load(self, images):
        """ Take list of images and display in main window """
        num = len(images)
        if num == 0:
            return

        width = self.width()
        maxcol = self.max_columns
        if num < maxcol:
            maxcol = num
        colwidth = width / maxcol

        # Set proper widget for display of multiple or single images
        if num > 1:
            self.setCurrentWidget(self.multiple_image)
            # Clear the layout
            while self.multiple_image_layout.count():
                self.multiple_image_layout.removeAt(0)
            # Clear the scene
            for child in self.panel.childItems():
                child.setParent(None)
        else:
            self.setCurrentWidget(self.single_image)
            self.single_image_scene.clear()
            self.single_image_scene.setSceneRect(
                self.single_image_scene.itemsBoundingRect())

        # Display images or image
        row = 0
        col = -1
        for index, image in images.items():
            col += 1
            if col >= maxcol:
                col = 0
                row += 1

            # Used any cached reads
            if index not in self.cached_images.keys():
                image_reader = QImageReader()
                image_reader.setDecideFormatFromContent(True)
                image_reader.setFileName(image.getFilename())
                self.cached_images[index] = image_reader.read()
            cached_image = self.cached_images[index]

            pixmap = QPixmap(cached_image)
            if num > 1:
                pixmap = pixmap.scaledToWidth(colwidth - 20)
                rec = MultiImageWidget(pixmap, basename(image.getFilename()),
                                       index)
                rec.imageClicked.connect(self.emitter)
                self.multiple_image_layout.addItem(rec, row, col)
            else:
                self.single_image_scene.addPixmap(pixmap)

        adjusted = self.multiple_image_scene.itemsBoundingRect()
        adjusted.adjust(0, 0, 0, 8 * row)
        self.multiple_image_scene.setSceneRect(adjusted)
Пример #24
0
class ImageView(TopicMessageView):
    """
    Popup image viewer
    """
    name = 'Image'

    def __init__(self, timeline, parent, topic):
        super(ImageView, self).__init__(timeline, parent, topic)

        self._image = None
        self._image_topic = None
        self._image_stamp = None
        self.quality = Image.NEAREST  # quality hint for scaling

        # TODO put the image_topic and image_stamp on the picture or display them in some fashion
        self._overlay_font_size = 14.0
        self._overlay_indent = (4, 4)
        self._overlay_color = (0.2, 0.2, 1.0)

        self._image_view = QGraphicsView(parent)
        self._image_view.resizeEvent = self._resizeEvent
        self._scene = QGraphicsScene()
        self._image_view.setScene(self._scene)
        parent.layout().addWidget(self._image_view)

    # MessageView implementation
    def _resizeEvent(self, event):
        # TODO make this smarter. currently there will be no scrollbar even if the timeline extends beyond the viewable area
        self._scene.setSceneRect(0, 0, self._image_view.size().width() - 2, self._image_view.size().height() - 2)
        self.put_image_into_scene()

    def message_viewed(self, bag, msg_details):
        """
        refreshes the image
        """
        TopicMessageView.message_viewed(self, bag, msg_details)
        topic, msg, t = msg_details[:3]
        if not msg:
            self.set_image(None, topic, 'no message')
        else:
            self.set_image(msg, topic, msg.header.stamp)

    def message_cleared(self):
        TopicMessageView.message_cleared(self)
        self.set_image(None, None, None)

    # End MessageView implementation
    def put_image_into_scene(self):
        if self._image:
            resized_image = self._image.resize((self._image_view.size().width() - 2, self._image_view.size().height() - 2), self.quality)

            QtImage = ImageQt(resized_image)
            pixmap = QPixmap.fromImage(QtImage)
            self._scene.clear()
            self._scene.addPixmap(pixmap)

    def set_image(self, image_msg, image_topic, image_stamp):
        self._image_msg = image_msg
        if image_msg:
            self._image = image_helper.imgmsg_to_pil(image_msg)
        else:
            self._image = None
        self._image_topic = image_topic
        self._image_stamp = image_stamp
        self.put_image_into_scene()
Пример #25
0
class AddItem(UsesQApplication):
    '''Tests for QGraphicsScene.add*'''

    qapplication = True

    def setUp(self):
        #Acquire resources
        super(AddItem, self).setUp()
        self.scene = QGraphicsScene()
        # While the scene does not inherits from QWidget, requires
        # an application to make the internals work.

    def tearDown(self):
        #Release resources
        del self.scene
        super(AddItem, self).tearDown()

    def testEllipse(self):
        #QGraphicsScene.addEllipse
        item = self.scene.addEllipse(100, 100, 100, 100)
        self.assertTrue(isinstance(item, QGraphicsEllipseItem))

    def testLine(self):
        #QGraphicsScene.addLine
        item = self.scene.addLine(100, 100, 200, 200)
        self.assertTrue(isinstance(item, QGraphicsLineItem))

    def testPath(self):
        #QGraphicsScene.addPath
        item = self.scene.addPath(QPainterPath())
        self.assertTrue(isinstance(item, QGraphicsPathItem))

    def testPixmap(self):
        #QGraphicsScene.addPixmap
        item = self.scene.addPixmap(QPixmap())
        self.assertTrue(isinstance(item, QGraphicsPixmapItem))

    def testPolygon(self):
        #QGraphicsScene.addPolygon
        points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)]
        item = self.scene.addPolygon(QPolygonF(points))
        self.assertTrue(isinstance(item, QGraphicsPolygonItem))

    def testRect(self):
        #QGraphicsScene.addRect
        item = self.scene.addRect(100, 100, 100, 100)
        self.assertTrue(isinstance(item, QGraphicsRectItem))

    def testSimpleText(self):
        #QGraphicsScene.addSimpleText
        item = self.scene.addSimpleText('Monty Python 42')
        self.assertTrue(isinstance(item, QGraphicsSimpleTextItem))

    def testText(self):
        #QGraphicsScene.addText
        item = self.scene.addText('Monty Python 42')
        self.assertTrue(isinstance(item, QGraphicsTextItem))

    def testWidget(self):
        #QGraphicsScene.addWidget
        # XXX: printing some X11 error when using under PyQt4
        item = self.scene.addWidget(QPushButton())
        self.assertTrue(isinstance(item, QGraphicsProxyWidget))
Пример #26
0
    class QtImageViewer(QGraphicsView):
        """ PyQt image viewer widget for a QPixmap in a QGraphicsView scene with mouse zooming and panning.
        Displays a QImage or QPixmap (QImage is internally converted to a QPixmap).
        To display any other image format, you must first convert it to a QImage or QPixmap.
        Some useful image format conversion utilities:
            qimage2ndarray: NumPy ndarray <==> QImage    (https://github.com/hmeine/qimage2ndarray)
            ImageQt: PIL Image <==> QImage  (https://github.com/python-pillow/Pillow/blob/master/PIL/ImageQt.py)
        Mouse interaction:
            Left mouse button drag: Pan image.
            Right mouse button drag: Zoom box.
            Right mouse button doubleclick: Zoom to show entire image.
        """

        # Mouse button signals emit image scene (x, y) coordinates.
        # !!! For image (row, column) matrix indexing, row = y and column = x.
        leftMouseButtonPressed = Signal(float, float)
        rightMouseButtonPressed = Signal(float, float)
        leftMouseButtonReleased = Signal(float, float)
        rightMouseButtonReleased = Signal(float, float)
        leftMouseButtonDoubleClicked = Signal(float, float)
        rightMouseButtonDoubleClicked = Signal(float, float)

        def __init__(self):
            QGraphicsView.__init__(self)

            # Image is displayed as a QPixmap in a QGraphicsScene attached to this QGraphicsView.
            self.scene = QGraphicsScene()
            self.setScene(self.scene)

            # Store a local handle to the scene's current image pixmap.
            self._pixmapHandle = None

            # Image aspect ratio mode.
            # !!! ONLY applies to full image. Aspect ratio is always ignored when zooming.
            #   Qt.IgnoreAspectRatio: Scale image to fit viewport.
            #   Qt.KeepAspectRatio: Scale image to fit inside viewport, preserving aspect ratio.
            #   Qt.KeepAspectRatioByExpanding: Scale image to fill the viewport, preserving aspect ratio.
            self.aspectRatioMode = Qt.KeepAspectRatio

            # Scroll bar behaviour.
            #   Qt.ScrollBarAlwaysOff: Never shows a scroll bar.
            #   Qt.ScrollBarAlwaysOn: Always shows a scroll bar.
            #   Qt.ScrollBarAsNeeded: Shows a scroll bar only when zoomed.
            self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)

            self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

            # Stack of QRectF zoom boxes in scene coordinates.
            self.zoomStack = []

            # Flags for enabling/disabling mouse interaction.
            self.canZoom = True
            self.canPan = True

        def hasImage(self):
            """ Returns whether or not the scene contains an image pixmap.
            """
            return self._pixmapHandle is not None

        def clearImage(self):
            """ Removes the current image pixmap from the scene if it exists.
            """
            if self.hasImage():
                self.scene.removeItem(self._pixmapHandle)
                self._pixmapHandle = None

        def pixmap(self):
            """ Returns the scene's current image pixmap as a QPixmap, or else None if no image exists.
            :rtype: QPixmap | None
            """
            if self.hasImage():
                return self._pixmapHandle.pixmap()
            return None

        def image(self):
            """ Returns the scene's current image pixmap as a QImage, or else None if no image exists.
            :rtype: QImage | None
            """
            if self.hasImage():
                return self._pixmapHandle.pixmap().toImage()
            return None

        def setImage(self, image):
            """ Set the scene's current image pixmap to the input QImage or QPixmap.
            Raises a RuntimeError if the input image has type other than QImage or QPixmap.
            :type image: QImage | QPixmap
            """
            if type(image) is QPixmap:
                pixmap = image
            elif type(image) is QImage:
                pixmap = QPixmap.fromImage(image)
            else:
                raise RuntimeError(
                    "ImageViewer.setImage: Argument must be a QImage or QPixmap."
                )
            if self.hasImage():
                self._pixmapHandle.setPixmap(pixmap)
            else:
                self._pixmapHandle = self.scene.addPixmap(pixmap)
            self.setSceneRect(QRectF(
                pixmap.rect()))  # Set scene size to image size.
            self.updateViewer()

        def loadImageFromFile(self, fileName):
            """ Load an image from file.
            Without any arguments, loadImageFromFile() will popup a file dialog to choose the image file.
            With a fileName argument, loadImageFromFile(fileName) will attempt to load the specified image file directly.
            """
            if len(fileName) and os.path.isfile(fileName):
                image = QImage(fileName)
                self.setImage(image)

        def updateViewer(self):
            """ Show current zoom (if showing entire image, apply current aspect ratio mode).
            """
            if not self.hasImage():
                return
            if len(self.zoomStack) and self.sceneRect().contains(
                    self.zoomStack[-1]):
                self.fitInView(self.zoomStack[-1], Qt.IgnoreAspectRatio
                               )  # Show zoomed rect (ignore aspect ratio).
            else:
                self.zoomStack = [
                ]  # Clear the zoom stack (in case we got here because of an invalid zoom).
                self.fitInView(
                    self.sceneRect(), self.aspectRatioMode
                )  # Show entire image (use current aspect ratio mode).

        def resizeEvent(self, event):
            """ Maintain current zoom on resize.
            """
            self.updateViewer()

        def wheelEvent(self, event):
            scale_factor = 1.1

            if event.delta() > 0:
                self.scale(scale_factor, scale_factor)
            else:
                self.scale(1 / scale_factor, 1 / scale_factor)

        def mousePressEvent(self, event):
            """ Start mouse pan or zoom mode.
            """
            scenePos = self.mapToScene(event.pos())
            if event.button() == Qt.LeftButton:
                if self.canPan:
                    self.setDragMode(QGraphicsView.ScrollHandDrag)
                self.leftMouseButtonPressed.emit(scenePos.x(), scenePos.y())
            QGraphicsView.mousePressEvent(self, event)

        def mouseReleaseEvent(self, event):
            """ Stop mouse pan or zoom mode (apply zoom if valid).
            """
            QGraphicsView.mouseReleaseEvent(self, event)
            scenePos = self.mapToScene(event.pos())
            if event.button() == Qt.LeftButton:
                self.setDragMode(QGraphicsView.NoDrag)
                self.leftMouseButtonReleased.emit(scenePos.x(), scenePos.y())

        def mouseDoubleClickEvent(self, event):
            """ Show entire image.
            """
            scenePos = self.mapToScene(event.pos())
            if event.button() == Qt.LeftButton:
                self.leftMouseButtonDoubleClicked.emit(scenePos.x(),
                                                       scenePos.y())
            elif event.button() == Qt.RightButton:
                if self.canZoom:
                    self.zoomStack = []  # Clear zoom stack.
                    self.updateViewer()
                self.rightMouseButtonDoubleClicked.emit(
                    scenePos.x(), scenePos.y())

            QGraphicsView.mouseDoubleClickEvent(self, event)
Пример #27
0
    def update_visuals(self):
        """
        This function updates compartment_table, variable_table and also the NetworkX Graph displayed
        """
        # Update compartment_table by iterating through compartment_list
        self.compartment_table.setRowCount(len(self.compartment_list))
        for index, compartment in enumerate(self.compartment_list):
            self.compartment_table.setItem(
                index, 0,
                self.get_uneditable_table_widget_item(
                    compartment.name, compartment.infection_state))
            self.compartment_table.setItem(
                index, 1,
                self.get_uneditable_table_widget_item(compartment.symbol))
            self.compartment_table.setItem(
                index, 2, QTableWidgetItem(
                    f'{compartment.value:.4f}'))  # 3rd column acc 4dp

        # Update variable_table by iterating through variable_list
        self.variable_table.setRowCount(len(self.variable_list))
        for index, variable in enumerate(self.variable_list):
            self.variable_table.setItem(
                index, 0,
                self.get_uneditable_table_widget_item(variable.equation))
            self.variable_table.setItem(
                index, 1,
                self.get_uneditable_table_widget_item(
                    str(variable.origin.name) if variable.
                    origin is not None else "-"))  # Birth is a -
            self.variable_table.setItem(
                index, 2,
                self.get_uneditable_table_widget_item(
                    str(variable.end.name) if variable.end is not None else "-"
                ))  # Death is a -

        # Create NetworkX graph
        G = nx.DiGraph()
        edges = list()
        labels = dict()
        for variable in self.variable_list:  # Set labels = {[Source Node1, End Node1]: Latex Equation1, ...}
            se_list = [
                variable.origin.name
                if variable.origin is not None else 'Birth',
                variable.end.name if variable.end is not None else 'Death'
            ]
            edges.append(se_list)
            labels[tuple(se_list)] = "${}$".format(latex(variable.equation))

        G.add_edges_from(edges)
        pos = nx.planar_layout(G)  # Planar layout so edges do not collide
        plt.figure()  # Start a figure before drawing
        nx.draw(G,
                pos,
                edge_color='black',
                node_size=2000,
                node_shape='s',
                node_color='white',
                with_labels=True,
                style='bold')
        nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
        plt.savefig(
            'graph.png'
        )  # Save as graph.png so QPixmap can be created from it below
        plt.close()  # Close plt to save memory and prevent issues downline

        scene = QGraphicsScene()
        scene.addPixmap(QPixmap('graph.png'))
        self.diagram_view.setScene(
            scene)  # DiagramView is set to be the graph.png
        self.diagram_view.show()
Пример #28
0
class AddItem(UsesQApplication):
    '''Tests for QGraphicsScene.add*'''

    qapplication = True

    def setUp(self):
        #Acquire resources
        super(AddItem, self).setUp()
        self.scene = QGraphicsScene()
        # While the scene does not inherits from QWidget, requires
        # an application to make the internals work.

    def tearDown(self):
        #Release resources
        del self.scene
        super(AddItem, self).tearDown()

    def testEllipse(self):
        #QGraphicsScene.addEllipse
        item = self.scene.addEllipse(100, 100, 100, 100)
        self.assertTrue(isinstance(item, QGraphicsEllipseItem))

    def testLine(self):
        #QGraphicsScene.addLine
        item = self.scene.addLine(100, 100, 200, 200)
        self.assertTrue(isinstance(item, QGraphicsLineItem))

    def testPath(self):
        #QGraphicsScene.addPath
        item = self.scene.addPath(QPainterPath())
        self.assertTrue(isinstance(item, QGraphicsPathItem))

    def testPixmap(self):
        #QGraphicsScene.addPixmap
        item = self.scene.addPixmap(QPixmap())
        self.assertTrue(isinstance(item, QGraphicsPixmapItem))

    def testPolygon(self):
        #QGraphicsScene.addPolygon
        points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)]
        item = self.scene.addPolygon(QPolygonF(points))
        self.assertTrue(isinstance(item, QGraphicsPolygonItem))

    def testRect(self):
        #QGraphicsScene.addRect
        item = self.scene.addRect(100, 100, 100, 100)
        self.assertTrue(isinstance(item, QGraphicsRectItem))

    def testSimpleText(self):
        #QGraphicsScene.addSimpleText
        item = self.scene.addSimpleText('Monty Python 42')
        self.assertTrue(isinstance(item, QGraphicsSimpleTextItem))

    def testText(self):
        #QGraphicsScene.addText
        item = self.scene.addText('Monty Python 42')
        self.assertTrue(isinstance(item, QGraphicsTextItem))

    def testWidget(self):
        #QGraphicsScene.addWidget
        # XXX: printing some X11 error when using under PyQt4
        item = self.scene.addWidget(QPushButton())
        self.assertTrue(isinstance(item, QGraphicsProxyWidget))
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        #Paths
        self.folderPath = "../Crop_Reports/Bengal Crop Reports PNG/"
        self.index = 0
        self.page_index = 0
        self.crop_report = ""
        self.pixmap = QPixmap()

        self.data = pd.read_csv("../Crop_Reports/Manual Check Crop Reports/crop_reports_verified.csv")

        #choices
        self.choices = listdir(self.folderPath)




        self.scene = QGraphicsScene()
        self.image = QGraphicsView(self.scene)
        self.image.show()
        self.submitButton = QPushButton("Submit")
        self.dateText = QLineEdit("")



        self.middle = QVBoxLayout()
        self.middle.setMargin(10)
        self.middle.addWidget(self.image)

        self.middle.addWidget(self.dateText)
        self.middle.addWidget(self.submitButton)


        # QWidget Layout
        self.layout = QHBoxLayout()
        self.layout.addLayout(self.middle)



        # Set the layout to the QWidget
        self.setLayout(self.layout)

        # Here we connect widgets to functions
        self.submitButton.clicked.connect(self.submit)


    # Here we add functions

    @Slot()
    def submit(self):
        self.index = self.index+1
        self.scene.clear()

        temp_path = self.choices[self.index]
        self.crop_report_pages = os.listdir(temp_path)

        self.pixmap = QPixmap(temp_path)
        self.scene.addPixmap(self.pixmap)

    @Slot()
    def nextPage(self):
        self.page_index = self.page_index + 1
Пример #30
0
class ImageView(QGraphicsView):
	# Tell PageWidget that a file is dropped onto view.
	dropped_relay = Signal(QDropEvent)

	def __init__(self, image_path):
		super(ImageView, self).__init__(None)
		self.scene = QGraphicsScene()
		self.setScene(self.scene)
		self.pixmapitem = self.scene.addPixmap(QPixmap.fromImage(QImage(image_path)))
		self.last_release_time = 0
		self.watcher = QFileSystemWatcher()
		self.watcher.fileChanged.connect(self.refresh_image)
		# Register file watcher
		self.watcher.addPath(image_path)

	def dragEnterEvent(self, drag_enter_event): # QDragEnterEvent
		if drag_enter_event.mimeData().hasUrls():
			drag_enter_event.acceptProposedAction()

	# https://stackoverflow.com/a/4421835/4112667
	def dragMoveEvent(self, event):
		pass

	def dropEvent(self, drop_event): # QDropEvent
		self.dropped_relay.emit(drop_event)

	'''
	When overwriting an image file, I guess Windows will delete it and then create
	a new file with the same name. So this function will be called twice. The first
	round is triggered by deleting. In this case, the image file doesn't exist, so
	QImage and QPixmap are all invalid and as a result, the view will become white
	background. Only after the image being created and the function is called for
	the second time, will the view show the image normally. The User will notice a
	white flicker because of two rounds of callings. To resolve this problem, we
	need to detect the invalid QImage or QPixmap and skip the unintended round.
	'''
	def refresh_image(self, image_path):
		qimage = QImage(image_path)
		if qimage.isNull():
			return
		pixmap = QPixmap.fromImage(qimage)
		self.scene.removeItem(self.pixmapitem)
		self.pixmapitem = self.scene.addPixmap(pixmap)
		# This will make scrollbar fit the image
		self.setSceneRect(QRectF(pixmap.rect()))

	def mousePressEvent(self, mouse_event): # QMouseEvent
		if mouse_event.button() == Qt.LeftButton:
			self.setDragMode(QGraphicsView.ScrollHandDrag)
		elif mouse_event.button() == Qt.RightButton:
			self.setDragMode(QGraphicsView.RubberBandDrag)
		QGraphicsView.mousePressEvent(self, mouse_event)

	def mouseReleaseEvent(self, mouse_event): # QMouseEvent
		QGraphicsView.mouseReleaseEvent(self, mouse_event)
		if mouse_event.button() == Qt.LeftButton:
			self.setDragMode(QGraphicsView.NoDrag)
		elif mouse_event.button() == Qt.RightButton:
			self.setDragMode(QGraphicsView.NoDrag)

			now = time.time()
			delta = now - self.last_release_time
			self.last_release_time = now
			if delta < 0.3: # fast double click
				self.resetTransform() # Reset to original size (reset scale matrix)
				return
			# Maybe a selection
			selection = self.scene.selectionArea().boundingRect()
			self.scene.setSelectionArea(QPainterPath())
			if selection.isValid():
				self.fitInView(selection, Qt.KeepAspectRatio)

	def wheelEvent(self, wheel_event): # QWheelEvent
		num_degrees = wheel_event.angleDelta().y() / 8
		num_steps = num_degrees / 15
		coefficient = 1 + (num_steps * 0.25)
		self.scale(coefficient, coefficient)
Пример #31
0
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.x1 = ""
        self.x3 = ""
        self.y1 = ""
        self.y3 = ""

        self.scene = QGraphicsScene()
        self.image = QGraphicsView(self.scene)
        self.image.show()
        self.submitButton = QPushButton("Submit")
        self.undoButton = QPushButton("Undo")
        self.nextReport = QPushButton("Next Report")
        self.districtText = QLineEdit("")
        self.prevPageButton = QPushButton("Previous Page")
        self.nextPageButton = QPushButton("Next Page")
        self.middle = QVBoxLayout()
        self.left = QHBoxLayout()
        self.middle.setMargin(10)
        self.middle.addWidget(self.image)
        self.middle.addLayout(self.left)
        self.bottom = QHBoxLayout()
        self.left.addWidget(self.prevPageButton)
        self.left.addWidget(self.nextPageButton)
        self.middle.addWidget(self.districtText)
        self.bottom.addWidget(self.nextReport)
        self.bottom.addWidget(self.undoButton)
        self.bottom.addWidget(self.submitButton)
        self.middle.addLayout(self.bottom)

        # QWidget Layout

        self.layout = QHBoxLayout()
        self.layout.addLayout(self.middle)

        # Set the layout to the QWidget
        self.setLayout(self.layout)

        # second
        # self.data_path = "../Crop_Reports/Manual Check Crop Reports/crop_reports_verified.csv"
        # self.data = pd.read_csv(self.data_path)
        self.dir_path = "../Crop_Reports/Bengal Crop Reports PNG/"
        # connect functions
        self.nextReport.clicked.connect(self.ignore)
        self.submitButton.clicked.connect(self.submit)
        self.undoButton.clicked.connect(self.undo)
        self.nextPageButton.clicked.connect(self.nextImage)
        self.prevPageButton.clicked.connect(self.prevImage)

        self.crop_index = 0
        self.page_index = 0
        self.zoom = .125

        self.out_folder = "../Crop_Reports/Bengal Crop Reports OCR Bounds/"
        self.finished = os.listdir(self.out_folder)
        self.data = pd.read_csv(
            "../Crop_Reports/Manual Check Crop Reports/crop_reports_verified_cleaned_is_good.csv"
        )
        self.data.Date = pd.to_datetime(self.data.Date)
        self.data = self.data[(self.data.Date > start_date)
                              & (self.data.Date < end_date)]

        self.columns = ["District", "x1", "y1", "x3", "y3", "Date", "Raw_Text"]
        self.bound_data = pd.DataFrame(columns=self.columns)
        self.bound_data_text = ""

        self.ocr_data_list = list()

        data = self.data
        for string in self.finished:
            string = string.split(".")[0]
            data = data[data.Path != string]

        self.reports = list(data.Path)
        self.dates = list(data.Date)
        print(u"Data index:", data.index)

        self.remain_string = "remaining folders " + str(len(self.reports))
        self.remainingLabel = QLabel(self.remain_string)
        self.left.addWidget(self.remainingLabel)

        temp_path = os.path.join(self.dir_path, self.reports[self.crop_index])
        self.report = os.listdir(temp_path)
        self.postImage()

        # Sets up drawing capabilities:
        self.image.setMouseTracking(True)
        self.image.viewport().installEventFilter(self)
        self.start = None
        self.end = None

    # error here, disregarded bc why not? :)
    def eventFilter(self, source, event):
        if event.type(
        ) == QtCore.QEvent.MouseButtonPress and source is self.image.viewport(
        ):
            if self.start is None:
                self.start = event.pos()
            elif self.end is None:
                self.end = event.pos()
                self.draw_bounding_box()
            else:
                print("ERROR!")
            #print(event.pos())
            #print(self.image.mapToScene(event.pos()))

    @Slot()
    def submit(self):
        self.postImage()

        ["District", "x1", "y1", "x3", "y3", "Date", "Raw_Text"]
        row = {
            'District': self.districtText.text(),
            'x1': self.x1,
            'y1': self.y1,
            'x3': self.x3,
            'y3': self.y3,
            'Date': self.date,
            'Raw_Text': self.bound_data_text
        }
        self.bound_data = self.bound_data.append(row, ignore_index=True)
        print(self.bound_data)

        self.districtText.setText("")

    @Slot()
    def undo(self):
        print(self.bound_data)
        self.bound_data.drop(self.bound_data.tail(1).index, inplace=True)
        print(self.bound_data)

    @Slot()
    def ignore(self):
        self.remain_string = "remaining folders " + str(
            len(self.reports) - self.crop_index - 1)
        self.remainingLabel.setText(self.remain_string)

        path = self.out_folder + self.reports[self.crop_index] + ".csv"
        print(u"out path:", path)

        self.bound_data.to_csv(path, index=False)
        self.bound_data = pd.DataFrame(columns=self.columns)

        self.crop_index = self.crop_index + 1
        self.page_index = 0
        self.postImage()

    @Slot()
    def nextImage(self):
        if ((len(self.report) - 1) > self.page_index):
            self.page_index = self.page_index + 1
        else:
            self.page_index = 0

        self.postImage()

    @Slot()
    def prevImage(self):
        if (1 > self.page_index):
            self.page_index = len(self.report) - 1
        else:
            self.page_index = self.page_index - 1

        self.postImage()

    def postImage(self):
        self.date = self.dates[self.crop_index]
        print(u"Date:", self.date)
        print(self.dates)
        temp_path = os.path.join(self.dir_path, self.reports[self.crop_index])
        report = os.listdir(temp_path)
        dt.sort_nicely(report)
        self.report = report
        self.ocr_data_list = dt.report_to_data(self.reports[self.crop_index])

        if (len(self.report) > 0):
            self.page = self.report[self.page_index]
            self.page_df = self.ocr_data_list[self.page_index]
            temp_path = os.path.join(self.dir_path,
                                     self.reports[self.crop_index], self.page)
            self.scene.clear()
            self.pixmap = QPixmap(temp_path)
            # adjusts zoom
            self.pixmap = self.pixmap.scaled(
                self.pixmap.size().width() * self.zoom,
                self.pixmap.size().height() * self.zoom, Qt.KeepAspectRatio)
            self.scene.addPixmap(self.pixmap)

    # def draw_bounding_box(self, x1, y1, x3, y3):
    #
    #     start = self.image.mapToScene(x1,y1)
    #     end = self.image.mapToScene(x3,y3)
    #     len_x = end.x()-start.x()
    #     len_y = end.y()-start.y()
    #     rectItem = QGraphicsRectItem(start.x(), start.y(), len_x, len_y)
    #     self.scene.addItem(rectItem)

    def draw_bounding_box(self):
        #self.item = QGraphicsPixmapItem(QPixmap(self.df["image"].iloc[self.index]))
        #self.scene.addItem(self.item)
        start = self.image.mapToScene(self.start)
        end = self.image.mapToScene(self.end)
        self.startSceneLoc = start
        self.endSceneLoc = end

        df = self.page_df

        scale = (1 / self.zoom)
        self.x1 = start.x() * scale
        #self.x3 = end.x()*scale
        #Fixed x length
        self.x3 = self.x1 + 250 * scale

        self.y1 = start.y() * scale
        self.y3 = end.y() * scale
        df = df[(df.x1 > self.x1) & (df.x3 < self.x3) & (df.y1 > self.y1) &
                (df.y3 < self.y3)]
        print(u"x1:", self.x1, u" x3:", self.x3, u" y1:", self.y1, u" y3:",
              self.y3, u" Scale:", scale)
        print(u"Current image:", self.report[self.page_index],
              u" Current df image:", df.image.unique())
        print(df.word)
        self.bound_data_text = " ".join(df.word.to_list())

        diff_x = (self.x1 - self.x3) * self.zoom
        diff_y = (self.y1 - self.y3) * self.zoom

        rectItem = QGraphicsRectItem(start.x(), start.y(), -diff_x, -diff_y)
        self.scene.addItem(rectItem)

        self.start = None
        self.end = None

    # def write_to_csv(self):
    #     new_row = {'ocr_report_path': self.reports[self.crop_index], 'date': self.districtText.text()}
    #     self.data = self.data.append(new_row, ignore_index=True)
    #     self.data.to_csv(self.data_path, index=False)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Return:
            self.submit()
Пример #32
0
class QGameOfLife(QWidget):

    Games = {
        "Game of Life": (GameOfLife, {
            'fill_rate': 0.50
        }),
        "Bacteria": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.035, 0.065)
        }),
        "Coral": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.062, 0.062)
        }),
        "Fingerprint": (GrayScottDiffusion, {
            'coeffs': (0.19, 0.05, 0.060, 0.062)
        }),
        "Spirals": (GrayScottDiffusion, {
            'coeffs': (0.10, 0.10, 0.018, 0.050)
        }),
        "Unstable": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.020, 0.055)
        }),
        "Worms": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.050, 0.065)
        }),
        "Zebrafish": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.035, 0.060)
        }),
    }

    def __init__(self, size=(400, 400)):
        super(QGameOfLife, self).__init__()
        self.size = size
        self.game = None
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Game of Life"))
        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.comboBox = QComboBox()
        self.comboBox.addItems([*QGameOfLife.Games.keys()])
        self.comboBox.currentTextChanged.connect(self.select)
        self.layout().addWidget(self.comboBox)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setSizePolicy(
            QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        self.view.setFrameShape(QFrame.NoFrame)
        self.layout().addWidget(self.view)

        self.item = None
        self.timer = QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.tick)
        initialGame = random.choice([*QGameOfLife.Games.keys()])
        self.select(initialGame)
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)
        self.comboBox.setCurrentText(initialGame)

    def select(self, name: str):
        self.timer.stop()
        Game, args = QGameOfLife.Games[name]
        self.game = Game(self.size, **args)
        self.tick()
        self.timer.start()

    def tick(self):
        self.game.tick()
        bitmap = self.game.visualize()
        image = QImage(bitmap.data, bitmap.shape[1], bitmap.shape[0],
                       QImage.Format_Grayscale8)
        self.scene.removeItem(self.item)
        pixmap = QPixmap.fromImage(image)
        self.item = self.scene.addPixmap(pixmap)

    def resizeEvent(self, event: QResizeEvent):
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)

    def sizeHint(self) -> QSize:
        return QSize(self.size[0], self.size[1])