我们经常在看到人脸验证的场景中,视频显示区域是一个圆形。而我们打开摄像头显示视频内容的时候是一个矩形。
有时在特定的场景下,我们需要一个圆形的人脸检测区域。以下在PyQt下实现的,实现的原理很简单,先通过掩膜产生一个圆形区域,再增加一个透明通道,把背景透明,再把图像数据显示在窗体的上。
一、PYQT窗体准备
窗体元素:一个用来显示图像的标签和按钮
二、编译窗体UI文件,新建程序主文件
源码:
import sys
from PyQt5 import QtCore,QtGui,QtWidgets
from Ui_vision import Ui_MainWindow
import os
import cv2
import numpy as np
class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.btnopen.clicked.connect(self.Open)
#产生不同形状掩模的方法
def get_mask(self,h,w,r,cx,cy):
y,x=np.ogrid[0:h,0:w]
mask = (x-cx)**2+(y-cy)**2<=r**2 #圆形
return mask
def Open(self):
cap=cv2.VideoCapture(0)
while cap.isOpened():
ret,frame=cap.read()
h,w,c=frame.shape #获取H,W,C
gray=np.zeros((h,w),np.uint8)
mask=self.get_mask(h,w,h//2,w//2,h//2)
gray[mask]=255 #圆内部白色
frame=cv2.bitwise_and(frame,frame,mask=gray)
b,g,r=cv2.split(frame) #拆分三通道
#生成a透明通道
a=np.ones(b.shape,np.uint8)*255
a[np.invert(mask)]=0 #背景透明
dst=cv2.merge((r,g,b,a)) #rgba模式,增加一个透明通道
img=QtGui.QImage(dst.data,dst.shape[1],dst.shape[0],QtGui.QImage.Format_RGBA8888)
#img=QtGui.QImage(frame.data,frame.shape[1],frame.shape[0],QtGui.QImage.Format_BGR888)
self.lblimg.setPixmap(QtGui.QPixmap.fromImage(img))
self.lblimg.setScaledContents(True)
QtWidgets.QApplication.processEvents()
cv2.waitKey(10)
if __name__=="__main__":
app=QtWidgets.QApplication(sys.argv)
mywin=MainWindow()
mywin.setWindowTitle("GUI 测试")
mywin.show()
sys.exit(app.exec())
注:直接用cv2.imshow的窗体没有支持透明通道,不能得背景透明效果。