opencv对视频进行人脸识别--使用videoCapture类

前言

使用libfacedetection库,我们能对一张图像进行人脸识别,那我们能否对多张图像进行识别呢,那就是接下来要说的,对一段视频进行人脸识别。

一、libfacedetection的配置及基本介绍:

这篇文章中我们进行了详细的介绍:https://blog.csdn.net/ivan_9/article/details/113336452

二、VideoCapture类:

1、构造函数类型:

2.1.1、VideoCapture();

简介:VideoCapture();是VideoCapture类的默认构造函数;

2.1.2、VideoCapture(const String& filename, int apiPreference = CAP_ANY);

简析:打开视频文件或捕获设备或IP视频流,以便使用API首选项进行视频捕获
filename此参数可以是:

  • 视频文件的名称(例如视频.avi)
  • 图像序列(例如“img\uu02d.jpg”,它将读取“img\u 00.jpg,img\u 01.jpg,img\u 02.jpg,…”)
  • 视频流的URL(例如协议://主机:端口/脚本名称?脚本|参数| auth
  • gst启动工具格式的GStreamer管道字符串,以防GStreamer用作后端,每个视频流或IP摄像机feed都有自己的URL方案
  • 首选要使用的捕获API后端。可用于强制特定读取器

2.1.3、VideoCapture(int index, int apiPreference = CAP_ANY);

简析:打开摄像头进行视频捕获

  • 要打开的视频捕获设备的参数索引id。
  • 使用默认后端打开默认相机,只需传递0。其他外接的摄像头或其他相机,传递1即可。
  • apippreference首选要使用的捕获API后端。可用于强制特定读取器
  • 如果有多个可用的实现:例如e.g. cv::CAP_DSHOW or cv::CAP_MSMF or cv::CAP_V4L.

2、构造函数具体定义:

class CV_EXPORTS_W VideoCapture{
public:
    CV_WRAP VideoCapture();
    CV_WRAP explicit VideoCapture(const String& filename, int apiPreference = CAP_ANY)
    CV_WRAP explicit VideoCapture(int index, int apiPreference = CAP_ANY);
}

三、VideoCapture类的函数:

1、open();函数

简介:打开用于视频捕获的视频文件、捕获设备或IP视频流。

3.1.1、第一种使用:

VideoCapture capture;
captrue.open("有趣的灵魂.mp4");//可以是avi,可以是mp4格式的视频文件

3.1.2、第二种使用:

VideoCapture capture("有趣的灵魂.mp4");//利用构造函数直接获取

2、isOpened()函数:

简析:如果已初始化视频捕获,则返回true,判断是否读取成功

if (cap.isOpened()) {
	cout << "恭喜你打开视频文件了!" << endl;
}
else {
	cout << "对不起你没打开视频文件!" << endl;
	return -1;
}

3、release()函数:

简析:关闭视频文件或捕获设备,与open()函数是相对应的,最好不要漏了release()函数

VideoCapture capture;
captrue.open("有趣的灵魂.mp4");
cap.release();

4、grab()函数与retrieve()函数:

简析:grab()函数从视频文件或照相机中获取下一帧,并返回true(成功的例子)。

该函数为每个摄像机调用VideoCapture::grab(),然后调用调用较慢的方法VideoCapture::retrieve()解码并从每个摄像机获取帧。这种方式消除了去马赛克或运动jpeg解压等的开销,恢复了帧从不同的摄像机会在时间上更接近。

简析:retrieve()函数解码并返回抓取的视频帧。

该方法解码并返回刚刚抓取的帧。如果没有抓到帧(相机已断开连接,或者视频文件中没有更多帧),该方法返回false。函数返回一个空图像(使用%cv::Mat,使用Mat::empty()测试它)

//这两个函数一般一起使用
cap.grab();
cap.retrieve(src);//src是每帧的图像对象

5、read()函数:

简析:获取、解码并返回下一个视频帧

cap.read(src);

6、set()函数:

简析:设置VideoCapture中的属性

cap.set(3, 480)
//把视频流的帧(图片)的高度调成480帧的,宽度为5

6、get()函数:

简析:返回指定的VideoCapture属性

cap.get(0)
//视频文件的当前位置(播放)以毫秒为单位

四、视频的人脸识别

代码块:

//视频的人脸识别
#include <iostream>
#include <opencv2/opencv.hpp>
#include <facedetectcnn.h>
#include <stdlib.h>
#define DETECT_BUFFER_SIZE 0x20000 //定义缓冲区大小
#define FACEDETECTION_EXPORT

using namespace std;
using namespace cv;
int main() {
	Mat src, dst, image;
	VideoCapture cap;
	int count = 1;
	cap.open("D:\\Myfile\\素材照片\\视频图像截取\\视频1.avi");
	if (cap.isOpened()) {
		//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;
		}
		system("cls");  //清屏
		while (true)
		{
			cap >> src;// cap.read(src);
			if (!src.data) {	//若不存在就返回 could not load your image!
				cout << "could not load your image!" << 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" ;	//输出检测人脸耗费时长
			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];
				if (confidence < 88) {
					cout << "------这帧图像没有人脸!!!\n\n";
					continue;
				}
				else cout << "--这帧图像有人脸!!!\n";
				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);
				image = dst(Rect(x, y, w, h));
				//画五个不同颜色的面部标志
				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操作符将点坐标转换为指定的类型。
				从浮点坐标到整数坐标的转换是通过舍入完成的。
				通常,转换对每个坐标都使用此操作。
				*/
				printf("face %d: confidence=%d, [%d, %d, %d, %d] (%d,%d) (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n\n",
					i, confidence, x, y, w, h, p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14]);
				namedWindow("output_detect_image", WINDOW_AUTOSIZE);
				imshow("output_detect_image", dst);	//输出识别后的图像
				string str = "D:\\Myfile\\素材照片\\视频图像截取\\" + to_string(count) + ".jpg"; //制定保存的命名规则
				imwrite(str, image); //将人脸截取出来并保存起来

				count++;

				waitKey(4000); //让每一张图片停留4s
			}
		}
		//release the buffer
		delete pBuffer; 
	}
	else cout << "could not load video!" << endl;
	cap.release();
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

