Solaris下人脸识别程序(OpenCV)

本文介绍了如何在Solaris系统下安装OpenCV 2.2,包括解决cc命令缺失、pthread库问题以及png库冲突等编译问题。在编译完成后,文章还讨论了人脸识别程序的编写、编译和运行,特别是在处理系统库依赖和环境配置上的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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 .

附上人脸识别程序,输入为文件夹,输出为对应的人脸识别结果,格式为图片名,是否有人脸,图像长度,图像宽度

#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <dirent.h>
//#include <sys/io.h>
using namespace std;

//由于是多线程版本,cascade和storage两个参数不能作为全局静态变量(静态变量会导致线程间共享变量,同时访问会出错)
bool detect_and_draw( IplImage* img, CvHaarClassifierCascade* cascade,
 CvMemStorage* storage);                                                     //人脸检测函数

const char* cascade_name ="haarcascade_frontalface_alt.xml";                                                                                              

typedef struct param {                                                       //存放线程函数参数的结构体
        string dirPath;                                                      //用户提供的目录,包含人脸识别图片
        string outFileName;                                                  //输出判断结果路径
}param;

void* thread_fun(void *arg)                                                  //线程函数
{
        CvHaarClassifierCascade* cascade = 0;
        CvMemStorage* storage = 0;
        cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); //加载人脸识别用到的分类器                                                                          
        if( !cascade )
        {
                cerr << "ERROR: Could not load classifier cascade" << endl;
                return NULL;
        }
        storage = cvCreateMemStorage(0);

        param *p = (param *)arg;                                              //线程函数的参数
        string dir = p->dirPath;
        string outDir = dir + "/";
        outDir += p->outFileName;

        ofstream out;
        out.open(outDir.c_str());

        dir += "/homepageImg";
        vector<string> gifpath, gifname;

        DIR *d;
        struct dirent *s_dir;

        d = opendir(dir.c_str());
        while((s_dir=readdir(d)) != NULL) {
                string filename = s_dir->d_name;
                string filepath = dir + "/" + filename;
                if(filename != "." && filename != "..") {
                        if(filename.find(".gif") == string::npos) {
                                IplImage* image = cvLoadImage(filepath.c_str(),1);  //加载图像
                                out << filename;
                                if(!image)
                                        out << ",success" << endl;
                                else {
                                        if(detect_and_draw(image, cascade, storage)) //如果识别成功 
                                                out << ",yes";
                                        else
                                                out << ",no";

                                        out << "," << image->width << "," << image->height;
                                        out << endl;
                                        cvReleaseImage(&image);
#ifdef DEBUG                                                                //区分debug模式和非debug模式
                                        cout << filepath << endl;
#endif
                                }
                        }
                }
        }
        closedir(d);

        out.close();
        return NULL;
}

int main()
{
        string dir;
        cout << "input directory name:";
        cin >> dir;

        string outFileName = "homepageImgResult.txt";

        DIR *d;
        long lf;

        d = opendir(dir.c_str());
        struct dirent *s_dir;
        vector<pthread_t> p;
        while((s_dir = readdir(d)) != NULL) {
                if(s_dir->d_name[0]== '.')
                        continue;

                pthread_t temp;
                int  ret;

                param *params = new param;              //这里必须动态申请,如果是局部变量,会导致该层循环结束后,param空间被释放
                params->dirPath = dir + "/";
                params->dirPath += s_dir->d_name;
                params->outFileName = outFileName;

                ret = pthread_create(&temp, NULL, thread_fun, params);
                if(ret) {
                        cerr << "Create Thread Error!" << endl;
                        exit(1);
                }
                p.push_back(temp);

        }

        for(vector<pthread_t>::iterator it = p.begin(); it != p.end(); ++it)
                pthread_join(*it, NULL);                                      //使主线程阻塞,直到所有子线程都执行完毕

        closedir(d);

        return 0;
}

bool detect_and_draw( IplImage* img, CvHaarClassifierCascade* cascade,
                CvMemStorage* storage)
{
        double scale = 1.3;
        IplImage* gray = cvCreateImage(cvSize(img->width,img->height), 8, 1);//这里格式比较固定
        IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
                                cvRound (img->height/scale)), 8, 1 );

        cvCvtColor( img, gray, CV_BGR2GRAY );
        cvResize( gray, small_img, CV_INTER_LINEAR );
        cvEqualizeHist( small_img, small_img );
        cvClearMemStorage( storage );

        if(cascade)
        {
                CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,                                                                                                  1.1, 2, 0 ,cvSize(30, 30) );

                int facenum = faces ? faces->total : 0;
                if(facenum) {
                        cvReleaseImage(&gray);
                        cvReleaseImage(&small_img);
                        return true;
                }
        }
        cvReleaseImage(&gray);
        cvReleaseImage(&small_img);

        return false;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值