必威体育Betway必威体育官网
当前位置:首页 > IT技术

奥比中光网络深度摄像头——人脸活体检测

时间:2019-06-07 07:43:09来源:IT技术作者:seo实验室小编阅读:70次「手机版」
 

奥比中光

最近一直在研发一个新的项目:基于深度摄像头的人脸活体识别,采用的是奥比中光的Astra Pro相机。

基于奥比中光的官方SDK进行开发

得到如下文件

1.第一步,在彩色图中添加OpenCV人脸检测代码,得到人脸框的位置坐标

2.第二步,根据人脸框的位置坐标对应到深度图中,标识出来(深度图和彩色图的大小一样,但是他们并没有对齐,这里只做效果)

3.第三步,计算深度图中标识出来的人脸框中所有像素点的均值和标准差,真人的深度图像素标准查明显大于照片中的像素标准差,可以自己设置一个阈值。

彩色图OpenCV人脸检测代码片段如下:

//更新彩色流
void update_color(astra::Frame& frame)
{
	const astra::ColorFrame colorFrame = frame.get<astra::ColorFrame>();
	if (!colorFrame.is_valid())
	{
		clear_view(colorView_);
		colorView_.texture_.update(&colorView_.buffer_[0]);			
		return;
	}
	const int colorWidth = colorFrame.width();
	const int colorHeight = colorFrame.height();
	init_texture(colorWidth, colorHeight, colorView_);
	if (ispaused_) { return; }
	const astra::RgbPixel* color = colorFrame.data();
	uint8_t* buffer = &colorView_.buffer_[0];

	{
		const astra::RgbPixel* colorT = color;
		cv::Mat frame_copy(colorHeight, colorWidth, CV_8UC3);//定义Mat

		for (int j = 0; j<colorHeight; j++)
		{
			for (int i = 0; i<colorWidth; i++)
			{
				frame_copy.at<cv::Vec3b>(j, i)[0] = colorT->b;//image.at<cv::Vec3b>(j, i)[0] / p * p + p / 2;
				frame_copy.at<cv::Vec3b>(j, i)[1] = colorT->g;
				frame_copy.at<cv::Vec3b>(j, i)[2] = colorT->r;
				colorT++;
			}
		}
		CascadeClassifier face_cascade;
		face_cascade.load("C:\\myfiles\\opencv-3.2.0\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml");
		std::vector<Rect> faces;
		Rect roi1;
		Mat frame_gray;
		cvtColor(frame_copy, frame_gray, COLOR_BGR2GRAY);//转换为灰度图
		equalizeHist(frame_gray, frame_gray);//直方图均衡化
		face_cascade.detectMultiscale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));//--人脸检测
		
		cv::Mat foo(colorHeight, colorWidth, CV_8UC3, (void*)color);
		rois.clear();
		for (size_t i = 0; i < faces.size(); i++)
		{
			Rect roi;
			roi.x = faces[static_cast<int>(i)].x;
			roi.y = faces[static_cast<int>(i)].y;
			roi.width = faces[static_cast<int>(i)].width;
			roi.height = faces[static_cast<int>(i)].height;
			rois.push_back(roi);
			cv::rectangle(foo, roi, cv::Scalar(255, 0, 0),3);//在彩色图中画出人脸
		}
		for (int i = 0; i < colorWidth * colorHeight; i++)
		{
			const int rgbaoffset = i * 4;
			buffer[rgbaOffset] = color[i].r;
			buffer[rgbaOffset + 1] = color[i].g;
			buffer[rgbaOffset + 2] = color[i].b;
			buffer[rgbaOffset + 3] = 255;
		}
	}	
	colorView_.texture_.update(&colorView_.buffer_[0]);
}

