简单的c++人脸识别源代码

 人脸识别算法初稿..

#include <stdio.h>
#include <iostream>
#include <opencv2\opencv.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include "src/facedetectcnn.h"
#include "time.h"
#include <dlib/opencv.h>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
#include <vector>
#include <math.h>


//define the buffer size. Do not change the size!
#define DETECT_BUFFER_SIZE 0x20000
using namespace cv;
using namespace dlib;
using namespace std;

CvPoint getPointAffinedPos(const CvPoint src, const Point center, double angle)
{
	CvPoint dst;
	int x = src.x - center.x;
	int y = src.y - center.y;
	dst.x = cvRound(x * cos(angle) + y * sin(angle) + center.x);
	dst.y = cvRound(-x * sin(angle) + y * cos(angle) + center.y);
	return dst;
}

Mat face_alignment(Mat &face, CvPoint& left, CvPoint& right, Rect roi) {
	
	int offsetx = roi.x;
	int offsety = roi.y;

	// 计算中心位置
	int cx = roi.width / 2;
	int cy = roi.height / 2;

	// 计算角度
	int dx = right.x - left.x;
	int dy = right.y - left.y;
	double degree = 180 * ((atan2(dy, dx)) / CV_PI);
	Point2f center(cx, cy);

	// 旋转矩阵计算
	Mat M = getRotationMatrix2D(center, degree, 1.0);
	Rect bbox = RotatedRect(center, face.size(), degree).boundingRect();
	M.at<double>(0, 2) += (bbox.width / 2.0 - center.x);
	M.at<double>(1, 2) += (bbox.height / 2.0 - center.y);

	// 对齐
	Mat result;
	warpAffine(face, result, M, bbox.size());//仿射变换
	int length = (result.cols - face.cols) / 2;

	left = getPointAffinedPos(left, center, degree*CV_PI / 180);
	right = getPointAffinedPos(right, center, degree*CV_PI / 180);
	left.x += length;
	left.y += length;
	right.x += length;
	right.y += length;

	imshow("face-alignment", result);
	imwrite("face_alignment.jpg", result);
	return result;
}



