OpenCV人脸检测,如何裁剪和保存人脸

OpenCV face detection, how to crop and save face?

本文关键字:裁剪 保存 何裁剪 检测 OpenCV      更新时间:2023-10-16

我在Ubuntu上使用OpenCV 3。下面的代码用于检测图像中的人脸并保存裁剪的部分。没有显示输出,但裁剪后的图像保存在我的文件夹中。

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
// Function Headers
void detectAndDisplay(Mat frame);
// Global variables
// Copy this file from opencv/data/haarscascades to target folder
string face_cascade_name = "/home/sruthi/opencv/data/haarcascades/haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
string window_name = "Capture - Face detection";
int filenumber; // Number of file to be saved
string filename;
// Function main
int main(void)
{
    // Load the cascade
    if (!face_cascade.load(face_cascade_name)){
        printf("--(!)Error loadingn");
        return (-1);
    }
    // Read the image file
    Mat frame = imread("/home/sruthi/Downloads/pic.jpg");
    // Apply the classifier to the frame
    if (!frame.empty()){
        detectAndDisplay(frame);
    }
    else{
        printf(" --(!) No captured frame -- Break!");
        //break;
    }
    int c = waitKey(10);
    if (27 == char(c)){
        //break;
    }
    return 0;
}
// Function detectAndDisplay
void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;
    Mat crop;
    Mat res;
    Mat gray;
    string text;
    stringstream sstm;
    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);
    // Detect faces
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
    // Set Region of Interest
    cv::Rect roi_b;
    cv::Rect roi_c;
    size_t ic = 0; // ic is index of current element
    int ac = 0; // ac is area of current element
    size_t ib = 0; // ib is index of biggest element
    int ab = 0; // ab is area of biggest element
    for (ic = 0; ic < faces.size(); ic++) // Iterate through all current elements (detected faces)
    {
        roi_c.x = faces[ic].x;
        roi_c.y = faces[ic].y;
        roi_c.width = (faces[ic].width);
        roi_c.height = (faces[ic].height);
        ac = roi_c.width * roi_c.height; // Get the area of current element (detected face)
        roi_b.x = faces[ib].x;
        roi_b.y = faces[ib].y;
        roi_b.width = (faces[ib].width);
        roi_b.height = (faces[ib].height);
        ab = roi_b.width * roi_b.height; // Get the area of biggest element, at beginning it is same as "current" element
        if (ac > ab)
        {
            ib = ic;
            roi_b.x = faces[ib].x;
            roi_b.y = faces[ib].y;
            roi_b.width = (faces[ib].width);
            roi_b.height = (faces[ib].height);
        }
        crop = frame(roi_b);
        resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); // This will be needed later while saving images
        cvtColor(crop, gray, CV_BGR2GRAY); // Convert cropped image to Grayscale
        // Form a filename
        filename = "";
        stringstream ssfn;
        ssfn << filenumber << ".jpg";
        filename = ssfn.str();
        filenumber++;
        imwrite(filename, gray);
        Point pt1(faces[ic].x, faces[ic].y); // Display detected faces on main window
        Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
        rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0);
 }
    // Show image
    sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename;
    text = sstm.str();
    putText(frame, text, cvPoint(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0, 0, 255), 1, CV_AA);
    imshow("original", frame);
    if (!crop.empty())
    {
        imshow("detected", crop);
    }
    else
        destroyWindow("detected");
}

但是在执行结束时,我得到:

sruthi@sruthi - 5547: ~/c++。美元/作物纯虚方法调用在没有活动异常的情况下终止调用Aborted (core dump)

我认为这里有两个问题。

首先,你的代码工作得很好,但是你应该在imshow之后添加cv::waitKey();,以防止窗口关闭(它会在按下一个键后关闭)。

第二,OpenCV 3.0.0中有一个导致pure virtual method called错误的错误。如果您的程序运行正常,我敢打赌错误消息是由于错误。如果你从github仓库获得最新的(和未发布的)OpenCV版本,它将被修复。

在python中可以这样做:

import cv2
import sys
cascPath = sys.argv[1]
faceCascade = cv2.CascadeClassifier(cascPath)
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=5,
        minSize=(30, 30),
        flags=cv2.cv.CV_HAAR_SCALE_IMAGE
    )
    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 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 = frame[y: y + h, x: x + w] 
        cv2.imwrite("face.jpg", crop)
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()