深度图人脸框标识和计算均值标准差的代码片段如下:

	//更新深度流
	void update_depth(astra::Frame& frame)
	{
		const astra::PointFrame pointFrame = frame.get<astra::PointFrame>();//获取点云帧

		if (!pointFrame.is_valid())
		{
			clear_view(depthView_);
			depthView_.texture_.update(&depthView_.buffer_[0]);
			return;
		}
		const int depthWidth = pointFrame.width();
		const int depthHeight = pointFrame.height();
		init_texture(depthWidth, depthHeight, depthView_);//数据纹理
		if (isPaused_) { return; }
		visualizer_.update(pointFrame);
		astra::RgbPixel* vizBuffer = visualizer_.get_output();
		uint8_t* buffer = &depthView_.buffer_[0];

		cv::Mat fool(depthHeight, depthWidth, CV_8UC3, (void*)vizBuffer);
		const astra::RgbPixel* colorT = vizBuffer;

		for (int i = 0; i < rois.size(); i++)
		{	
			Mat out = fool(Rect(rois[i].x, rois[i].y, rois[i].width, rois[i].height));//将人脸位置截取出来
			Mat means, stddev, covar;
			meanStdDev(out, means, stddev);//计算src图片的均值和标准差
			double stddev_sum = 0;
			double stddev_avg = 0;
			for (int row = 0; row < means.rows; row++)
			{
				stddev_sum = stddev_sum + stddev.at<double>(row);
			}
			stddev_avg = stddev_sum / means.rows;//计算平均标准差
			stringstream ss,sss;
			ss << "real_" << stddev_avg;
			sss << "unreal_" << stddev_avg;
			int font = cv::FONT_HERSHEY_COMPLEX;
			if (stddev_avg > 60)
			{
				printf("真人!标准差 = %.3f\n", stddev_avg);
				cv::rectangle(fool,rois[i], cv::Scalar(255, 0, 0),3);//在深度图中画出人脸
				cv::putText(fool, ss.str(), cvPoint(rois[i].x, rois[i].y),font,1.5, cv::Scalar(255, 0, 0),2);
			}
			else
			{
				printf("假人!标准差 = %.3f\n", stddev_avg);
				cv::rectangle(fool, rois[i], cv::Scalar(0, 255, 0),3);//在深度图中画出人脸
				cv::putText(fool, sss.str(), cvPoint(rois[i].x, rois[i].y), font, 1.5, cv::Scalar(0, 255, 0),2);
			}
		}
		
		for (int i = 0; i < depthWidth * depthHeight; i++)
		{
			const int rgbaOffset = i * 4;//4通道
			buffer[rgbaOffset] = vizBuffer[i].r;//第一个通道
			buffer[rgbaOffset + 1] = vizBuffer[i].g;//第二个通道
			buffer[rgbaOffset + 2] = vizBuffer[i].b;//第三个通道
			buffer[rgbaOffset + 3] = 255;//第四个通道
		}
		depthView_.texture_.update(&depthView_.buffer_[0]);
	}

效果如下:

相关阅读

摄像头视频采集

一个录屏软件的流程基本就是: 图像采集 图像编码 将解码好的图像封装成视频 图像的采集: FFmpeg中有一个和多媒体设备

深度分析:最近融资千万的社交产品恋爱圈,到底凭的啥?

最近,一款名叫恋爱圈的社交产品获得了一笔千万的融资,作者对这款产品深度体验后进行了如下分析。最近,36Kr报道了一款名叫恋爱圈的社

长文深度解析:国内证券业的不安与未来

国内证券业发展至今已有二十多年,受国内市场环境和金融监管影响已形成独具特色的商业模式。而今,随着科技快速发展和社会结构的演变

深度解密 | 如何避开网红营销那些“坑”

网红营销模式的成功,直接加剧了优质网红资源的竞争,一类公司选择收拢网红资源,做中间商赚差价;另一类公司选择前期孵化,中后期营销变现

Android USBCamera,UVCCamera开发通用库,我试用了普通的

Android直播开发之旅(10):AndroidUSBCamera,UVCCamera开发通用库

分享到:

栏目导航

推荐阅读

热门阅读