我正在动态调整通过OpenCV从网络摄像头收到的图像帧的大小,但是它显示了失真的图像。
给出下面的代码和ui文件。 要调整大小,请按住鼠标右键并拖动。
我试图将分辨率设为偶数,例如如果分辨率为623x420,那么我会将其转换为624x420。这减少了加扰,但是对于某些大小仍然会发生。尝试添加等待键,但没有效果。 尝试使用视频文件而不是网络摄像头,结果是相同的。
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
import cv2
from we import Ui_MainWindow
class MainWindow_exec(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.fps=24
self.start_camera()
self.rightClick=None
self.x = 600
self.y = 400
def mousePressEvent(self, QMouseEvent):
self.timer.stop()
self.press = QMouseEvent.pos()
if QMouseEvent.button() == QtCore.Qt.RightButton:
self.rdragx = QMouseEvent.x()
self.rdragy = QMouseEvent.y()
self.currentx = self.width()
self.currenty = self.height()
self.rightClick = True
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton:
globalPos = event.globalPos()
self.move(globalPos-self.press)
if self.rightClick == True:
self.x = self.currentx + event.x() - self.rdragx
self.y = self.currenty + event.y() - self.rdragy
self.resize(self.x, self.y)
self.label.setFixedSize(self.x, self.y)
def mouseReleaseEvent(self, event):
self.rightClick = False
self.timer.start(1000./self.fps)
def next_frame(self):
ret, frame = self.cap.read()
frame = cv2.resize(frame,(self.x,self.y ))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
pix = QtGui.QPixmap.fromImage(img)
self.label.setPixmap(pix)
def start_camera(self):
self.cap = cv2.VideoCapture(0)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.next_frame)
self.timer.start(1000./self.fps)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow1 = MainWindow_exec()
MainWindow1.show()
sys.exit(app.exec_())
UI文件we.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(532, 353)
MainWindow.setWindowOpacity(1.0)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setStyleSheet("background:grey")
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
答案 0 :(得分:0)
问题在于QImage
期望数据行被填充4字节。
将此添加到文件的开头
import numpy as np
def padded_row(row_size, padding=4):
return (row_size + padding - 1) // padding * padding
在将边框传递给QImage
之前,将边框添加到边框:
def next_frame(self):
ret, frame = self.cap.read()
frame = cv2.resize(frame,(self.x,self.y ))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
padded_frame = np.zeros((padded_row(self.x * 3), self.y), 'u1')
padded_frame[:self.x * 3, :] = frame
frame = padded_frame
img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
pix = QtGui.QPixmap.fromImage(img)
self.label.setPixmap(pix)