介绍

本文主要介绍一个小工具,其功能是在具有各种姿态(各个角度的转头)的人脸图片库中筛选出正脸的图片。

环境需求

SeetaFace人脸识别库
OpenCV

基本方法

首先使用OpenCV的glob遍历文件夹里的图片,然后对每张图片提取脸部特征。

1. 提取脸部特征点:

Mat frame = imread(fn[i]);
        if (!frame.data)
        {
            continue;
        }
        images.push_back(frame);

        seeta::FaceDetector2 FD("bindata/SeetaFaceDetector2.0.ats");

        seeta::cv::ImageData image = frame;

        seeta::PointDetector2 PD("bindata/SeetaPointDetector2.0.pts5.ats");
        int num;
        SeetaRect *face = FD.Detect(image, &num);
        if (num==0)
        {
            continue;
        }
        SeetaPointF *points = PD.Detect(image, *face);

        if (points)
        {
            std::cout << "Points: [" << std::endl;
            for (int j = 0; j < PD.LandmarkNum(); ++j)
            {
                std::cout << "(" << points[j].x << ", " << points[j].y << ")," << std::endl;
            }
            std::cout << "]" << std::endl;
        }

2. 计算点3是否为点1和点二的中点,如果是的话,则判断为正脸照片。

double result = 2 * points[2].x - points[0].x - points[1].x;
        result = fabs(result);
        if (result < s)
        {
            s = result;
            std::cout << s << std::endl;
            string Img_Name = "D:/Desktop/pachong/result/" + to_string(s) + ".jpg";
            imwrite(Img_Name, frame);
        }

完整代码

#include<seeta/FaceDetector2.h>
#include<seeta/PointDetector2.h>
#include<seeta/FaceRecognizer.h>
#include<opencv2/opencv.hpp>
#include<seeta/Struct_cv.h>
#include<iostream>
#include<io.h>
#include<string>
#include<vector>

using namespace std;
using namespace cv;



void main()
{
    vector<Mat> read_images_in_folder(cv::String pattern);
    cv::String pattern = "你的图片文件路径";
    vector<Mat> images = read_images_in_folder(pattern);
}

std::vector<Mat> read_images_in_folder(cv::String pattern)
{
    vector<cv::String> fn;
    glob(pattern, fn, false);
    cout << "pattern"<<pattern << endl;
    vector<Mat> images;
    size_t count = fn.size();
    cout << count << endl;
    double s = 20;
    int pick_img = 0;
    for (size_t i = 0; i < count; i++)
    {
        Mat frame = imread(fn[i]);
        if (!frame.data)
        {
            continue;
        }
        images.push_back(frame);

        seeta::FaceDetector2 FD("bindata/SeetaFaceDetector2.0.ats");

        seeta::cv::ImageData image = frame;

        seeta::PointDetector2 PD("bindata/SeetaPointDetector2.0.pts5.ats");
        int num;
        SeetaRect *face = FD.Detect(image, &num);
        if (num==0)
        {
            continue;
        }
        SeetaPointF *points = PD.Detect(image, *face);

        if (points)
        {
            std::cout << "Points: [" << std::endl;
            for (int j = 0; j < PD.LandmarkNum(); ++j)
            {
                std::cout << "(" << points[j].x << ", " << points[j].y << ")," << std::endl;
            }
            std::cout << "]" << std::endl;
        }

        double result = 2 * points[2].x - points[0].x - points[1].x;
        result = fabs(result);
        if (result < s)
        {
            s = result;
            std::cout << s << std::endl;
            string Img_Name = "D:/Desktop/pachong/result/" + to_string(s) + ".jpg";
            imwrite(Img_Name, frame);
        }
    }

    return images;

}
Last modification:January 10, 2023
您赞赏,我就多写点儿。