int main(int argc, char* argv[])
{

	// Load pose estimation models.
	shape_predictor pose_model;
	deserialize("model\\shape_predictor_5_face_landmarks.dat") >> pose_model;

	//usb camera
	Mat image = imread("images/test1.jpg");
	//VideoCapture cam(0);
	Mat mb = imread("model/mb.jpg");
	Mat result_image;


	if (image.empty())
	{
		//fprintf(stderr, "Can not open camera.\n");
		return -1;
	}
	resize(image, image, Size(640, 360));
	cv_image<bgr_pixel> cimg(image);

	time_t start = clock();
	int * pResults = NULL;
	//pBuffer is used in the detection functions.
	//If you call functions in multiple threads, please create one buffer for each thread!
	unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
	if (!pBuffer)
	{
		fprintf(stderr, "Can not alloc buffer.\n");
		return -1;
	}

	///
	// CNN face detection
	// Best detection rate

	pResults = facedetect_cnn(pBuffer, (unsigned char*)(image.ptr(0)), image.cols, image.rows, (int)image.step);
	printf("%d faces detected.\n", (pResults ? *pResults : 0));
	Mat result_cnn = image.clone();

	//print the detection results
	if (*pResults)
	{
		//short * p = ((short*)(pResults + 1)) + 142 * i;
		short *p = (short*)(pResults + 1);
		int x = p[0];
		int y = p[1];
		int w = p[2];
		int h = p[3];
		int neighbors = p[4];
		int angle = p[5];

		printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
		
		cv::rectangle(result_cnn, Rect(x - 20, y - 40, w + 40, h + 40), Scalar(0, 255, 0), 2);
		Rect roi(x - 20, y - 40, w + 40, h + 40);
		Mat roi_image = result_cnn(Rect(x - 20, y - 40, w + 40, h + 40));
		//circle(roi_image, cvPoint(roi_image.cols / 2, roi_image.rows / 2), 3, cv::Scalar(0, 0, 255), -1);
	
		

		//Find the pose of each face.
		dlib::rectangle face;
		//std::vector<dlib::rectangle> faces;
		std::vector<full_object_detection> shapes;
		face.set_left(x);
		face.set_top(y);
		face.set_right(x + w);
		face.set_bottom(y + h);
		//faces.push_back(face);
		/*for (unsigned long i = 0; i < faces.size(); ++i)
			shapes.push_back(pose_model(cimg, faces[i]));*/
		shapes.push_back(pose_model(cimg, face));
		//draw 5 points
		if (!shapes.empty())
		{
			std::vector<CvPoint> keypoints;
			for (int i = 0; i < 5; i++)
			{
				circle(image, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 3, cv::Scalar(0, 0, 255), -1);
				CvPoint p(shapes[0].part(i).x(), shapes[0].part(i).y());
				cout << p.x << " " << p.y << endl;
				keypoints.push_back(p);
				//putText(image, to_string(i), cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), cv::FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255));
			}
			CvPoint p1, p2;
			p1.x = (keypoints[0].x + keypoints[1].x) / 2 - (x - 20);
			p1.y = (keypoints[0].y + keypoints[1].y) / 2 - (y - 40);
			p2.x = (keypoints[2].x + keypoints[3].x) / 2 - (x - 20);
			p2.y = (keypoints[2].y + keypoints[3].y) / 2 - (y - 40);

			/*circle(roi_image, p2, 3, cv::Scalar(0, 255, 255), -1);
			circle(roi_image, p1, 3, cv::Scalar(0, 255, 255), -1);*/

			imshow("roi_img", roi_image);


			Mat face_result = face_alignment(roi_image, p2, p1, roi);
			/*circle(face_result, p2, 2, cv::Scalar(255, 255, 255), -1);
			circle(face_result, p1, 2, cv::Scalar(255, 255, 255), -1);*/

			Mat mask = Mat::zeros(face_result.cols, face_result.rows, CV_8UC3);	
			Mat mb2roi(mask, Rect(p2.x - 55, p2.y - 77, 200, 200));
			mb.copyTo(mb2roi);

			imshow("mask", mask);

			/*double alpha = 0.8;
			double beta = 1 - alpha;
			addWeighted(face_result, alpha, mask, beta, 0.0, result_image);*/

			//cout << "result_image size is: " << result_image.cols << " " << result_image.rows << endl;

			Mat Image_Forehead = Mat::zeros(face_result.cols, face_result.rows, CV_8UC3);//额头
			Mat Image_Eyelid = Mat::zeros(face_result.cols, face_result.rows, CV_8UC3);//眼眶
			Mat Image_Cheek = Mat::zeros(face_result.cols, face_result.rows, CV_8UC3);//脸颊
			Mat Image_Nose = Mat::zeros(face_result.cols, face_result.rows, CV_8UC3);//鼻子
			Mat Image_Mouth = Mat::zeros(face_result.cols, face_result.rows, CV_8UC3);//嘴巴

			for (int i = 0; i < mask.rows; i++)
			{
				uchar* p = mask.ptr<uchar>(i);
				for (int j = 0; j < mask.cols; j++)
				{
					uchar b = p[3 * j + 0];
					uchar g = p[3 * j + 1];
					uchar r = p[3 * j + 2];

					if (b == 0 && g == 0 && r == 255)//额头 红
					{
						Image_Forehead.at<cv::Vec3b>(i, j) = face_result.at<cv::Vec3b>(i, j);
					}
					else if(b == 255 && g == 0 && r == 0)//眼眶 蓝
					{
						Image_Eyelid.at<cv::Vec3b>(i, j) = face_result.at<cv::Vec3b>(i, j);

					}
					else if (b == 0 && g == 255 && r == 255)//脸颊 黄
					{
						Image_Cheek.at<cv::Vec3b>(i, j) = face_result.at<cv::Vec3b>(i, j);

					}
					else if (b == 0 && g == 255 && r == 0)//鼻子 绿
					{
						Image_Nose.at<cv::Vec3b>(i, j) = face_result.at<cv::Vec3b>(i, j);

					}
					else if (b == 255 && g == 255 && r == 0)//嘴巴 青色
					{
						Image_Mouth.at<cv::Vec3b>(i, j) = face_result.at<cv::Vec3b>(i, j);

					}
					else
					{
						continue;
					}

				}
			}

			imshow("Image_Forehead", Image_Forehead);
			imshow("Image_Eyelid", Image_Eyelid);
			imshow("Image_Cheek", Image_Cheek);
			imshow("Image_Nose", Image_Nose);
			imshow("Image_Mouth", Image_Mouth);

		

		}
	}

	time_t end = clock();


	imshow("landmark", image);
	imshow("result_cnn", result_cnn);
	//imshow("result_image", result_image);
	//imwrite("result_image.jpg", result_image);

	//release the buffer
	free(pBuffer);

	//calculate running time
	double total_time = (double)(end - start) / CLOCKS_PER_SEC * 1000;
	cout << "total_time:" << total_time << "ms" << endl;

	waitKey(0);

	return 0;
}

未完待续...

  • 3
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值