Python QT与Opencv(三)

一.PyQt5 GUI中的Opencv眼睛和人脸检测

①Qt designer
在这里插入图片描述
②loadandsave.ui -> loadandsave.py

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'loadandsave.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(824, 576)
        self.imagelabel = QtWidgets.QLabel(Dialog)
        self.imagelabel.setGeometry(QtCore.QRect(42, 120, 341, 431))
        self.imagelabel.setObjectName("imagelabel")
        self.processedlabel = QtWidgets.QLabel(Dialog)
        self.processedlabel.setGeometry(QtCore.QRect(420, 120, 321, 431))
        self.processedlabel.setObjectName("processedlabel")
        self.hSlider = QtWidgets.QSlider(Dialog)
        self.hSlider.setGeometry(QtCore.QRect(30, 80, 741, 22))
        self.hSlider.setOrientation(QtCore.Qt.Horizontal)
        self.hSlider.setTickInterval(10)
        self.hSlider.setObjectName("hSlider")
        self.widget = QtWidgets.QWidget(Dialog)
        self.widget.setGeometry(QtCore.QRect(30, 10, 751, 30))
        self.widget.setObjectName("widget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.loadButton = QtWidgets.QPushButton(self.widget)
        self.loadButton.setObjectName("loadButton")
        self.horizontalLayout.addWidget(self.loadButton)
        self.saveButton = QtWidgets.QPushButton(self.widget)
        self.saveButton.setObjectName("saveButton")
        self.horizontalLayout.addWidget(self.saveButton)
        self.detectButton = QtWidgets.QPushButton(self.widget)
        self.detectButton.setObjectName("detectButton")
        self.horizontalLayout.addWidget(self.detectButton)
        self.widget1 = QtWidgets.QWidget(Dialog)
        self.widget1.setGeometry(QtCore.QRect(520, 60, 261, 21))
        self.widget1.setObjectName("widget1")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget1)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.checkface = QtWidgets.QCheckBox(self.widget1)
        self.checkface.setObjectName("checkface")
        self.horizontalLayout_2.addWidget(self.checkface)
        self.checkeye = QtWidgets.QCheckBox(self.widget1)
        self.checkeye.setObjectName("checkeye")
        self.horizontalLayout_2.addWidget(self.checkeye)
        
        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.imagelabel.setText(_translate("Dialog", "imagelabel"))
        self.processedlabel.setText(_translate("Dialog", "processedlabel"))
        self.loadButton.setText(_translate("Dialog", "Load Image"))
        self.saveButton.setText(_translate("Dialog", "Save Image"))
        self.detectButton.setText(_translate("Dialog", "Detect"))
        self.checkface.setText(_translate("Dialog", "Face"))
        self.checkeye.setText(_translate("Dialog", "Eye"))

③ main_code
其中人脸检测和人眼检查模块,
在这里插入图片描述
https://pan.baidu.com/s/1k9k0rhzU_kE_ObYvnra7vQ
提取码:740z

import sys
import cv2
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QImage,QPixmap
from PyQt5.QtWidgets import QDialog,QApplication,QFileDialog
from PyQt5.uic import loadUi
from loadandsave import Ui_Dialog

