SeetaFaceEngine 人脸检测库实现人脸三部曲

如何使用 SeetaFaceEngine 人脸检测库实现人脸三部曲?

前期准备

  1. SeetaFaceEngine 编译 Win32 动态库
  2. 编译 Opencv Win32 库

Note:

该代码测试环境 Win7 x64 SeetaFaceEngine Win32 动态库 Opencv3.3.0 Win32 动态库

测试结果

使用多张脸图片,图中可以标记图人脸的特征点

使用两张原图对比,相似度达到 0.99

使用一张原图和angelababy图片做对比,相似度达到 0.46

使用两张angelababy图像做对比,相似度达到 0.64 ,主要这两个样本人脸方向差异太大

使用一张angelababy图像和dilraba图像做对比,相似度 0.64

使用一张angelababy图像和dilraba图像做对比,相似度 0.53 ,这张人脸方向差异不大

使用两张dilraba图像做对比,相似度 0.68

使用两张dilraba图像做对比,相似度 0.80

使用两张dilraba图像做对比,相似度 0.50,人脸方向差异大

1. 人脸检测

#include <stdlib.h>
#include <iostream>
#include <string>
#include "opencv2\highgui.hpp" //GUI模块
#include "opencv2\imgproc.hpp" //图像处理模块
#include "opencv2\imgcodecs.hpp" //图像读写模块
#include "opencv2\core.hpp" //核心模块
#include "face_detection.h" //SeetaFaceEngine 人脸检测模块
#pragma comment(lib,"opencv_highgui330.lib")
#pragma comment(lib,"opencv_imgproc330.lib")
#pragma comment(lib,"opencv_imgcodecs330.lib")
#pragma comment(lib,"opencv_core330.lib")
#pragma comment(lib,"FaceDetection.lib")

using namespace std;
using namespace cv;
using namespace seeta;

int main()
{
//加载模型
seeta::FaceDetection detector(“model/seeta_fd_frontal_v1.0.bin”);
//设置参数
detector.SetMinFaceSize(40);//设置检测器最小尺寸,默认为20。
detector.SetScoreThresh(2.f);//设置检测阈值
detector.SetImagePyramidScaleFactor(0.8f);//设置图像金字塔缩放系数
detector.SetWindowStep(4, 4);//设置滑动窗口步长
//读取待检测图像并转换为灰度图像。
cv::Mat img = cv::imread(“1.jpg”, cv::IMREAD_UNCHANGED);
cv::Mat img_gray;
if (img.channels() != 1)
{
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
}
else
{
img_gray = img;
}
//初始化 seeta::ImageData 图像数据结构体
seeta::ImageData img_data;
img_data.data = img_gray.data;
img_data.width = img_gray.cols;
img_data.height = img_gray.rows;
img_data.num_channels = 1;
//开始检测人脸并获取运行时间
long t0 = cv::getTickCount();
std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
long t1 = cv::getTickCount();
double secs = (t1 - t0) / cv::getTickFrequency();
//获取搜寻到人脸的数量并绘制矩形框
cv::Rect face_rect;
int32_t num_face = static_cast<int32_t>(faces.size());
for (int32_t i = 0; i < num_face; i++) {
face_rect.x = faces[i].bbox.x;
face_rect.y = faces[i].bbox.y;
face_rect.width = faces[i].bbox.width;
face_rect.height = faces[i].bbox.height;
cv::rectangle(img, face_rect, CV_RGB(0, 255, 0), 2, 8, 0);
}
//显示最后结果图像
cv::namedWindow(“Win7”, cv::WINDOW_AUTOSIZE);
cv::imshow(“Win7”,img);
cv::waitKey(0);
cv::destroyAllWindows();
system(“pause”);
return 0;
}

2. 人脸校正

#include <stdlib.h>
#include <iostream>
#include <string>
#include "opencv2\highgui.hpp" //GUI模块
#include "opencv2\imgproc.hpp" //图像处理模块
#include "opencv2\imgcodecs.hpp" //图像读写模块
#include "opencv2\core.hpp" //核心模块
#include "face_detection.h" //SeetaFaceEngine           人脸检测模块
#include "face_alignment.h" //SeetaFaceAlignment        人脸校准模块

#pragma comment(lib,“opencv_highgui330.lib”)
#pragma comment(lib,“opencv_imgproc330.lib”)
#pragma comment(lib,“opencv_imgcodecs330.lib”)
#pragma comment(lib,“opencv_core330.lib”)
#pragma comment(lib,“FaceDetection.lib”)
#pragma comment(lib,“SeetaFaceAlignment.lib”)
using namespace std;
using namespace cv;
using namespace seeta;

