人脸识别引擎SeetaFaceEngine中Identification模块用于比较两幅人脸图像的相似度,以下是测试代码:

int test_recognize()
{
	const std::string path_images{ "E:/GitCode/Face_Test/testdata/recognization/" };
	seeta::FaceDetection detector("E:/GitCode/Face_Test/src/SeetaFaceEngine/FaceDetection/model/seeta_fd_frontal_v1.0.bin");
	seeta::FaceAlignment alignment("E:/GitCode/Face_Test/src/SeetaFaceEngine/FaceAlignment/model/seeta_fa_v1.1.bin");
	seeta::FaceIdentification face_recognizer("E:/GitCode/Face_Test/src/SeetaFaceEngine/FaceIdentification/model/seeta_fr_v1.0.bin");

	detector.SetMinFaceSize(20);
	detector.SetMaxFaceSize(200);
	detector.SetScoreThresh(2.f);
	detector.SetImagePyramidScaleFactor(0.8f);
	detector.SetWindowStep(4, 4);

	std::vector<std::vector<seeta::FacialLandmark>> landmards;

	// detect and alignment
	for (int i = 0; i < 20; i++) {
		std::string image = path_images + std::to_string(i) + ".jpg";
		//fprintf(stderr, "start process image: %s\n", image.c_str());

		cv::Mat src_ = cv::imread(image, 1);
		if (src_.empty()) {
			fprintf(stderr, "read image error: %s\n", image.c_str());
			continue;
		}

		cv::Mat src;
		cv::cvtColor(src_, src, CV_BGR2GRAY);

		seeta::ImageData img_data;
		img_data.data = src.data;
		img_data.width = src.cols;
		img_data.height = src.rows;
		img_data.num_channels = 1;

		std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
		if (faces.size() == 0) {
			fprintf(stderr, "%s don't detect face\n", image.c_str());
			continue;
		}

		// Detect 5 facial landmarks: two eye centers, nose tip and two mouth corners
		std::vector<seeta::FacialLandmark> landmard(5);
		alignment.PointDetectLandmarks(img_data, faces[0], &landmard[0]);

		landmards.push_back(landmard);

		cv::rectangle(src_, cv::Rect(faces[0].bbox.x, faces[0].bbox.y,
			faces[0].bbox.width, faces[0].bbox.height), cv::Scalar(0, 255, 0), 2);

		for (auto point : landmard) {
			cv::circle(src_, cv::Point(point.x, point.y), 2, cv::Scalar(0, 0, 255), 2);
		}

		std::string save_result = path_images + "_" + std::to_string(i) + ".jpg";
		cv::imwrite(save_result, src_);
	}

	int width = 200;
	int height = 200;
	cv::Mat dst(height * 5, width * 4, CV_8UC3);
	for (int i = 0; i < 20; i++) {
		std::string input_image = path_images + "_" + std::to_string(i) + ".jpg";
		cv::Mat src = cv::imread(input_image, 1);
		if (src.empty()) {
			fprintf(stderr, "read image error: %s\n", input_image.c_str());
			return -1;
		}

		cv::resize(src, src, cv::Size(width, height), 0, 0, 4);
		int x = (i * width) % (width * 4);
		int y = (i / 4) * height;
		cv::Mat part = dst(cv::Rect(x, y, width, height));
		src.copyTo(part);
	}
	std::string output_image = path_images + "result_alignment.png";
	cv::imwrite(output_image, dst);

	// crop image
	for (int i = 0; i < 20; i++) {
		std::string image = path_images + std::to_string(i) + ".jpg";
		//fprintf(stderr, "start process image: %s\n", image.c_str());

		cv::Mat src_img = cv::imread(image, 1);
		if (src_img.data == nullptr) {
			fprintf(stderr, "Load image error: %s\n", image.c_str());
			return -1;
		}

		if (face_recognizer.crop_channels() != src_img.channels()) {
			fprintf(stderr, "channels dismatch: %d, %d\n", face_recognizer.crop_channels(), src_img.channels());
			return -1;
		}

		// ImageData store data of an image without memory alignment.
		seeta::ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels());
		src_img_data.data = src_img.data;

		// Create a image to store crop face.
		cv::Mat dst_img(face_recognizer.crop_height(), face_recognizer.crop_width(), CV_8UC(face_recognizer.crop_channels()));
		seeta::ImageData dst_img_data(dst_img.cols, dst_img.rows, dst_img.channels());
		dst_img_data.data = dst_img.data;
		// Crop Face
		face_recognizer.CropFace(src_img_data, &landmards[i][0], dst_img_data);

		std::string save_image_name = path_images + "crop_" + std::to_string(i) + ".jpg";
		cv::imwrite(save_image_name, dst_img);
	}

	dst = cv::Mat(height * 5, width * 4, CV_8UC3);
	for (int i = 0; i < 20; i++) {
		std::string input_image = path_images + "crop_" + std::to_string(i) + ".jpg";
		cv::Mat src_img = cv::imread(input_image, 1);
		if (src_img.empty()) {
			fprintf(stderr, "read image error: %s\n", input_image.c_str());
			return -1;
		}

		cv::resize(src_img, src_img, cv::Size(width, height), 0, 0, 4);
		int x = (i * width) % (width * 4);
		int y = (i / 4) * height;
		cv::Mat part = dst(cv::Rect(x, y, width, height));
		src_img.copyTo(part);
	}
	output_image = path_images + "result_crop.png";
	cv::imwrite(output_image, dst);

	// extract feature
	int feat_size = face_recognizer.feature_size();
	if (feat_size != 2048) {
		fprintf(stderr, "feature size mismatch: %d\n", feat_size);
		return -1;
	}

	float* feat_sdk = new float[feat_size * 20];

	for (int i = 0; i < 20; i++) {
		std::string input_image = path_images + "crop_" + std::to_string(i) + ".jpg";
		cv::Mat src_img = cv::imread(input_image, 1);
		if (src_img.empty()) {
			fprintf(stderr, "read image error: %s\n", input_image.c_str());
			return -1;
		}

		cv::resize(src_img, src_img, cv::Size(face_recognizer.crop_height(), face_recognizer.crop_width()));

		// ImageData store data of an image without memory alignment.
		seeta::ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels());
		src_img_data.data = src_img.data;

		// Extract feature
		face_recognizer.ExtractFeature(src_img_data, feat_sdk + i * feat_size);
	}

	float* feat1 = feat_sdk;
	// varify(recognize)
	for (int i = 1; i < 20; i++) {
		std::string image = std::to_string(i) + ".jpg";
		float* feat_other = feat_sdk + i * feat_size;

		// Caculate similarity
		float sim = face_recognizer.CalcSimilarity(feat1, feat_other);
		fprintf(stdout, "0.jpg -- %s similarity: %f\n", image.c_str(), sim);
	}

	delete[] feat_sdk;

	return 0;
}

