Goal:
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.
About the QLabel (used to display the image):
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)
About the QFrame used in QLabel:
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)
When does this occur?
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.
Minimal Reproducible Code:
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.