int main()
{
//加载模型
seeta::FaceDetection detector(“model/seeta_fd_frontal_v1.0.bin”);
seeta::FaceAlignment point_detector(“model/seeta_fa_v1.1.bin”);
//设置参数
detector.SetMinFaceSize(40);//设置检测器最小尺寸,默认为20。
detector.SetScoreThresh(2.f);//设置检测阈值
detector.SetImagePyramidScaleFactor(0.8f);//设置图像金字塔缩放系数
detector.SetWindowStep(4, 4);//设置滑动窗口步长
//读取待检测图像并转换为灰度图像。
cv::Mat img = cv::imread(“000.jpg”, cv::IMREAD_UNCHANGED);
cv::Mat img_gray;
if (img.channels() != 1)
{
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
}
else
{
img_gray = img;
}
//初始化 seeta::ImageData 图像数据结构体
seeta::ImageData img_data;
img_data.data = img_gray.data;
img_data.width = img_gray.cols;
img_data.height = img_gray.rows;
img_data.num_channels = 1;
//开始检测人脸并获取运行时间
long t0 = cv::getTickCount();
std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
long t1 = cv::getTickCount();
double secs = (t1 - t0) / cv::getTickFrequency();
//检测5个特征点
int pts_num = 5;
seeta::FacialLandmark points[5];
//获取搜寻到人脸的数量并绘制矩形框
cv::Rect face_rect;
int32_t num_face = static_cast<int32_t>(faces.size());
for (int32_t i = 0; i < num_face; ++i) {
face_rect.x = faces[i].bbox.x;
face_rect.y = faces[i].bbox.y;
face_rect.width = faces[i].bbox.width;
face_rect.height = faces[i].bbox.height;
cv::rectangle(img, face_rect, CV_RGB(0, 255, 0), 2, 8, 0);
//开始查找特征点
point_detector.PointDetectLandmarks(img_data, faces[i], points);
//绘制
//cv::rectangle(img, cvPoint(faces[0].bbox.x, faces[0].bbox.y), cvPoint(faces[0].bbox.x + faces[0].bbox.width - 1, faces[0].bbox.y + faces[0].bbox.height - 1), CV_RGB(255, 0, 0), 0, 0, 0);
for (int j = 0; j<pts_num; ++j)
{
cv::circle(img, cvPoint(points[j].x, points[j].y), 2, CV_RGB(0, 255, 0), CV_FILLED);
}
}
cv::resize(img, img, cv::Size(img.cols * 1, img.rows * 1));
//显示最后结果图像
cv::namedWindow(“Win7”, cv::WINDOW_AUTOSIZE);
cv::imshow(“Win7”, img);
cv::waitKey(0);
cv::destroyAllWindows();
system(“pause”);
return 0;
}

3.人脸识别

#include <stdlib.h>
#include <iostream>
#include <string>
#include "opencv2\highgui.hpp" //GUI模块
#include "opencv2\imgproc.hpp" //图像处理模块
#include "opencv2\imgcodecs.hpp" //图像读写模块
#include "opencv2\core.hpp" //核心模块
#include "face_detection.h" //SeetaFaceEngine           人脸检测模块
#include "face_alignment.h" //SeetaFaceAlignment        人脸校准模块
#include "face_identification.h" //FaceIdentification   人脸识别模块
#pragma comment(lib,"opencv_highgui330.lib")
#pragma comment(lib,"opencv_imgproc330.lib")
#pragma comment(lib,"opencv_imgcodecs330.lib")
#pragma comment(lib,"opencv_core330.lib")
#pragma comment(lib,"FaceDetection.lib")
#pragma comment(lib,"SeetaFaceAlignment.lib")
#pragma comment(lib,"FaceIdentification.lib")
using namespace std;
using namespace cv;
using namespace seeta;