从网上找了20张图像,前19张为周星驰,最后一张为汤唯,用于测试此模块,测试结果如下:

detect/alignment结果如下:

crop结果如下:

取上图中最左上图为标准图,与其它19幅图作验证,测试结果如下:

GitHubhttps://github.com/fengbingchun/Face_Test

人脸识别引擎SeetaFaceEngine中Identification模块使用的测试代码的更多相关文章

  1. 人脸识别引擎SeetaFaceEngine中Alignment模块使用的测试代码

    人脸识别引擎SeetaFaceEngine中Alignment模块用于检测人脸关键点,包括5个点,两个眼的中心.鼻尖.两个嘴角,以下是测试代码: int test_alignment() { std: ...

  2. 人脸识别引擎SeetaFaceEngine中Detection模块使用的测试代码

    人脸识别引擎SeetaFaceEngine中Detection模块用于人脸检测,以下是测试代码: int test_detection() { std::vector<std::string&g ...

  3. 人脸识别引擎SeetaFaceEngine简介及在windows7 vs2013下的编译

    SeetaFaceEngine是开源的C++人脸识别引擎,无需第三方库,它是由中科院计算所山世光老师团队研发.它的License是BSD-2. SeetaFaceEngine库包括三个模块:人脸检测( ...

  4. 【计算机视觉】SeetaFace Engine开源C++人脸识别引擎

    SeetaFace Engine是一个开源的C++人脸识别引擎,它可以在不依赖第三方的条件下载CPU上运行.他包含三个关键部分,即:SeetaFace Detection,SeetaFace Alig ...

  5. Android打开相机进行人脸识别,使用虹软人脸识别引擎

    上一张效果图,渣画质,能看就好 功能说明: 人脸识别使用的是虹软的FreeSDK,包含人脸追踪,人脸检测,人脸识别,年龄.性别检测功能,其中本demo只使用了FT和FR(人脸追踪和人脸识别),封装了开 ...

  6. 教你如何认识人脸识别开发套件中的双目摄像、3D结构光摄像头、单目摄像头的区别及详细讲解

    深圳市宁远电子提供的人脸识别模组可支持双目摄像头和3D结构光摄像头,在客户咨询中经常有被问到双目的为什么会比单目的成本高,区别在哪里,他们的适用于哪些场景呢?在此,深圳市宁远电子技术工程师就为大家详细 ...

  7. 关于人脸识别引擎FaceRecognitionDotNet的实例

    根据我上篇文章的分享,我提到了FaceRecognitionDotNet,它是python语言开发的一个项目face_recognition移植.结果真是有喜有忧,喜的是很多去关注了,进行了下载,我看 ...

  8. 人脸识别引擎SeetaFace编译 ubuntu

    00.SeetaFace简介 SeetaFace Engine is an open source C++ face recognition engine, which can run on CPU ...

  9. .NET的关于人脸识别引擎分享(C#)

    https://www.cnblogs.com/RainbowInTheSky/p/10247921.html

随机推荐

  1. windows server 2008/2012安装PostgreSQL过程及问题总结

    今天第一次接触在Windows Server2008/2012 下安装PostgreSQL,遇到的问题总结如下: 1.首先,在安装的时候,我更改安装目录改为自定义的E盘,安装时报错:libintl.d ...

  2. CF219D Choosing Capital for Treeland

    嘟嘟嘟 树形dp. 首先一个很常规的想法就是如果u到v有一条边,那么建立cost(u, v) = 0, cost(v, u) = 1的两条边. 可以两遍dfs. 先任选一个点作为根节点,第一遍从下往上 ...

  3. gulp基础使用及进阶

    提示:路径中不允许出现中文,否则scss编译会出错,大概. 按照惯例,先检查一下Node.js.npm(cnpm).gulp的版本号 1.新建package.json 我们可以通过手动新建这个配置文件 ...

  4. 30、springboot与检索(2)

    项目中进行整合: 1.整合 新建项目加入依赖(NoSql) springboot默认使用SpringDate ElasticSearch模块进行操作   查看自动配置类: SpringBoot默认支持 ...

  5. WEB安全 Sqlmap 中绕过空格拦截的12个脚本

    图片较小,可以右键点击图片-->选择 "在新标签中打开图片" --> 查看大图 Sql 注入时遇到过滤空格时可以使用下面12个脚本尝试绕过,在实际利用中可以灵活修改.

  6. 新闻cms管理系统(一) ---- thinkphp框架准备

    1.thinkphp介绍 一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架 MVC:M数据层. V视图层 . C控制层 优点: (1)入手非常快 (2)thinkpjp提供核心内库.文件.函 ...

  7. Java对象声明时:new与null的区别

    作者:林子云链接:https://www.zhihu.com/question/21468505/answer/18333632来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  8. PAT——1066. 图像过滤

    图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来.现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换. 输入格式: 输入在第一行给出一幅图像的分辨 ...

  9. zabbix 表结构详情(基本)

    zabbix表结构 1.acknowledges 记录告警的确认信息 2.actions 记录了当触发器触发时,需要采用的动作. mysql> desc actions; +---------- ...

  10. case when then else end 与 decode 的区别

    case when  then else end : 条件可以有 等于 ,大于 ,小于 与 decode : 条件只可以有等于的.