class Life2Coding(QDialog,Ui_Dialog):
    face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    eye_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
    def __init__(self, parent=None):
        super(QDialog,self).__init__(parent)
        self.setupUi(self)
        
        self.image = None          # 左边imagelabel控件上的图像image
        self.processedImage = None #右边processedlabel控件上的图像processedImage
        
        self.loadButton.clicked.connect(self.loadClicked) #按钮Load Image
        self.saveButton.clicked.connect(self.saveClicked) #按钮Save Image
        self.detectButton.clicked.connect(self.detectClicked) #按钮Canny
        self.hSlider.valueChanged.connect(self.cannyDisplay) 
        
    @pyqtSlot()
    def cannyDisplay(self):
        gray = cv2.cvtColor(self.image,cv2.COLOR_BGR2GRAY) if len(self.image.shape) >=3 else self.image
        self.processedImage = cv2.Canny(gray,self.hSlider.value(),self.hSlider.value()*3)
        self.displayImage(2)
        
    @pyqtSlot()
    def detectClicked(self):
        gray = cv2.cvtColor(self.image,cv2.COLOR_BGR2GRAY) if len(self.image.shape)>=3 else self.image
        faces = self.face_cascade.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in faces:
            if self.checkface.isChecked():
                cv2.rectangle(self.processedImage,(x,y),(x+w,y+h),(255,0,0),2)
            else:
                self.processedImage = self.image.copy()
            roi_gray = gray[y:y+h,x:x+w]
            roi_color = self.processedImage[y:y+h,x:x+w]
            if self.checkeye.isChecked():
                eyes = self.eye_cascade.detectMultiScale(roi_gray)
                for (ex,ey,ew,eh) in eyes:
                    cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
            else:
                self.processedImage[y:y+h,x:x+w] = self.image[y:y+h,x:x+w].copy()
        self.displayImage(2)
        
    @pyqtSlot()
    def loadClicked(self):
        fname, filter = QFileDialog.getOpenFileName(self, "Open File", "E:\\youtu_image", "Image Files (*.jpg)")
        if fname:
            self.loadImage(fname)
        else:
            print("Invalid Image!!!Check!!!")
            
    @pyqtSlot()
    def saveClicked(self):
        fname, filter = QFileDialog.getSaveFileName(self, "Save File", "E:\\youtu_image", "Image Files (*.jpg)")
        if fname:
            cv2.imwrite(fname, self.image)
        else:
            print("Error!!!")
            
    def loadImage(self,fname):
        # self.image = cv2.imread(fname)
        self.image = cv2.imread(fname, cv2.IMREAD_COLOR)      #图片彩色读取
        # self.image = cv2.imread(fname,cv2.IMREAD_GRAYSCALE) #图片灰度读取
        self.processedImage = self.image.copy()
        self.displayImage(1)
        
    def displayImage(self,window=1):
        qformat = QImage.Format_Indexed8
        if len(self.processedImage.shape) == 3: #rows->shape[0],cols_>shape[1],channels->shape[2]
            if(self.processedImage.shape[2]) == 4:
                qformat = QImage.Format_RGBA8888
            else:
                qformat = QImage.Format_RGB888
        img = QImage(self.processedImage,self.processedImage.shape[1],self.processedImage.shape[0],self.processedImage.strides[0],qformat)
        # BGR->RGB
        img = img.rgbSwapped()
        if window == 1:
            self.imagelabel.setPixmap(QPixmap.fromImage(img))
            self.imagelabel.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
        if window == 2:
            self.processedlabel.setPixmap(QPixmap.fromImage(img))
            self.processedlabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
            
app = QApplication(sys.argv)
window = Life2Coding()
window.show()
sys.exit(app.exec_())

效果:
在这里插入图片描述

二.通过PyQt5界面编程旋转一个图片并将其保存

