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 }
posted @ 2013-05-09 14:48  whu-小磊  阅读(983)  评论(0编辑  收藏  举报