Reputation: 333
I am trying to display an image using PyQt5 edited using OpenCV.
The above image shows a side by side comparison of my expected output (Shown from a openCV Window) and the actual output displayed in a PyQt5 Label Pixmap.
The picture shows that the image is successfully resized, but not being displayed correctly.
The QLabel is within a Frame. Here's how it is defined:
self.ImageDisplayerLB = QtWidgets.QLabel(self.topFrame) #topFrame is a QFrame
self.ImageDisplayerLB.setEnabled(True)
self.ImageDisplayerLB.setText("")
self.ImageDisplayerLB.setPixmap(QtGui.QPixmap("./<image>.jpg"))
self.ImageDisplayerLB.setAlignment(QtCore.Qt.AlignCenter)
self.ImageDisplayerLB.setObjectName("ImageDisplayerLB")
self.gridLayout_2.addWidget(self.ImageDisplayerLB, 0, 0, 1, 1)
The QFrame does have a minimum height and width (Size) set so it doesn't look too small while displaying the image.
self.topFrame = QtWidgets.QFrame(self.frame)
self.topFrame.setMinimumSize(QtCore.QSize(831, 409))
self.topFrame.setStyleSheet("background-color: rgb(1,1,1);")
self.topFrame.setObjectName("topFrame")
self.topFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.topFrame.setFrameShadow(QtWidgets.QFrame.Raised)
The Pixmap is being set again with a different function call while handling an event. The below code snippet is where the error seem to be occuring.
if hw := self.__check_oversized_image(image): # Returns height, width if image is larger than the QLabel size, else returns None.
w, h = self.ImageDisplayerLB.width(), self.ImageDisplayerLB.height()
self.ImageDisplayerLB.pixmap().detach() # Tried the same without it, makes no difference
thresh = min((self.ImageDisplayerLB.width(), self.ImageDisplayerLB.height()))
r = thresh / image.shape[1]
dim = (thresh, int(image.shape[0] * r))
image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA) # Resize Image maintaining the ratio
self.ImageDisplayerLB.setScaledContents(True) # Makes no difference with or without this
# End of if block
frame = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
self.qimage = QtGui.QImage(
frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888
)
try:
self.pimage = QtGui.QPixmap.fromImage(self.qimage, QtCore.Qt.AutoColor)
self.ImageDisplayerLB.setPixmap(self.pimage)
except Exception as e:
print(e)
This issue is only when the image is found oversized and I am resizing the image. It works fine without the image being oversized.
Any help to fix the issue where the image is grayscale
and tilted.
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QMainWindow
import cv2 as cv
class main(QMainWindow):
def __init__(self):
super().__init__()
self.mainFrame = QtWidgets.QFrame(self)
self.grid = QtWidgets.QGridLayout(self.mainFrame)
self.label = QtWidgets.QLabel(self.mainFrame)
img = cv.imread("cert_template.png") # Image from -> https://simplecert.net/certificate-templates/
frame = img.copy()
self.label.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(frame.data,frame.shape[1],frame.shape[0],QtGui.QImage.Format_RGB888,))) # Not sure why this is grayscale and tilted
self.mainFrame.setMinimumSize(QtCore.QSize(831, 409))
self.label.setScaledContents(True)
self.grid.addWidget(self.label, 0, 0, 1, 1)
cv.imshow("image", img) # Displays the predicted output
cv.waitKey(0)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = main()
window.show()
app.exec_()
Much appreciated.
Upvotes: 1
Views: 442
Reputation: 41
Pass bytesPerLine
as 3 * img.shape[1]
in the QImage
constructor:
QtGui.QImage(img, img.shape[1], img.shape[0], 3 * img.shape[1], QtGui.QImage.Format_BGR888)
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget, QLabel
import cv2
class MainWindow(QWidget):
def __init__(self):
super().__init__()
img = cv2.imread("cert_template.png")
qt5_img = QtGui.QImage(img, img.shape[1], img.shape[0], 3 * img.shape[1], QtGui.QImage.Format_BGR888)
pixmap = QtGui.QPixmap.fromImage(qt5_img)
self.image_label = QLabel(self)
self.image_label.setPixmap(pixmap)
self.showMaximized()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = MainWindow()
app.exec_()
Upvotes: 0