Reputation: 7304
I am displaying webcam image from cv2 on QPixmap.
I have PyQt5 and Python2.7.
Now the issue is the display size doesn't change with Window size.
I like to change image size together with display window size.
Now is always 640x480.
Attached images show image size is fixed. I like to have just slightly smaller than window size and change together with window size.
My code is as follow.
from PyQt5 import QtCore, QtGui, QtWidgets
import cv2
class Thread(QtCore.QThread):
changePixmap = QtCore.pyqtSignal(QtGui.QImage)
def run(self):
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if ret:
print(frame.shape)
rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
convertToQtFormat = QtGui.QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QtGui.QImage.Format_RGB888)
p = convertToQtFormat.scaled(640, 480, QtCore.Qt.KeepAspectRatio)
self.changePixmap.emit(p)
class PlayStreaming(QtWidgets.QWidget):
def __init__(self):
super(PlayStreaming,self).__init__()
self.initUI()
@QtCore.pyqtSlot(QtGui.QImage)
def setImage(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
def initUI(self):
self.setWindowTitle("Image")
# create a label
self.label = QtWidgets.QLabel(self)
th = Thread(self)
th.changePixmap.connect(self.setImage)
th.start()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
class UIWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(UIWidget, self).__init__(parent)
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
# Add tabs
self.tabs.addTab(self.tab1,"Face")
self.tabs.addTab(self.tab2,"Human")
self.tabs.addTab(self.tab3,"Vehicle")
# Create first tab
self.createGridLayout()
self.tab1.layout = QtWidgets.QVBoxLayout()
self.display = PlayStreaming()
self.tab1.layout.addWidget(self.display, stretch=1)
self.tab1.layout.addWidget(self.horizontalGroupBox)
self.tab1.setLayout(self.tab1.layout)
# Add tabs to widget
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tabs)
def createGridLayout(self):
self.horizontalGroupBox = QtWidgets.QGroupBox("Control")
self.horizontalGroupBox.setStyleSheet("QGroupBox { background-color: red}");
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QPushButton('Test'),0,0)
layout.addWidget(QtWidgets.QPushButton('Run'),0,1)
layout.addWidget(QtWidgets.QPushButton('Set Faces'),0,2)
layout.addWidget(QtWidgets.QPushButton('Recognize'),1,0)
layout.addWidget(QtWidgets.QPushButton('Rescale'),1,1)
layout.addWidget(QtWidgets.QPushButton('FacePose'),1,2)
self.horizontalGroupBox.setLayout(layout)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = UIWidget()
w.resize(1000, 800)
w.show()
sys.exit(app.exec_())
Upvotes: 1
Views: 6143
Reputation: 505
You can listen to the resize event of PlayStreaming and send the adjusted size to the thread through the signal for scaling.
from PyQt5 import QtCore, QtGui, QtWidgets
import cv2
class Thread(QtCore.QThread):
changePixmap = QtCore.pyqtSignal(QtGui.QImage)
scaled_size = QtCore.QSize(640, 480)
def run(self):
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if ret:
print(frame.shape)
rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
convertToQtFormat = QtGui.QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QtGui.QImage.Format_RGB888)
p = convertToQtFormat.scaled(self.scaled_size, QtCore.Qt.KeepAspectRatio)
self.changePixmap.emit(p)
def scaled(self, scaled_size):
self.scaled_size = scaled_size
class PlayStreaming(QtWidgets.QLabel):
reSize = QtCore.pyqtSignal(QtCore.QSize)
def __init__(self):
super(PlayStreaming, self).__init__()
self.initUI()
@QtCore.pyqtSlot(QtGui.QImage)
def setImage(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
def initUI(self):
self.setWindowTitle("Image")
# create a label
self.label = QtWidgets.QLabel(self)
th = Thread(self)
th.changePixmap.connect(self.setImage)
self.reSize.connect(th.scaled)
th.start()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
def resizeEvent(self, event):
self.reSize.emit(self.size())
class UIWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(UIWidget, self).__init__(parent)
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
# Add tabs
self.tabs.addTab(self.tab1, "Face")
self.tabs.addTab(self.tab2, "Human")
self.tabs.addTab(self.tab3, "Vehicle")
# Create first tab
self.createGridLayout()
self.tab1.layout = QtWidgets.QVBoxLayout()
self.display = PlayStreaming()
self.tab1.layout.addWidget(self.display, stretch=1)
self.tab1.layout.addWidget(self.horizontalGroupBox)
self.tab1.setLayout(self.tab1.layout)
# Add tabs to widget
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tabs)
def createGridLayout(self):
self.horizontalGroupBox = QtWidgets.QGroupBox("Control")
self.horizontalGroupBox.setStyleSheet("QGroupBox { background-color: red}");
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QPushButton('Test'), 0, 0)
layout.addWidget(QtWidgets.QPushButton('Run'), 0, 1)
layout.addWidget(QtWidgets.QPushButton('Set Faces'), 0, 2)
layout.addWidget(QtWidgets.QPushButton('Recognize'), 1, 0)
layout.addWidget(QtWidgets.QPushButton('Rescale'), 1, 1)
layout.addWidget(QtWidgets.QPushButton('FacePose'), 1, 2)
self.horizontalGroupBox.setLayout(layout)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = UIWidget()
w.resize(1000, 800)
w.show()
sys.exit(app.exec_())
Upvotes: 3