python - opencv BGR 图像和它的反向版本 RGB 图像 [:,:,::-1] 有什么区别?

标签 python opencv pyqt qimage

我正在尝试显示带有 QLabel 的 opencv 图像。我有两个不同版本的图像,第一个是 opencv BGR 图像,第二个是使用 image[:,:,::-1] 的 RGB 图像,BGR 版本工作正常但 RGB 版本不工作.

下面的代码工作正常

src = cv.imread('image.jpg')
h,w,ch = src.shape
bytesPerLine = ch * w
qImg = QImage(src.data, w, h, bytesPerLine, QImage.Format_RGB888)
qImg = qImg.rgbSwapped()
self.ui.label.setPixmap(QPixmap.fromImage(qImg))


这些代码不起作用:

src = cv.imread('image.jpg')
src = src[:,:,::-1]
h,w,ch = src.shape
bytesPerLine = ch * w
qImg = QImage(src.data, w, h, bytesPerLine, QImage.Format_RGB888)
self.ui.label.setPixmap(QPixmap.fromImage(qImg))

最佳答案

正如您所注意到的,opencv 以 BGR 格式读取图像,而以 RGB 格式读取 QImage,在您的第一种方法中,您在不进行转换的情况下转换为 QImage,然后使用 rgbSwapped() 方法进行转换.

通过测试我得到的第一种方法:

1000 loops, best of 5: 291 usec per loop

在第二种方法中,您尝试在将其转换为 QImage 之前执行此操作,但是当我执行它时,假设您也得到了它,我会收到以下错误。

Traceback (most recent call last):
  File "xxxx.py", line 18, in <module>
    qImg = QtGui.QImage(src.data, w, h, bytesPerLine, QtGui.QImage.Format_RGB888)
TypeError: arguments did not match any overloaded call:
  QImage(): too many arguments
  QImage(QSize, QImage.Format): argument 1 has unexpected type 'memoryview'
  QImage(int, int, QImage.Format): argument 1 has unexpected type 'memoryview'
  QImage(bytes, int, int, QImage.Format): argument 1 has unexpected type 'memoryview'
  QImage(sip.voidptr, int, int, QImage.Format): argument 1 has unexpected type 'memoryview'
  QImage(bytes, int, int, int, QImage.Format): argument 1 has unexpected type 'memoryview'
  QImage(sip.voidptr, int, int, int, QImage.Format): argument 1 has unexpected type 'memoryview'
  QImage(List[str]): argument 1 has unexpected type 'memoryview'
  QImage(str, format: str = None): argument 1 has unexpected type 'memoryview'
  QImage(QImage): argument 1 has unexpected type 'memoryview'
  QImage(Any): too many arguments

这是因为 numpy 使用 memoryview 来优化某些任务。在这种情况下,当执行 src[:,:,::-1] 时,一种优化方法不是修改数据而是访问数据的方式,这是通过 Buffer Protocol 完成的。 .

在这种情况下,QImage 不支持这种类型的数据,因此解决方案是使用 tobytes() 访问字节。或 bytes():

import cv2
from PyQt5 import QtGui, QtWidgets

if __name__ == '__main__':
    import sys
    src = cv2.imread('image.jpg')
    src = src[:,:,::-1]
    h, w, ch = src.shape
    bytesPerLine = ch * w
    qImg = QtGui.QImage(src.data.tobytes(), w, h, bytesPerLine, QtGui.QImage.Format_RGB888)
    # Or
    # qImg = QtGui.QImage(bytes(src.data), w, h, bytesPerLine, QtGui.QImage.Format_RGB888)
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QLabel()
    w.setPixmap(QtGui.QPixmap.fromImage(qImg))
    w.show()
    sys.exit(app.exec_())

时间:

500 loops, best of 5: 523 usec per loop

另一种解决方案是使用opencv的cvtColor()函数,如果修改数据:

import cv2
from PyQt5 import QtGui, QtWidgets

if __name__ == '__main__':
    import sys
    src = cv2.imread('image.jpg')
    src = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
    h, w, ch = src.shape
    bytesPerLine = ch * w
    qImg = QtGui.QImage(src.data, w, h, bytesPerLine, QtGui.QImage.Format_RGB888)
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QLabel()
    w.setPixmap(QtGui.QPixmap.fromImage(qImg))
    w.show()
    sys.exit(app.exec_())

时间:

1000 loops, best of 5: 263 usec per loop

关于python - opencv BGR 图像和它的反向版本 RGB 图像 [:,:,::-1] 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55468135/

相关文章:

python - 多重处理 python 方法

python - 我可以将 2 字节大小的变量作为 1 字节大小的变量发送吗?

python - OpenCV检测摄像头但不返回图像提要,而guvcview却

python - 导入错误 : cannot import name QtGui

Python 请求使用 ast.literal_eval 错误语法无效?

python - 如何从包含 munch 的字典中编写 YAML,而不使用 "!munch.Munch"?

python-3.x - 试试,除了,再试一次?

java - 在 JNI 中修改的 Mat 不反射(reflect)在 Java 中的更改

python - 在 PyQT4 中上下移动行

python - PyQt4:使用 QVariantAnimation 在两个值之间设置动画