①Qt designer
在这里插入图片描述
在这里插入图片描述
②loadandsave.ui -> loadandsave.py

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'loadandsave.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(824, 576)
        self.imagelabel = QtWidgets.QLabel(Dialog)
        self.imagelabel.setGeometry(QtCore.QRect(42, 120, 341, 431))
        self.imagelabel.setObjectName("imagelabel")
        self.processedlabel = QtWidgets.QLabel(Dialog)
        self.processedlabel.setGeometry(QtCore.QRect(420, 120, 321, 431))
        self.processedlabel.setObjectName("processedlabel")
        self.hSlider = QtWidgets.QSlider(Dialog)
        self.hSlider.setGeometry(QtCore.QRect(30, 80, 231, 22))
        self.hSlider.setOrientation(QtCore.Qt.Horizontal)
        self.hSlider.setTickInterval(10)
        self.hSlider.setObjectName("hSlider")
        self.layoutWidget = QtWidgets.QWidget(Dialog)
        self.layoutWidget.setGeometry(QtCore.QRect(30, 10, 751, 30))
        self.layoutWidget.setObjectName("layoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.loadButton = QtWidgets.QPushButton(self.layoutWidget)
        self.loadButton.setObjectName("loadButton")
        self.horizontalLayout.addWidget(self.loadButton)
        self.saveButton = QtWidgets.QPushButton(self.layoutWidget)
        self.saveButton.setObjectName("saveButton")
        self.horizontalLayout.addWidget(self.saveButton)
        self.detectButton = QtWidgets.QPushButton(self.layoutWidget)
        self.detectButton.setObjectName("detectButton")
        self.horizontalLayout.addWidget(self.detectButton)
        self.layoutWidget1 = QtWidgets.QWidget(Dialog)
        self.layoutWidget1.setGeometry(QtCore.QRect(520, 60, 261, 21))
        self.layoutWidget1.setObjectName("layoutWidget1")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget1)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.checkface = QtWidgets.QCheckBox(self.layoutWidget1)
        self.checkface.setObjectName("checkface")
        self.horizontalLayout_2.addWidget(self.checkface)
        self.checkeye = QtWidgets.QCheckBox(self.layoutWidget1)
        self.checkeye.setObjectName("checkeye")
        self.horizontalLayout_2.addWidget(self.checkeye)
        self.dialValue = QtWidgets.QDial(Dialog)
        self.dialValue.setGeometry(QtCore.QRect(290, 60, 50, 64))
        self.dialValue.setMaximum(360)
        self.dialValue.setNotchesVisible(True)
        self.dialValue.setObjectName("dialValue")
        self.rotateValue = QtWidgets.QLineEdit(Dialog)
        self.rotateValue.setGeometry(QtCore.QRect(360, 80, 113, 21))
        self.rotateValue.setObjectName("rotateValue")
        
        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.imagelabel.setText(_translate("Dialog", "imagelabel"))
        self.processedlabel.setText(_translate("Dialog", "processedlabel"))
        self.loadButton.setText(_translate("Dialog", "Load Image"))
        self.saveButton.setText(_translate("Dialog", "Save Image"))
        self.detectButton.setText(_translate("Dialog", "Detect"))
        self.checkface.setText(_translate("Dialog", "Face"))
        self.checkeye.setText(_translate("Dialog", "Eye"))

③ main_code

# -*- coding: utf-8 -*-

import sys
import cv2
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QImage,QPixmap
from PyQt5.QtWidgets import QDialog,QApplication,QFileDialog,QMessageBox
from PyQt5.uic import loadUi
from loadandsave import Ui_Dialog
import numpy as np

