2

I am student of Computer-Sciences and I am learning image processing using OpenCv with Python. I am working on gender detection using Periocular region. There I am facing a problem while I browse image; the Crop code work fine but on the interface Output is not displayed as requirement.

I searched for solution and apply various Qimage-Format but it did not work properly.

I would be grateful if you help me out.

I have attached code along with current output and desired output also I am going to attach so that it make the question more clearly understandable

from PyQt5 import QtGui,QtWidgets,QtCore,uic
from PyQt5.QtWidgets import QApplication,QMainWindow,QPushButton,QMessageBox,QStatusBar
from PyQt5.QtCore import QCoreApplication

import sys
import cv2

IMAGE_1=0
class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window,self).__init__()
        uic.loadUi('Welcome1.ui',self)
        self.title="Gender_Identifier"

        self.setWindowIcon(QtGui.QIcon("main-logo.png"))
#        self.browse_button.clicked.connect(self.setimage)
 #       self.roi_button.clicked.connect(self.crop)
        self.work_IMAGE=None
        self.browse_button.clicked.connect(self.setimage)
        self.roi_button.clicked.connect(self.crop)

        button=QPushButton("close",self)
        button.clicked.connect(self.close)

        self.InitWindow()

        #IMAGE=self.set_image()
    def InitWindow(self):

        self.statusBar().showMessage("This is a simple status bar")
        self.setWindowTitle(self.title)

    def file(self):

        fileName ,_ =QtWidgets.QFileDialog.getOpenFileName(None,"Select Image", "D:\python_data\interface","Image Files (*.png *.jpg)")
        return fileName

    def setimage(self):
        fileName ,_ =QtWidgets.QFileDialog.getOpenFileName(None,"Select Image", "D:\python_data\interface\images\preprocessed","Image Files (*.png *.jpg)")

        if fileName:
            #pixmap object
            pixmap=QtGui.QPixmap(fileName)
            pixmap=pixmap.scaled(self.browse_label.width(),self.browse_label.height(),QtCore.Qt.KeepAspectRatio)
            self.browse_label.setPixmap(pixmap)
            self.browse_label.setAlignment(QtCore.Qt.AlignCenter)
            if(fileName):
                self.work_IMAGE=fileName
    def crop(self):
        if(self.work_IMAGE):
            file=self.work_IMAGE
            img = cv2.imread(file, 0)

            height,width=img.shape[:2]
            start_row,strt_col=int(height*.40),int(width*.15)
            end_row,end_col=int(height*.60),int(width*.90)
            croped=img[start_row:end_row,strt_col:end_col].copy()
            #cv2.imshow("img",croped)
            image = QtGui.QImage(croped, croped.shape[0], croped.shape[1], QtGui.QImage.Format_RGB888)
            pixmap = QtGui.QPixmap(image)
            print(type(image))
            print(type(pixmap))
            print(type(croped))
            #cv2.imshow("img",croped)

            pixmap=pixmap.scaled(self.roi_label.width(),self.roi_label.height(),QtCore.Qt.KeepAspectRatio)
            cv2.imshow("img",croped)
            self.roi_label.setPixmap(pixmap)
            self.roi_label.setAlignment(QtCore.Qt.AlignCenter)


if __name__=='__main__':

    App=QtWidgets.QApplication(sys.argv)
    window=Window()
   # IMAGE=window.setimage()
    #window.crop(IMAGE)
   # IMAGE_1=IMAGE
    #print(IMAGE)
    #print(IMAGE_1)
    window.show()
    sys.exit(App.exec_())

enter image description here

enter image description here

I need when user click on "Region of Interest" button ; only cropped image should be displayed there at lable_box as displayed in second image.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
sabeen kanwal
  • 607
  • 1
  • 5
  • 16

1 Answers1

3

You must use the QImage::Format_Indexed8 format to convert the numpy array to QImage. I have implemented a method that converts some types of numpy arrays to QImage

def numpyQImage(image):
    qImg = QtGui.QImage()
    if image.dtype == np.uint8:
        if len(image.shape) == 2:
            channels = 1
            height, width = image.shape
            bytesPerLine = channels * width
            qImg = QtGui.QImage(
                image.data, width, height, bytesPerLine, QtGui.QImage.Format_Indexed8
            )
            qImg.setColorTable([QtGui.qRgb(i, i, i) for i in range(256)])
        elif len(image.shape) == 3:
            if image.shape[2] == 3:
                height, width, channels = image.shape
                bytesPerLine = channels * width
                qImg = QtGui.QImage(
                    image.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888
                )
            elif image.shape[2] == 4:
                height, width, channels = image.shape
                bytesPerLine = channels * width
                fmt = QtGui.QImage.Format_ARGB32
                qImg = QtGui.QImage(
                    image.data, width, height, bytesPerLine, QtGui.QImage.Format_ARGB32
                )
    return qImg

So in your case it should be:

def crop(self):
    if not self.work_IMAGE:
        return
    img = cv2.imread(self.work_IMAGE, cv2.IMREAD_GRAYSCALE)
    if img is None:
        return
    height, width = img.shape[:2]
    start_row, strt_col = int(height * 0.40), int(width * 0.15)
    end_row, end_col = int(height * 0.60), int(width * 0.90)
    croped = img[start_row:end_row, strt_col:end_col].copy()
    qImg = numpyQImage(croped)
    pixmap = QtGui.QPixmap.fromImage(qImg)
    pixmap = pixmap.scaled(self.roi_label.size(), QtCore.Qt.KeepAspectRatio)
    self.roi_label.setPixmap(pixmap)
    self.roi_label.setAlignment(QtCore.Qt.AlignCenter)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I am implementing this..but it is giving me error (name 'numpyQImage' is not defined) ... although I have defined both .. – sabeen kanwal Oct 14 '19 at 15:29
  • yes Sir..I am trying to solve this out but I couldnt find the solution – sabeen kanwal Oct 14 '19 at 15:36
  • I had some problems with this answer with Pyside2 v5.12.0 and upwards. Creating QImage inside the function scope and returning by value does not seem to play well with Qt's implicit data sharing which applies to QImage and is a way to allow passing by value but minimising copying. Using this function on two different images one after another, I was having the result of the 2nd overwrite the result of the 1st in memory. It was a very useful starting point though, just need to save the result directly to a member variable or global rather than return from a function – Mark Ch Jul 05 '21 at 20:17