我有一个PyQt5图形用户界面应用程序.我从相机中读取一个帧,以在其上 Select 一个较小的区域,稍后我只想显示该区域.我正确地 Select 了该区域,并将其存储在QRect中.但当我试图裁剪要显示的帧并稍后进行处理时,显示的实时视频有时会正常工作.但大多数情况下,它看起来就像这张照片上的那样.它变得倾斜了,右角应该是左角.粉红色的圆圈应该在视频的中间,所以它有点错误.

Image example

我有这个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()

推荐答案

We have to set bytesPerLine argument.
Replace ConvertToQtFormat = QImage(img.data, img.shape[1], img.shape[0], QImage.Format_RGB888) with:

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

img.strides[0] applies the number of bytes in each line of img.
When img.shape[1] = 100, img.strides[0] is usually equal 100*3 = 300 bytes when there are 3 bytes per pixel.

我们有strides的原因是,有些情况下,记忆中的线条不连续,步幅不等于宽度*3.

The equivalent parameter in QImage object is bytesPerLine.
By default, QImage object assumes that bytesPerLine is a multiple of 4.
In case width*3 is not a multiple of 4, padding bytes are assumed to be present at the end of each line.
For example, when width = 101, bytesPerLine is 304 instead of 303 (1 padding byte is assumed).
(The multiple of 4 assumption is originated from the BMP image format).

在我们的 case 中:

  • img.shape[1]是4的倍数时,图像看起来是正确的.
  • When img.shape[1] is a not multiple of 4, the image is going to be "slanted".
    In our case the NumPy array has no padding bytes, and there is a mismatch between Qt bytesPerLine and NumPy strides.

The solution is setting the bytesPerLine parameter (using an overloaded QImage constructor).
In general, when converting from NumPy to QImage, we should set img.strides[0] as bytesPerLine argument.

Python相关问答推荐

如何终止带有队列的Python进程?+ 队列大小的错误?

无法使用equals_html从网址获取全文

如何在Deliveryter笔记本中从同步上下文正确地安排和等待Delivercio代码中的结果?

Pandas 滚动最接近的价值

通过Selenium从页面获取所有H2元素

管道冻结和管道卸载

如何列举Pandigital Prime Set

如何在python xsModel库中定义一个可选[December]字段,以产生受约束的SON模式

对所有子图应用相同的轴格式

如何使用Python以编程方式判断和检索Angular网站的动态内容?

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

SQLAlchemy bindparam在mssql上失败(但在mysql上工作)

考虑到同一天和前2天的前2个数值,如何估算电力时间序列数据中的缺失值?

如何使用OpenGL使球体遵循Python中的八样路径?

从源代码显示不同的输出(机器学习)(Python)

jsonschema日期格式

如何从比较函数生成ngroup?

有没有办法在不先将文件写入内存的情况下做到这一点?

如何使用加速广播主进程张量?

利用SCIPY沿第一轴对数组进行内插