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));