总结

本文简述了videoCapture类的使用,并且进行了视频的人脸识别

参考来源

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

如有疑问,请留言!
如有错误,敬请指教!

  • 6
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,这是一个关于php_opencv使用VideoCapture进行人脸识别和处理的问题。首先,需要确保你已经安装了php_opencv扩展,并且已经熟悉了OpenCV的基本概念和使用方法。 接下来,我们可以使用VideoCapture来读取视频文件或者直接从摄像头中获取视频流。对于人脸识别,我们可以使用OpenCV提供的人脸检测器来进行人脸识别,比如Haar Cascade分器。 具体实现可以参考以下步骤: 1. 创建一个VideoCapture对象,用于读取视频文件或者获取摄像头视频流。 ```php $cap = new CvCapture($video_file); // 或者 $cap = new CvCapture(0); 获取摄像头视频流 ``` 2. 加载Haar Cascade分器,用于人脸检测。 ```php $face_cascade = new CvHaarClassifierCascade(file_get_contents('haarcascade_frontalface_alt.xml')); ``` 3. 循环读取视频帧,进行人脸检测和处理。 ```php while (true) { // 读取视频帧 $frame = $cap->queryFrame(); // 如果视频结束,则退出循环 if (!$frame) { break; } // 进行人脸检测 $gray = $frame->convertColor(CV_BGR2GRAY); $faces = $face_cascade->detectMultiScale($gray); // 处理每个检测到的人脸 foreach ($faces as $face) { // 在人脸周围绘制矩形框 $frame->rectangle($face->x, $face->y, $face->x + $face->width, $face->y + $face->height, [0, 255, 0]); // 对人脸进行处理,比如进行美颜等操作 // ... } // 显示处理后的视频帧 $frame->showImage(); } ``` 在这个循环中,我们首先读取视频帧,然后进行人脸检测,接着对每个检测到的人脸进行处理,最后显示处理后的视频帧。 注意,以上代码只是一个简单的示例,具体的人脸处理方法可以根据你的需求来实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值