numpy 如何在PyQt5中裁剪实时视频提要?QImage看起来被剪切

nhjlsmyf  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(231)

我有一个PyQt5 GUI应用程序。我从相机中读取一个帧以选择其上的一个较小区域,稍后我想只显示该区域。我正确地选择了区域,并将其存储在QRect中。但是当我尝试裁剪帧以显示并稍后处理时,显示的实时视频有时会正确工作。但大多数时候它看起来像这张照片。它变得倾斜,右角应该是左角。而且粉红色的圆圈应该在视频的中间,所以有点不对。

我有一个Worker1类,在这里我处理显示的帧。

class Worker1(QThread):
    ImageUpdate = pyqtSignal(QImage)

    def __init__(self, canvas, selection):
        super().__init__()
        self.ThreadActive = True
        self.canvas = canvas
        self.anim = None
        self.selection = selection

    def run(self):
        Capture = cv.VideoCapture(0)

        old_closest_contour = None
        d_tresh = 300
        P_color = (0, 255, 0)
        global i
        i = 0

        while self.ThreadActive:
            i += 1
            ret, frame = Capture.read()
            if ret:
                if self.selection is None or self.selection.isEmpty():
                    cropped_frame = frame
                else:
                    a = int(self.selection.x())
                    b = int(self.selection.y())
                    width = int(self.selection.width())
                    height = int(self.selection.height())
                    #print(str(a) + " " + str(b) + " " + str(width) + " " + str(height))
                    cropped_frame = frame[b: b + height, a: a + width].copy()
                    #print(cropped_frame.shape[1])
                    #print(cropped_frame.shape[0])

                ### other processing lines, those are not relevant in the displaying ###

                Image = cv.cvtColor(cropped_frame, cv.COLOR_BGR2RGB)
                img = cv.medianBlur(Image, 25)

                cv.circle(img, (x, y), r, P_color, 1)
                cv.circle(img, (x, y), 4, P_color, -1)
                cv.circle(img, point, 0, (255, 0, 255), 10)

                ConvertToQtFormat = QImage(img.data, img.shape[1], img.shape[0], QImage.Format_RGB888)
                self.ImageUpdate.emit(ConvertToQtFormat)

        Capture.release()
nqwrtyyt

nqwrtyyt1#

我们必须设置bytesPerLine参数。
ConvertToQtFormat = QImage(img.data, img.shape[1], img.shape[0], QImage.Format_RGB888)替换为:

ConvertToQtFormat = QImage(img.data, img.shape[1], img.shape[0], img.strides[0], QImage.Format_RGB888)

img.strides[0]应用img的每行中的字节数。
img.shape[1] = 100img.strides[0]通常等于100*3 = 300字节时,每个像素有3个字节。
我们使用strides的原因是,在内存中存在行不连续的情况,并且步幅不等于宽度 * 3。
QImage对象中的等效参数是bytesPerLine
默认情况下,QImage对象假设bytesPerLine是4**的 * 倍数。
在width*3不是4的倍数的情况下,假设填充字节存在于每行的末尾。
例如,当width = 101时,bytesPerLine是304而不是303(假设1个填充字节)。
(The 4的倍数假设源自BMP image format)。
在我们的案例中:

  • img.shape[1]是4的倍数时,图像看起来是正确的。
  • img.shape[1]不是4的倍数时,图像将“倾斜”。

在我们的例子中,NumPy数组没有填充字节,Qt bytesPerLine和NumPy strides之间不匹配。
解决方案是设置bytesPerLine参数(使用重载的QImage构造函数)。
一般来说,当从NumPy转换为QImage时,我们应该将img.strides[0]设置为bytesPerLine参数。

相关问题