介绍
本文主要介绍一个小工具,其功能是在具有各种姿态(各个角度的转头)的人脸图片库中筛选出正脸的图片。
环境需求
基本方法
首先使用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;
}