c++实现情绪识别

在上一篇使用python实现情绪识别的基础上,使用c++实现情绪识别。

 

这里的人脸检测模块不是使用dlib模块(使用dlib模块也可以,测试以后发现速度比较慢),这里使用另外一个开源的模块。

facedetect-dll.h,可以去我的资源里下载。里面的眉毛斜率检测模块,因为c++没有np.polyfit,所以需要自己实现(参考最小二乘)。

 

 

#include <fstream>  
#include <string>  
#include <iostream>  
//#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 <dlib/image_io.h>
#include <opencv2/core/core.hpp>  
//#include <dlib/timer.h>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include "highgui.h"
#include "lib\facedetect-dll.h"
#include <iostream>
#include <cstdlib>
#include "lib\facedetect-dll.h"
using namespace cv;
using namespace std;
using namespace dnn;
float LineFitLeastSquares(float *data_x, float *data_y, int data_n);
// ----------------------------------------------------------------------------------------
//
#define DETECT_BUFFER_SIZE 0x20000
int main()
{


	const char* path = "E:/fangtu1/1/FTA001190217537664_一寸照.jpg";
	unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);

	//auto src = cv::imread("C:/Users/01/Desktop/face/CNN_Face_Glass_Classfy-master/face7.jpg");
	auto src = cv::imread(path);
	Mat gray;
	cvtColor(src, gray, CV_BGR2GRAY);
	auto pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48, 0, 1);
	int i = 0;
	short * p = ((short*)(pResults + 1)) + 142 * i;
	int x = p[0];
	int y = p[1];
	int w = p[2];
	int h = p[3];
	int neighbors = p[4];
	int angle = p[5];
	const char *saveFilePath = "F:\\00res.jpg";
	printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
	//cv::rectangle(src, Rect(x-w/2, y, w, h), Scalar(0, 255, 0), 2);

	cv::rectangle(src, Rect(x, y, w, h), Scalar(0, 255, 0), 2);
	//cv::rectangle(src, Rect(x + w + w / 16, y + h / 3, w / 5, h / 5), Scalar(255, 0, 0), 2);
	//cv::rectangle(src, Rect(x + w + w / 16, y + 4 * h / 3, w / 5, h / 5), Scalar(0, 0, 225), 2);
	//cout << "hehe" << x << y << w << h << endl;

	 save roi image  
	设定感兴趣的区域ROI
	//cv::Mat m_roi = src(cv::Rect(x, y, w, h));


	
	//cv::Mat PR_m_roi = src(cv::Rect(x + w + w / 16, y + h / 3, w / 5, h / 5));
	//cv::Mat FO_m_roi = src(cv::Rect(x + w + w / 16, y + 4 * h / 3, w / 5, h / 5));
	//imshow("Results_multiview_reinforce", PR_m_roi);
	//imshow("Results_multiview_reinforce1", FO_m_roi);
	if (1)
	{
		for (int j = 17; j < 21; j++)
		{ 
			cv::circle(src, Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), 1, Scalar(0, 255, 0));
			cout << "hehe" << p[6 + 2 * j]<<"========="<< p[6 + 2 * j + 1]<< endl;
			
		};
		/*cv::rectangle(src, Rect(p[6 + 2 * 62], p[6 + 2 * 62 + 1], 1, 1), Scalar(0, 225, 0), 2);
		cv::rectangle(src, Rect(p[6 + 2 * 66], p[6 + 2 * 66 + 1], 1, 1), Scalar(0, 0, 225), 2);*/
		float mouth_higth = (p[6 + 2 * 66 + 1] - p[6 + 2 * 62 + 1]) / (float) p[2];  //嘴巴张开程度
		float eye_sum = ((p[6 + 2 * 41 + 1] - p[6 + 2 * 37 + 1]) + (p[6 + 2 * 40 + 1] - p[6 + 2 * 38 + 1]) + (p[6 + 2 * 47 + 1] - p[6 + 2 * 43 + 1]) + (p[6 + 2 * 46 + 1] - p[6 + 2 * 44 + 1]));
		float eye_hight = (eye_sum / 4) / (float)p[2];
		//计算眉毛的角度
		float pX[4] = { p[6 + 2 * 17],
					     p[6 + 2 * 18],
						 p[6 + 2 * 19],
						 p[6 + 2 * 20] };
		float pY[4] = { p[6 + 2 * 17+1],
						 p[6 + 2 * 18 + 1],
						 p[6 + 2 * 19 + 1],
						 p[6 + 2 * 20 + 1] };

		//cout << "====" <<  p[6 + 2 * 17] << "====" << p[6 + 2 * 18] << "====" << p[6 + 2 * 19] << "====" << p[6 + 2 * 20] << endl;
		//cout << "====" << p[6 + 2 * 17+1] << "====" << p[6 + 2 * 18 + 1] << "====" << p[6 + 2 * 19 + 1] << "====" << p[6 + 2 * 20 + 1] << endl;
		//float pX[4] = { 97, 105, 115, 124 };
		//float pY[4] = { 105, 101, 101, 105 };
		float brow_k =-LineFitLeastSquares(pX, pY, 4);//使用最小二乘法计算眉毛的斜率。
       
		if (mouth_higth >= 0.03)
		{
			if (eye_hight >= 0.056)
			{

				cout << "amazing" << endl;
			}
			else
			{
				cout << "happy" << endl;
			}
		}
		else
		{
			if (brow_k <= -0.03)
			{
				cout << "angry" << endl;
			}
			else
			{
				cout << "nature" << endl;
			}

		}
		cout << "mouth_higth" << mouth_higth << endl;
		cout << "eye_hight" << eye_hight << endl;
		cout << "brow_k" << brow_k << endl;
	//	//cv::rectangle(src, Rect(1254, 1436, 160, 160), Scalar(0, 0, 225), 2);
	//	//cv::rectangle(src, Rect(1407, 1422, 160, 160), Scalar(0, 225, 0), 2);
	//	//cv::rectangle(src, Rect(1254-1, 1436-(1407-1254)/2, (1407 - 1254), (1407 - 1254)), Scalar(0, 0, 225), 2);
	//	//cv::rectangle(src, Rect(1323, 1441, 160, 160), Scalar(25, 0, 0), 2);
}

	检测眼镜的大小
	//float rate_oc, di1, di2;
	//di1 = (p[6 + 2 * 44] - p[6 + 2 * 43]) / 2 + (p[6 + 2 * 46] - p[6 + 2 * 47]) / 2;
	//di2 = (p[6 + 2 * 47 + 1] - p[6 + 2 * 43 + 1]) / 2 + (p[6 + 2 * 46 + 1] - p[6 + 2 * 44 + 1]) / 2;
	//rate_oc = di2 / di1;
	检测眼镜的大小
	检测右眼的位置
	//cout << "plaese open hear" << rate_oc << endl;
	//cv::Mat yanjing1 = src(cv::Rect(p[6 + 2 * 42] - 1, p[6 + 2 * 42 + 1] - (p[6 + 2 * 45] - p[6 + 2 * 42]) / 2, (p[6 + 2 * 45] - p[6 + 2 * 42]), 2 * (p[6 + 2 * 45] - p[6 + 2 * 42]) / 3));
	//imshow("Results_multiview_reereinforce", yanjing1);
	检测左眼的位置
	//cv::Mat yanjing2 = src(cv::Rect(p[6 + 2 * 36] + 1, p[6 + 2 * 36 + 1] - (p[6 + 2 * 39] - p[6 + 2 * 36]) / 2, (p[6 + 2 * 39] - p[6 + 2 * 36]), 2 * (p[6 + 2 * 39] - p[6 + 2 * 36]) / 3));
	//imshow("Results_multiview_reereinfor123ce", yanjing2);
	把检测到ROI区域进行保存。
	//imwrite("OPEN_CLOSE_RIGHT.jpg", yanjing1);
	//imwrite("OPEN_CLOSE_LEGHT11.jpg", yanjing2);
	//namedWindow("enhanced", 0);
	//resizeWindow("enhanced", 640, 480);
	imshow("enhanced", src);
	waitKey(0);
	//free(pBuffer);
	return 0;
}
// ----------------------------------------------------------------------------------------
/*************************************************************************
 最小二乘法拟合直线,y = a*x + b; n组数据; r-相关系数[-1,1],fabs(r)->1,说明x,y之间线性关系好,fabs(r)->0,x,y之间无线性关系,拟合无意义
 a = (n*C - B*D) / (n*A - B*B)
 b = (A*D - B*C) / (n*A - B*B)
 r = E / F
 其中:
 A = sum(Xi * Xi)
 B = sum(Xi)
 C = sum(Xi * Yi)
 D = sum(Yi)
 E = sum((Xi - Xmean)*(Yi - Ymean))
 F = sqrt(sum((Xi - Xmean)*(Xi - Xmean))) * sqrt(sum((Yi - Ymean)*(Yi - Ymean)))
**************************************************************************/
float LineFitLeastSquares(float *data_x, float *data_y, int data_n)
{
	float A = 0.0;
	float B = 0.0;
	float C = 0.0;
	float D = 0.0;
	float E = 0.0;
	float F = 0.0;
	for (int i = 0; i < data_n; i++)
	{
		A += data_x[i] * data_x[i];
		B += data_x[i];
		C += data_x[i] * data_y[i];
		D += data_y[i];
	}
	// 计算斜率a和截距b  
	float a, b, temp = 0;
	if (temp = (data_n*A - B * B))// 判断分母不为0  
	{
		a = (data_n*C - B * D) / temp;
		b = (A*D - B * C) / temp;
	}
	else
	{
		a = 1;
		b = 0;
	}
	// 计算相关系数r  
	float Xmean, Ymean;
	Xmean = B / data_n;
	Ymean = D / data_n;
	float tempSumXX = 0.0, tempSumYY = 0.0;
	for (int i = 0; i < data_n; i++)
	{
		tempSumXX += (data_x[i] - Xmean) * (data_x[i] - Xmean);
		tempSumYY += (data_y[i] - Ymean) * (data_y[i] - Ymean);
		E += (data_x[i] - Xmean) * (data_y[i] - Ymean);
	}
	F = sqrt(tempSumXX) * sqrt(tempSumYY);
	float r;
	r = E / F;
	//cout << "a" << a << endl;
	//cout << b << endl;
	//cout << r^2 << endl;
	return a;
}




 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值