opencv画像の顔認識

序文

Opencv画像の顔認識、libfacedetectionライブラリを使用して画像の顔認識を実行します

1.画像分析と使用

参照:
https//blog.csdn.net/ivan_9/article/details/113336452
https://blog.csdn.net/ivan_9/article/details/113177480

2.基本原則:

1. imread()関数を使用して、画像を読み取ります。

Mat src;
src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\7.jpg");  //导入需要识别的图像	

2.メモリスペースを割り当てます。

//pBuffer用来检测人脸
	unsigned char* pBuffer = new unsigned char[DETECT_BUFFER_SIZE];  //multiple threads
	//是多线程时,要分配内存空间
	if (!pBuffer) {
    
     //如果无法分配内存,就返回could not alloc buffer!
		cout << "could not alloc buffer!" << endl;
		return 0;
	}

3.顔検出:

int* pResults = NULL; //用来检测人脸
pResults = facedetect_cnn(pBuffer, (unsigned char*)(src.ptr(0)), src.cols, src.rows, src.step);

4.顔の領域を描画します。

for (int i = 0; i < (pResults ? (*pResults) : 0); i++) {
    
    
		//如果pResult为NULL,即pResult没有检测到人脸,就返回0,for循环结束
		short* p = ((short*)(pResults + 1)) + (142 * i);
		//p指针用来指向
		int confidence = p[0];
		int x = p[1];
		int y = p[2];
		int w = p[3];
		int h = p[4];
		//显示脸的分数。其范围为[0-100]
		char sScore[256];
		snprintf(sScore, 256, "%d", confidence);
		putText(dst, sScore, Point(x, y - 3), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
		//计算文本字符串的宽度和高度。
		//把脸用矩形画出来
		rectangle(dst, Rect(x, y, w, h), Scalar(0, 255, 0), 2);
		//画五个不同颜色的面部标志
		circle(dst, Point(p[5], p[5 + 1]), 1, Scalar(255, 0, 0), 2);
		circle(dst, Point(p[5 + 2], p[5 + 3]), 1, Scalar(0, 0, 255), 2);
		circle(dst, Point(p[5 + 4], p[5 + 5]), 1, Scalar(0, 255, 0), 2);
		circle(dst, Point(p[5 + 6], p[5 + 7]), 1, Scalar(255, 0, 255), 2);
		circle(dst, Point(p[5 + 8], p[5 + 9]), 1, Scalar(0, 255, 255), 2);
	}

5. 5つのパラメーター:

intconfidence = p [0];
confidenceパラメータは認識率の大きさを示します
intx = p [1];
int y = p [2];
x、yは画像全体で認識されたポートレートの位置を示します。は、左上隅です。位置は(x、y)
int w = p [3];
int h = p [4];
w、hは認識されたポートレートの幅と長さを表します

例:信頼度パラメーターを使用して、認識率が90未満のポートレートの描画をキャンセルできます。

if (confidence < 90) {
    
    
	cout << "这张图像识别率小于90%!!!\n\n";
	continue;
}

第三に、顔認識の特定の操作

コードブロック

#include <iostream>
#include <opencv2/opencv.hpp>
#include <facedetectcnn.h>
#define DETECT_BUFFER_SIZE 0x20000 //定义缓冲区大小
#define FACEDETECTION_EXPORT

using namespace std;
using namespace cv;
int main() {
    
    
	Mat src, dst;
	src = imread("D:\\Myfile\\素材照片\\opencv素材照片\\7.jpg");  //导入需要识别的图像	
	if (!src.data) {
    
    	//若不存在就返回 could not load your image!
		cout << "could not load your image!" << endl;
		return 0;
	}
	//pBuffer用来检测人脸
	unsigned char* pBuffer = new unsigned char[DETECT_BUFFER_SIZE];  //multiple threads
	//是多线程时,要分配内存空间
	if (!pBuffer) {
    
     //如果无法分配内存,就返回could not alloc buffer!
		cout << "could not alloc buffer!" << endl;
		return 0;
	}
	dst = src.clone();	//将src原图像复制给dst
	TickMeter myClock;	//计时器
	myClock.start();
	int* pResults = NULL; //用来检测人脸
	pResults = facedetect_cnn(pBuffer, (unsigned char*)(src.ptr(0)), src.cols, src.rows, src.step);
	//利用facedetect_cnn函数来获取人脸,用于存储人脸检测结果的缓冲存储器!其大小必须为0x20000字节
	//facedetect_cnn函数识别的图像必须为BGR三通道的图像,而非rgb图像
	myClock.stop();
	cout << myClock.getTimeSec() << "s" << endl;	//输出检测人脸耗费时长
	for (int i = 0; i < (pResults ? (*pResults) : 0); i++) {
    
    
		//如果pResult为NULL,即pResult没有检测到人脸,就返回0,for循环结束
		short* p = ((short*)(pResults + 1)) + (142 * i);
		//p指针用来指向
		int confidence = p[0];
		int x = p[1];
		int y = p[2];
		int w = p[3];
		int h = p[4];
		//显示脸的分数。其范围为[0-100]
		char sScore[256];
		snprintf(sScore, 256, "%d", confidence);
		/*从给定位置加载数据,转换为字符串等价版本,并将结果写入各种池。
			1) 写结果到 stdout 。2) 写结果到文件流 stream 。3) 写结果到字符串 buffer 。
			4) 写结果到字符串 buffer 。至多写 buf_size - 1 个字符。产生的字符串会以空字符终止,除非 buf_size 为零。
			若buf_size为零,则不写入任何内容,且buffer可以是空指针,然而依旧计算返回值(会写入的字符数,不包含空终止符)并返回。
			若调用 sprintf 或 snprintf 导致在重叠的对象间发生复制,则行为未定义。
			(例如 sprintf(buf, "%s text", buf); )*/
		putText(dst, sScore, Point(x, y - 3), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
		//计算文本字符串的宽度和高度。
		//把脸用矩形画出来
		rectangle(dst, Rect(x, y, w, h), Scalar(0, 255, 0), 2);
		//画五个不同颜色的面部标志
		circle(dst, Point(p[5], p[5 + 1]), 1, Scalar(255, 0, 0), 2);
		circle(dst, Point(p[5 + 2], p[5 + 3]), 1, Scalar(0, 0, 255), 2);
		circle(dst, Point(p[5 + 4], p[5 + 5]), 1, Scalar(0, 255, 0), 2);
		circle(dst, Point(p[5 + 6], p[5 + 7]), 1, Scalar(255, 0, 255), 2);
		circle(dst, Point(p[5 + 8], p[5 + 9]), 1, Scalar(0, 255, 255), 2);
		//circle()绘制简单或粗椭圆弧或填充椭圆扇区。
		/*
		Point类的实例可以与C结构、CvPoint和CvPoint2D32f互换。
		还有一个cast操作符将点坐标转换为指定的类型。
		从浮点坐标到整数坐标的转换是通过舍入完成的。
		通常,转换对每个坐标都使用此操作。
		*/
	}

	namedWindow("output_detect_image", WINDOW_AUTOSIZE);
	imshow("output_detect_image", dst);	//输出识别后的图像

	waitKey(0);
	return 0;
}


実行結果:
ここに画像の説明を挿入
写真を変更して、このハンサムな男を見てみましょう:
ここに画像の説明を挿入

総括する:

この記事では、libfacedetectionライブラリを使用したopencv画像の顔認識の使用について説明し、マークするポイントを描画します

参考資料

https://github.com/ShiqiYu/libfacedetection#cnn-based-face-detection-on-windows


ご不明な点がございましたら、メッセージを残してください!エラーが発生した場合は、アドバイスしてください!

おすすめ

転載: blog.csdn.net/ivan_9/article/details/113804559