Solaris下人脸识别程序(OpenCV linux 多线程版本)
一、Solaris下OpenCV工具安装
1. 选择OpenCV的linux版本OpenCV2.2,链接地址为http://www.opencv.org.cn/download/OpenCV-2.2.0.tar.bz2,下载后解压并放到linux目录下。
2. OpenCV2.2的编译需要借助cmake工具,cmake下载的链接地址为
http://www.cmake.org/cmake/resources/software.html,下载后解压并上传到Solaris中。
Cmake工具的安装分为3步骤
首先./configure 这时可以选择安装目录 --prefix=/usr/local/cmake
然后make编译
最后make install安装到Solaris系统中
在安装后发现cmake命令还是用不了,这时一方面检查/usr/local/bin中是否有cmake命令,另一方面可以重新登录看是否能用。
3.进入OpenCV的解压目录,输入cmake命令
会出现如下错误提示
该提示为cc命令的问题
在solaris中cc命令是没有安装无法使用的,为了解决这一问题,将gcc链接到cc命令上,使得cc不再没有意义,编译过程利用cc能够顺利完成。
3. 接着输入命令”cmake .”,提示配置完毕后,可以看到OpenCV目录下多个很多文件包括Makefile文件。
4. 输入make进行编译。在编译过程中可能会出现错误提示如下
这个问题可以通过在CMakeList.txt文件中的C_Flags参数中加入-std=c99解决,在文件的变量EXTRA_C_FLAGS中添加CFlags参数。
此外在编译过程中还可能出现pthread的警告,经分析,这是因为在Solaris下面引入pthread库的名称略有不同,改为pthreads就可以了。
5. 这样基本就可以将OpenCV编译完成。紧接着输入命令
make install完成OpenCV到系统的安装。
二、人脸识别程序编译、运行
1. 首先编写人脸识别程序,和在Windows下基本相同。需要注意的是Solaris下面的可能会缺少某些库,如在遍历目录子文件时,如果缺少io.h则需要采用其他方法替代。
2. 编译
3.运行 ./FaceDetect
首先配置OpenCV到环境变量
第一次运行时,又发现了一个严重的问题,即png库的冲突,直接导致png
图片的加载失败。警告信息提示如下:
解决这个问题的步骤:
首先发现目前的Solaris系统下面没有libpng-1.4.3,于是下载安装了一个。安装
到的路径为
然后将usr/include /usr/lib /usr/bin 下面与png有关的链接全部链接到1.4.3这个
版本上面来,这个过程有点曲折,有时候容易因为链接设置失误,而出错。
这些系统里的需要手动更改,指向1.4.3版本。
重新运行./FaceDetect结果如下
明显处理png时不再有警告了。
在另一台solaris上面配置环境发现又有了新的错误。以下是新错误补充:
首先是cc和CC的问题,由于系统默认cc和CC用的是Sun的版本,而不是gnu版本,会导致编译时出现语法的错误,也会出现c99的问题。
我的解决方法就是将cc和CC分别链接到系统中的gcc和g++(我的gcc和g++都在/usr/local/bin下面)。
然后重新cmake, make ,make install。然而在后面又发现如下错误:
该错误是关于python的问题,由于我们并没有使用python,可以利用cmake直接关掉,命令如下:
cmake -D BUILD_NEW_PYTHON_SUPPORT=NO .
附上人脸识别程序,输入为文件夹,输出为对应的人脸识别结果,格式为图片名,是否有人脸,图像长度,图像宽度
1 #include "cv.h" 2 #include "highgui.h" 3 #include <iostream> 4 #include <string> 5 #include <fstream> 6 #include <vector> 7 #include <dirent.h> 8 //#include <sys/io.h> 9 using namespace std; 10 11 //由于是多线程版本,cascade和storage两个参数不能作为全局静态变量(静态变量会导致线程间共享变量,同时访问会出错) 12 bool detect_and_draw( IplImage* img, CvHaarClassifierCascade* cascade, 13 CvMemStorage* storage); //人脸检测函数 14 15 const char* cascade_name ="haarcascade_frontalface_alt.xml"; 16 17 typedef struct param { //存放线程函数参数的结构体 18 string dirPath; //用户提供的目录,包含人脸识别图片 19 string outFileName; //输出判断结果路径 20 }param; 21 22 void* thread_fun(void *arg) //线程函数 23 { 24 CvHaarClassifierCascade* cascade = 0; 25 CvMemStorage* storage = 0; 26 cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); //加载人脸识别用到的分类器 27 if( !cascade ) 28 { 29 cerr << "ERROR: Could not load classifier cascade" << endl; 30 return NULL; 31 } 32 storage = cvCreateMemStorage(0); 33 34 param *p = (param *)arg; //线程函数的参数 35 string dir = p->dirPath; 36 string outDir = dir + "/"; 37 outDir += p->outFileName; 38 39 ofstream out; 40 out.open(outDir.c_str()); 41 42 dir += "/homepageImg"; 43 vector<string> gifpath, gifname; 44 45 DIR *d; 46 struct dirent *s_dir; 47 48 d = opendir(dir.c_str()); 49 while((s_dir=readdir(d)) != NULL) { 50 string filename = s_dir->d_name; 51 string filepath = dir + "/" + filename; 52 if(filename != "." && filename != "..") { 53 if(filename.find(".gif") == string::npos) { 54 IplImage* image = cvLoadImage(filepath.c_str(),1); //加载图像 55 out << filename; 56 if(!image) 57 out << ",success" << endl; 58 else { 59 if(detect_and_draw(image, cascade, storage)) //如果识别成功 60 out << ",yes"; 61 else 62 out << ",no"; 63 64 out << "," << image->width << "," << image->height; 65 out << endl; 66 cvReleaseImage(&image); 67 #ifdef DEBUG //区分debug模式和非debug模式 68 cout << filepath << endl; 69 #endif 70 } 71 } 72 } 73 } 74 closedir(d); 75 76 out.close(); 77 return NULL; 78 } 79 80 int main() 81 { 82 string dir; 83 cout << "input directory name:"; 84 cin >> dir; 85 86 string outFileName = "homepageImgResult.txt"; 87 88 DIR *d; 89 long lf; 90 91 d = opendir(dir.c_str()); 92 struct dirent *s_dir; 93 vector<pthread_t> p; 94 while((s_dir = readdir(d)) != NULL) { 95 if(s_dir->d_name[0]== '.') 96 continue; 97 98 pthread_t temp; 99 int ret; 100 101 param *params = new param; //这里必须动态申请,如果是局部变量,会导致该层循环结束后,param空间被释放 102 params->dirPath = dir + "/"; 103 params->dirPath += s_dir->d_name; 104 params->outFileName = outFileName; 105 106 ret = pthread_create(&temp, NULL, thread_fun, params); 107 if(ret) { 108 cerr << "Create Thread Error!" << endl; 109 exit(1); 110 } 111 p.push_back(temp); 112 113 } 114 115 for(vector<pthread_t>::iterator it = p.begin(); it != p.end(); ++it) 116 pthread_join(*it, NULL); //使主线程阻塞,直到所有子线程都执行完毕 117 118 closedir(d); 119 120 return 0; 121 } 122 123 bool detect_and_draw( IplImage* img, CvHaarClassifierCascade* cascade, 124 CvMemStorage* storage) 125 { 126 double scale = 1.3; 127 IplImage* gray = cvCreateImage(cvSize(img->width,img->height), 8, 1);//这里格式比较固定 128 IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale), 129 cvRound (img->height/scale)), 8, 1 ); 130 131 cvCvtColor( img, gray, CV_BGR2GRAY ); 132 cvResize( gray, small_img, CV_INTER_LINEAR ); 133 cvEqualizeHist( small_img, small_img ); 134 cvClearMemStorage( storage ); 135 136 if(cascade) 137 { 138 CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.1, 2, 0 ,cvSize(30, 30) ); 139 140 int facenum = faces ? faces->total : 0; 141 if(facenum) { 142 cvReleaseImage(&gray); 143 cvReleaseImage(&small_img); 144 return true; 145 } 146 } 147 cvReleaseImage(&gray); 148 cvReleaseImage(&small_img); 149 150 return false; 151 }