如何在 OpenCV 中以椭圆形式捕获图像?

问题描述

有人可以指导我吗?我正在尝试检测人脸,然后使用 OpenCV 以椭圆形式捕获图像。以下是我运行 python 脚本时的示例。

enter image description here

目前,我只是在检测人脸并创建了这个固定框架。我还设法找到了如何以矩形形式执行此操作的解决方案,但我需要以椭圆形式捕获图像。有人可以帮我吗?另外,这是我的代码

import cv2
import sys
import numpy as np
import matplotlib.pyplot as plt

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

video_capture = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret,frame = video_capture.read()
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(
        gray,scaleFactor=1.1,minNeighbors=25,minSize=(30,30),flags=cv2.CASCADE_SCALE_IMAGE
    )

    # Draw a rectangle around the faces
    for (x,y,w,h) in faces:
    
        #320 horizontal position,250 vertical position,80 horizontal size,120 vertical size
        #0 angle,0 startangle,360 endangle
        #(0,255,0) color,2 thickness
    
        startAngle = 0
        endAngle = 10
        for z in range(20):
            cv2.ellipse(frame,(320,250),(80,120),startAngle,endAngle,(255,255),2)
            startAngle = startAngle+20
            endAngle = endAngle+20
    
        #Centered Vertical Dashed Line
        xCord = 320
        yCord = 400
        for z in range(12):
            cv2.line(frame,(xCord,yCord),yCord-20),2)
            yCord = yCord-25

        #Upper Horizontal Dashed Line
        xCord = 160
        yCord = 130
        for z in range(13):
            cv2.line(frame,(xCord+20,2)
            xCord = xCord+25
    
        #Lower Horizontal Dashed Line
        xCord = 160
        yCord = 370
        for z in range(13):
            cv2.line(frame,2)
            xCord = xCord+25
    
        cv2.putText(frame,'Head',(330,cv2.FONT_HERShey_SIMPLEX,0.5,2) 
        cv2.putText(frame,'Chin',390),2) 

        # display the resulting frame
        cv2.imshow('Video',frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    if cv2.waitKey(1) & 0xFF == ord('c'):
        crop_img = frame[y-50: y+h+10,x: x+w] # Crop from x,h -> 100,200,300,400,y-50 is to include head in the picture too y+h+10 is to include chin.
            cv2.imwrite("media/faces/face.jpg",crop_img)

# When everything is done,release the capture
video_capture.release()
cv2.destroyAllWindows()

解决方法

编辑:我已经编辑了代码,使其成为包含一张脸的图像的独立代码。

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

rgb = cv2.imread('/path/to/your/faceImage.jpg')
gray = cv2.cvtColor(rgb,cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,scaleFactor=1.1,minNeighbors=25,minSize=(30,30),flags=cv2.CASCADE_SCALE_IMAGE
)

x,y,w,h = faces[0] # Working with image with only one face
imh,imw = gray.shape

center_x,center_y = int(x+w/2),int(y+h/2)

mask = np.zeros((imh,imw),np.uint8)
cv2.ellipse(mask,(center_x,center_y),(int(w/2),int(h/2)),360,255,cv2.FILLED)
rgb[mask == 0] = 255
plt.imshow(rgb[y:y+h,x:x+w])