class Life2Coding(QDialog,Ui_Dialog):
    face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    eye_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
    
    def __init__(self, parent=None):
        super(QDialog,self).__init__(parent)
        self.setupUi(self)
        
        self.image = None          # 左边imagelabel控件上的图像image
        self.processedImage = None # 右边processedlabel控件上的图像processedImage
        
        self.loadButton.clicked.connect(self.loadClicked) #按钮Load Image
        self.saveButton.clicked.connect(self.saveClicked) #按钮Save Image
        self.detectButton.clicked.connect(self.detectClicked) #按钮Canny
        self.hSlider.valueChanged.connect(self.cannyDisplay)
        self.dialValue.valueChanged.connect(self.rotate_image) #控件Dial
        self.rotateValue.returnPressed.connect(self.updateImage) #控件LineEdit
        
    def updateImage(self):
        angle = int(self.rotateValue.text())
        self.loadButton.setDefault(False)
        self.loadButton.setAutoDefault(False)
        if angle >= 0 and angle <= 360:
            self.rotate_image(angle)
            self.dialValue.setValue(angle)
        else:
            QMessageBox.information(self,"Error!","Please Enter Between 0 to 360")
            
    def rotate_image(self,angle,scale=1):
        w = self.image.shape[1]
        h = self.image.shape[0]
        rangle = np.deg2rad(int(angle)) # 弧度角度转换
        
        # 然后计算新的图片的宽度与高度
        nw = (abs(np.sin(rangle) * h) + abs(np.cos(rangle) * w)) * scale
        nh = (abs(np.cos(rangle) * h) + abs(np.sin(rangle) * w)) * scale
        
        # 要求Opencv提供旋转矩阵
        rot_mat = cv2.getRotationMatrix2D((nw * 0.5,nh * 0.5),angle,scale)
        
        # 计算从原来的中心到新的中心的合并移动及旋转角度
        rot_move = np.dot(rot_mat,np.array([(nw - w) * 0.5,(nh - h) * 0.5,0]))
        
        # 移动只会影响角度,因此更新角度
        rot_mat[0, 2] += rot_move[0]
        rot_mat[1, 2] += rot_move[1]
        
        self.processedImage = cv2.warpAffine(self.image,rot_mat,(int(np.math.ceil(nw)),int(np.math.ceil(nh))))
        self.rotateValue.setText(str(angle))
        self.displayImage(2)
        
    @pyqtSlot()
    def cannyDisplay(self):
        gray = cv2.cvtColor(self.image,cv2.COLOR_BGR2GRAY) if len(self.image.shape) >=3 else self.image
        self.processedImage = cv2.Canny(gray,self.hSlider.value(),self.hSlider.value()*3)
        self.displayImage(2)
        
    @pyqtSlot()
    def detectClicked(self):
        gray = cv2.cvtColor(self.image,cv2.COLOR_BGR2GRAY) if len(self.image.shape)>=3 else self.image
        faces = self.face_cascade.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in faces:
            if self.checkface.isChecked():
                cv2.rectangle(self.processedImage,(x,y),(x+w,y+h),(255,0,0),2)
            else:
                self.processedImage = self.image.copy()
            roi_gray = gray[y:y+h,x:x+w]
            roi_color = self.processedImage[y:y+h,x:x+w]
            if self.checkeye.isChecked():
                eyes = self.eye_cascade.detectMultiScale(roi_gray)
                for (ex,ey,ew,eh) in eyes:
                    cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
            else:
                self.processedImage[y:y+h,x:x+w] = self.image[y:y+h,x:x+w].copy()
        self.displayImage(2)
        
    @pyqtSlot()
    def loadClicked(self):
        fname, filter = QFileDialog.getOpenFileName(self, "Open File", "E:\\youtu_image", "Image Files (*.jpg)")
        if fname:
            self.loadImage(fname)
        else:
            print("Invalid Image!!!Check!!!")
            
    @pyqtSlot()
    def saveClicked(self):
        fname, filter = QFileDialog.getSaveFileName(self, "Save File", "E:\\youtu_image", "Image Files (*.jpg)")
        if fname:
            cv2.imwrite(fname, self.image)
        else:
            print("Error!!!")
            
    def loadImage(self,fname):
        # self.image = cv2.imread(fname)
        self.image = cv2.imread(fname, cv2.IMREAD_COLOR)      #图片彩色读取
        # self.image = cv2.imread(fname,cv2.IMREAD_GRAYSCALE) #图片灰度读取
        self.processedImage = self.image.copy()
        self.displayImage(1)
        
    def displayImage(self,window=1):
        qformat = QImage.Format_Indexed8
        
        if len(self.processedImage.shape) == 3: #rows->shape[0],cols_>shape[1],channels->shape[2]
            if(self.processedImage.shape[2]) == 4:
                qformat = QImage.Format_RGBA8888
            else:
                qformat = QImage.Format_RGB888
        img = QImage(self.processedImage,self.processedImage.shape[1],self.processedImage.shape[0],self.processedImage.strides[0],qformat)
        # BGR->RGB
        img = img.rgbSwapped()
        if window == 1:
            self.imagelabel.setPixmap(QPixmap.fromImage(img))
            self.imagelabel.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
        if window == 2:
            self.processedlabel.setPixmap(QPixmap.fromImage(img))
            self.processedlabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
            
app = QApplication(sys.argv)
window = Life2Coding()
window.show()
sys.exit(app.exec_())

效果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boss-dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值