图像处理--linux opencv2多线程人脸识别

1.多线程

   多线程处理可以同时运行多个线程。由于多线程应用程序将程序划分成多个独立的任务,因此可以在以下方面显著提高性能:

(1)多线程技术使程序的响应速度更快 ,因为用户界面可以在进行其它工作的同时一直处于活动状态;

(2)当前没有进行处理的任务时可以将处理器时间让给其它任务;

(3)占用大量处理时间的任务可以定期将处理器时间让给其它任务;

(4)可以随时停止任务;

(5)可以分别设置各个任务的优先级以优化性能。

 

是否需要创建多个线程取决于各种因素。在以下情况下,最适合采用多线程处理:

(1)耗时或大量占用处理器的任务阻塞用户界面操作;

(2)各个任务必须等待外部资源(如远程文件或 Internet连接)。

同样的 ,多线程也存在许多缺点 ,在考虑多线程时需要进行充分的考虑。

多线程的主要缺点包括: 

(1)等候使用共享资源时造成程序的运行速度变慢。这些共享资源主要是独占性的资源 ,如打印机等。

(2)对线程进行管理要求额外的 CPU开销。线程的使用会给系统带来上下文切换的额外负担。

            当这种负担超过一定程度时,多线程的特点主要表现在其缺点上,比如用独立的线程来更新数组内每个元素。

(3)线程的死锁。即较长时间的等待或资源竞争以及死锁等多线程症状。

(4)对公有变量的同时读或写。当多个线程需要对公有变量进行写操作时,后一个线程往往会修改掉前一个线程存放的数据,从而使前一个线程的参数被修改;

        另外 ,当公用变量的读写操作是非原子性时,在不同的机器上,中断时间的不确定性,会导致数据在一个线程内的操作产生错误,从而产生莫名其妙的错误,而这种错误是程序员无法预知的。

2.opencv2人脸识别

 人脸识别使用的分类器为haarcascade_frontalface_alt.xml

<pre name="code" class="cpp">string face_cascade_name = "../conf/haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade1;
boost::thread thread_ocr_1;
boost::thread thread_face;
concurrent_queue<std::pair<Mat, string> > g_cap_buff;//存储摄像头采集的图片 存储方式(图片|时间)

//人脸识别

void task_do_ocr_1() {
	try {
		while (true) {
			int cap_size1 = g_cap_buff.get_size();
			if (cap_size1 > 0)
			{
				double t1 = cvGetTickCount();
				std::string t1_ms_start = get_time_usmm();
				std::pair<Mat, string> image_stamp1;
				g_cap_buff.wait_and_pop(image_stamp1);
				Mat img1 = image_stamp1.first;
				string ts1 = image_stamp1.second;
				if (ts1 == "END") {
					thread_ocr_1.interrupt();
				}
				if (!img1.data) {
					continue;
				}
				std::vector<Rect> faces1;
				Mat image_gray1;
				if (img1.channels() == 1) {
					img1.copyTo(image_gray1);
				} else {
					cvtColor(img1, image_gray1, CV_BGR2GRAY);
				}
				equalizeHist(image_gray1, image_gray1);
				double t2 = cvGetTickCount();
				//
				face_cascade1.detectMultiScale(image_gray1, faces1, 1.2,2,0 | CV_HAAR_SCALE_IMAGE, Size(40, 40));
				double t3 = cvGetTickCount();
				double t3_2 = (t3 - t2) / cvGetTickFrequency() / 1000;

							for (int i1 = 0; i1 < faces1.size(); i1++) {
					Point center1(faces1[i1].x + faces1[i1].width * 0.5,
							faces1[i1].y + faces1[i1].height * 0.5);
					ellipse(img1, center1,
							Size(faces1[i1].width * 0.5,
									faces1[i1].height * 0.5), 0, 0, 360,
							Scalar(255, 0, 255), 4, 8, 0);
				}

				g_face_buff.push_back(make_pair(img1, ts1));          //
				double t4 = cvGetTickCount();
			    double t4_1 = (t4 - t1) / cvGetTickFrequency() / 1000;
				cout<<" t3_2 "<<t3_2<<" t4_1 "<<t4_1<<endl;

			}
			boost::this_thread::interruption_point();

		}
	} catch (...) {
		cout << "exit 12 " << g_cap_buff.get_size() << endl;
		exit(0);
	}
}

//人脸识别显示
void face_show() {
	try {
		while (true) {
			int face_size = g_face_buff.size();
			if (face_size >4)
			{
				nCoutface++;
				double t11f = cvGetTickCount();
				std::pair<Mat, string> image_stamp_face;
				image_stamp_face=g_face_buff[0];
				string tsm = image_stamp_face.second;
				int min_l=0;
				for (int l=0; l < g_face_buff.size(); l++) {
							std::pair<Mat, string> image_stampl;
							image_stampl=g_face_buff[l];
							string tsl = image_stampl.second;
                            if(tsm>tsl)
                            {
                            	min_l=l;
                            }
							}
				image_stamp_face=g_face_buff[min_l];
			    std::vector<std::pair<Mat, string> >::iterator it = g_face_buff.begin()+min_l;
			    g_face_buff.erase(it);
				Mat imgf = image_stamp_face.first;
				string tsf = image_stamp_face.second;
				if (tsf == "END") {
					thread_face.interrupt();
				}
				if(!imgf.data)
					continue;
				cout << "show img face face_size " <<face_size<<" nCoutface "<<nCoutface<<" "<<tsf<< endl;
			    cv::imshow(Windname, imgf);
			    cv::waitKey(1);
			}
			boost::this_thread::interruption_point();
		}
	} catch (...) {
		cout << "exit f2 " << g_face_buff.size() << endl;
		exit(-1);
	}
}


//主函数中,调用人脸识别线程与人脸识别显示线程
thread_ocr_1 = boost::thread(boost::bind(&task_do_ocr_1));
thread_face = boost::thread(boost::bind(&face_show));


 
 






























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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值