int main()
{
//加载模型
seeta::FaceDetection detector(“model/seeta_fd_frontal_v1.0.bin”);
seeta::FaceAlignment point_detector(“model/seeta_fa_v1.1.bin”);
seeta::FaceIdentification face_recognizer(“model/seeta_fr_v1.0.bin”);
//设置参数
detector.SetMinFaceSize(40);//设置检测器最小尺寸,默认为20。
detector.SetScoreThresh(2.f);//设置检测阈值
detector.SetImagePyramidScaleFactor(0.8f);//设置图像金字塔缩放系数
detector.SetWindowStep(4, 4);//设置滑动窗口步长
//读取待检测图像并转换为灰度图像。
cv::Mat img = cv::imread(“Dilraba3.jpg”, cv::IMREAD_UNCHANGED);
//保存彩色图像样本用于裁剪
cv::Mat _img = img.clone();
ImageData src_img_data(_img.cols, _img.rows, _img.channels());
src_img_data.data = _img.data;
cv::Mat img_gray;
if (img.channels() != 1)
{
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
}
else
{
img_gray = img;
}
//初始化 seeta::ImageData 图像数据结构体
seeta::ImageData img_data;
img_data.data = img_gray.data;
img_data.width = img_gray.cols;
img_data.height = img_gray.rows;
img_data.num_channels = 1;
//开始检测人脸并获取运行时间
long t0 = cv::getTickCount();
std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
long t1 = cv::getTickCount();
double secs = (t1 - t0) / cv::getTickFrequency();
//检测5个特征点
int pts_num = 5;
seeta::FacialLandmark points[5];
//获取搜寻到人脸的数量并绘制矩形框
cv::Rect face_rect;
int32_t num_face = static_cast<int32_t>(faces.size());
for (int32_t i = 0; i < num_face; ++i) {
face_rect.x = faces[i].bbox.x;
face_rect.y = faces[i].bbox.y;
face_rect.width = faces[i].bbox.width;
face_rect.height = faces[i].bbox.height;
cv::rectangle(img, face_rect, CV_RGB(0, 255, 0), 2, 8, 0);
//开始查找特征点
point_detector.PointDetectLandmarks(img_data, faces[i], points);
//绘制
//cv::rectangle(img, cvPoint(faces[0].bbox.x, faces[0].bbox.y), cvPoint(faces[0].bbox.x + faces[0].bbox.width - 1, faces[0].bbox.y + faces[0].bbox.height - 1), CV_RGB(255, 0, 0), 0, 0, 0);
for (int j = 0; j<pts_num; ++j)
{
cv::circle(img, cvPoint(points[j].x, points[j].y), 2, CV_RGB(0, 255, 0), CV_FILLED);
}
}
//创建一个用来存储根据5个特征点裁剪后的图像
cv::Mat dst_img(face_recognizer.crop_height(),face_recognizer.crop_width(),CV_8UC(face_recognizer.crop_channels()));
ImageData dst_img_data(dst_img.cols, dst_img.rows, dst_img.channels());
dst_img_data.data = dst_img.data;
//裁剪图像并显示 256x256
face_recognizer.CropFace(src_img_data,points,dst_img_data);
cv::imwrite(“Dilraba3Crop.jpg”, dst_img);
cv::imshow(“Crop Face”, dst_img);
//判定特征维度是否等于2048
int feat_size = face_recognizer.feature_size();
if (feat_size != 2048)
{
return 1;
}
//读取待测图片并大小归一化
cv::Mat src_img = cv::imread(“Dilraba1Crop.jpg”,cv::IMREAD_COLOR);
cv::imshow(“Probe Face”, src_img);
cv::resize(src_img,src_img, cv::Size(face_recognizer.crop_height(),face_recognizer.crop_width()));
//
ImageData _src_img_data(src_img.cols, src_img.rows, src_img.channels());
_src_img_data.data = src_img.data;
//获取脸部特征,注意获取的特征维度必须等于模型的特征维度
float * feats = new float[face_recognizer.feature_size()];
float probe_fea[2048];
//FacialLandmark pt5[5] = { points[0],points[1],points[2],points[3],points[4] };
face_recognizer.ExtractFeature(dst_img_data, feats);
face_recognizer.ExtractFeature(_src_img_data, probe_fea);
//face_recognizer.ExtractFeatureWithCrop(_src_img_data, pt5, feats);
//计算相似度
float sim = face_recognizer.CalcSimilarity(feats,probe_fea);
std::cout << sim << std::endl;
//图像比较小,不好查看,就把图像放大,太大就缩小
cv::resize(img, img, cv::Size(img.cols * 1, img.rows * 1));
//显示最后结果图像
cv::namedWindow(“Win7”, cv::WINDOW_AUTOSIZE);
cv::imshow(“Win7”, img);
cv::waitKey(0);
cv::destroyAllWindows();
system(“pause”);
delete[] feats;
return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值