当前位置:C++技术网 > 资讯 > opencv编程:1 开发环境配置(配人脸识别源码测试)

opencv编程:1 开发环境配置(配人脸识别源码测试)

更新时间:2015-07-03 16:28:39浏览次数:1+次

    我们要做图形图像处理,很多人很多公司都选用了OpenCV。OpenCV全称为Open Computer Vision,是开放计算机视觉的意思。这是一个开放的计算机视觉库。所谓的视觉库,就是图形图像处理,包括图片的处理和识别等。我们可以想象,计算机装上摄像头,就可以获取图像了。然而,只是获取图像,却不一定知道图像中的物体是什么。这就需要图形图像处理,然后识别了。
    图形图像识别,其实是一个非常复杂的过程。它需要从图像中分析出需要的东西,这些需要强大的算法支持。好在OpenCV对此支持很好了,使用这个工具,我们可以很轻松的实现基本的功能。比如人脸识别等。也就是说,需要的一些算法,都已经是写好了的,只要用就行了,不需要我们自己写。
    当然,如果需要实现特定的功能,那还是需要你写一些算法。当然,不仅如此,你还更加需要了解图形学的一些基础知识。幸运的时,OpenCV是开源跨平台的视觉库,因此,有很多资料可以参考。这不,我也在写点资料供大家参考。哈哈哈,当然,我这是初学入门的参考资料,也是学习总结,学到哪写到哪。如果有问题,请一定要指出来,一起学习。
    好了,进入正题。既然我要做这个,就要下定决心去学习,不要半途而废。做这个需要学习很多基础知识,所以,事先要做好心理准备。要想学好,不停的动手练习是必不可少的,那么,配置环境成为第一个关键问题。
    很多人会卡在这里,给开始造成困难。网上也有一些资料,可能还不够细致吧。我刚学,自然也会觉得一些地方,写的并没有解答我。而我,摸着石头过河,弄明白了,告诉你,应该效果更好吧。
    好了,开始准备工具了。第一个就是OpenCV2.4.9库的文件,因为我用的是2.4.9版本,配置的也是OpenCV2.4.9,所以为了保持一致,让你第一次配置成功通过,建议先下载这个吧。之后想换高版本的,可以自行去下载哦。
    下载地址:点我去sourceforge网站下载
    当然,作为贴心的我,当然也不会让你下载起来,感觉很麻烦咯。我已将下载好的文件,存储在百度网盘了。
    百度网盘下载:点我去百度网盘下载

    至于VS,基本上,每一个版本都能够用,所以,这里其实跟VS无关,用你手里用的这个版本就好。
    下载完后,是下图这么一个文件名为opencv-2.4.9.exe的安装程序,可以双击运行。

    opencv-2.4.9.exe
    双击运行后,出现如下图所示的解压对话框。

    opencv-2.4.9.exe
    在编辑框中,输入或者选择一个文件夹,用来装OpenCV库文件的。这个库文件是我们开发中,经常用到的。所以,不要随意放置在一个地方,很容易当做一个普通的文件夹被移走。移走后,程序编译就找不到库文件。所以,建议放在Program Files文件夹下,这样一般就不会轻易动这个文件夹里的东西了。同时,我的演示,也是放在这个文件夹里,所以,你也先放在这里,如果实在不习惯,以后再换个位置也行。它就一些文件而已,直接剪切走就行。
    还有一个问题,第一次解压时,你也可能担心只写个D:\Program Files怕程序把库文件都解压在这个文件夹下,搞得乱七八糟了。因为这个文件夹还有很多其他软件的文件。这个会默认自动在D:\Program Files下面创建一个名为opencv的文件夹,然后将所有的文件放在opencv文件夹下,方便管理。所以,也不要自己填了,也不用担心。

    解压的过程中,如下图所示。
    opencv-2.4.9.exe
    解压文件后,得到如下图所示的两个文件夹。可以自行打开浏览熟悉,是一定要熟悉哦。看看有哪些文件。

   

    这样,我们需要的库文件就准备好了。现在是,我们要使用这些库来做开发了。也就是要使用这些库,如何使用呢?
    因为在程序编译时,编译器会到库目录里面去找对应的文件来编译,因此,需要让编译器知道这些路径。所以,我们通常的做法,就是将这些路径存入环境变量中。编译器会去这些路径找库文件的。
    而环境变量有两种,一个是系统变量,一个是用户变量。我们不需要纠结两者的详细区别,我只要知道,系统变量当然是全局的,系统中所有用户,都能够得到的全局变量。而用户变量,则是当前用户才能够得到的变量。大概就了解这么多就行,我只要设置好就OK。
    首先在系统变量中,添加一个Path变量,变量的值为D:\Program Files\opencv\build\x86\vc12\bin。
    设置的位置为:(Win7)右击桌面的“我的电脑”或者“计算机”,选择属性,选择左侧的“高级系统设置”,弹出如下界面:

    环境变量
    点击上图的“高级”下的“环境变量(N)...”按钮,弹出如下界面:
    环境变量(N)...
    上面显示的是“Administrator”用户变量,也就是上面说的用户变量,下面的是系统变量。
    所以,我们先在系统变量里面,找一下是否已经有了Path变量,如果有,那么就把Path变量的值添加进去即可。当然,要现在已有的变量值后面加个英文的分号,然后将我们的变量值放在分号后面即可。如果没有这个变量,那么我们就要点“新建”,填入变量名和变量值,确定保存系统变量。
    然后就是检查用户变量中有没有Path变量,有就添加,没有就新建一个,方法同系统变量一样,值也是D:\Program Files\opencv\build\x86\vc12\bin。而用户变量还要多一个变量,就是opencv变量,如果之前没有玩过,基本就没有。在用户变量里面创建一个名为opencv的变量,值为D:\Program Files\opencv\build。
    这些路径就是解压放置的文件的路径。这里需要强调一下,不管你的系统是32位还是64位,都是选择x86这个路径哦,因为编译都是使用32位编译的,不要自作聪明。如果你想试试也是可以的,不就是编译出错嘛,到时候再改回来就可以了。
    都添加好后,一路确定,退出环境变量的配置,即可。

    下面就是使用Opencv库了。我们只需要使用一个控制台程序即可哦。新建控制台的项目,在项目创建向导的“附加选项”中,选择“空项目”,如果是VS2012或者更高版本,去掉“安全开发生命周期(SDL)检查”这个选项,然后确定即可。因为这个很简单,就不截图了。
    项目创建好后,就是我们在项目引用OpenCV(即使用OpenCV)的时候了。在VC开发中,引用库无非就是引用lib库,然后来加载Dll的。
    首选我们要创建一个cpp源文件,方法就不说了,这个很简单,我相信你知道的,不知道的话告诉我,我去扁你一顿,哈哈。然后点击一下cpp编辑文件的地方,把焦点聚焦到这个文件的编辑,这样,再点击VS菜单的“项目”菜单,就可以看到如下图所示的菜单。
    VS项目属性
    红色方框中,显示的是“项目名属性”,单击这个属性进去,就可以看到这个项目的设置了。我们要在这里添加目录的引用,让编译器知道去相应的目录去找相关的文件。
    如下图所示,我们在“VC++目录”标签的“包含目录”中添加如下三个路径:
    D:\Program Files\opencv\build\include,D:\Program Files\opencv\build\include\opencv,D:\Program Files\opencv\build\include\opencv2。

    添加方法就是:单击包含目录右边的一列,最右侧出现下来箭头,点击下拉箭头,然后单击编辑。出现如下界面:

   
    当然我这是添加好了的。如果没有添加,这三个路径的位置是空白,点击就可以编辑对应的行,然后输入路径即可,编辑完一个,可以单击另外一行,编辑另外一个。最后完成三个的添加,确定即可。

    然后在库目录这里,添加一个路径:D:\Program Files\opencv\build\x86\vc12\lib,方法和包含目录一样。
    为了方便,引入lib的我就直接用预编译指令来完成。当然,你也可以在“链接器”下的“输入”标签中的“附加依赖项”中添加以下lib文件的引用:

opencv_ml249d.lib
opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_objdetect249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_nonfree249d.lib
opencv_ocl249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_superres249d.lib
opencv_videostab249d.lib
     当然,这样,每次建立一个新项目时,都要设置以下包含目录、库目录和引用lib,所以我为了减少新建项目的工作量,就用预编译指令引入lib了。因为这些是Debug版的lib版,所以如果要用release版,还要将这些lib换成release版的,即后面没有d字母的,如opencv_ml249.lib。其他的也是类似,去掉d即可。当然,在预编译指令里面,我已经处理好了,只要复制那段代码,就可以了。后面就知道了。
    在CPP文件中,添加如下代码,来测试。如果成功,说明环境配置完毕。下面代码是人脸识别的代码哦。

#include "cv.h" 
#include "highgui.h"

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <assert.h> 
#include <math.h> 
#include <float.h> 
#include <limits.h> 
#include <time.h> 
#include <ctype.h>
/* - 下面这一段,就是预编译指令直接处理了引入库lib,如果是Debug就引用Debug版本,否则引用Release版本 - */
#ifdef _DEBUG
#pragma comment(lib,"opencv_ml249d.lib")
#pragma comment(lib,"opencv_calib3d249d.lib")
#pragma comment(lib,"opencv_contrib249d.lib")
#pragma comment(lib,"opencv_core249d.lib")
#pragma comment(lib,"opencv_features2d249d.lib")
#pragma comment(lib,"opencv_flann249d.lib")
#pragma comment(lib,"opencv_gpu249d.lib")
#pragma comment(lib,"opencv_highgui249d.lib")
#pragma comment(lib,"opencv_imgproc249d.lib")
#pragma comment(lib,"opencv_legacy249d.lib")
#pragma comment(lib,"opencv_objdetect249d.lib")
#pragma comment(lib,"opencv_ts249d.lib")
#pragma comment(lib,"opencv_video249d.lib")
#pragma comment(lib,"opencv_nonfree249d.lib")
#pragma comment(lib,"opencv_ocl249d.lib")
#pragma comment(lib,"opencv_photo249d.lib")
#pragma comment(lib,"opencv_stitching249d.lib")
#pragma comment(lib,"opencv_superres249d.lib")
#pragma comment(lib,"opencv_videostab249d.lib")

#else
#pragma comment(lib,"opencv_ml249.lib")
#pragma comment(lib,"opencv_calib3d249.lib")
#pragma comment(lib,"opencv_contrib249.lib")
#pragma comment(lib,"opencv_core249.lib")
#pragma comment(lib,"opencv_features2d249.lib")
#pragma comment(lib,"opencv_flann249.lib")
#pragma comment(lib,"opencv_gpu249.lib")
#pragma comment(lib,"opencv_highgui249.lib")
#pragma comment(lib,"opencv_imgproc249.lib")
#pragma comment(lib,"opencv_legacy249.lib")
#pragma comment(lib,"opencv_objdetect249.lib")
#pragma comment(lib,"opencv_ts249.lib")
#pragma comment(lib,"opencv_video249.lib")
#pragma comment(lib,"opencv_nonfree249.lib")
#pragma comment(lib,"opencv_ocl249.lib")
#pragma comment(lib,"opencv_photo249.lib")
#pragma comment(lib,"opencv_stitching249.lib")
#pragma comment(lib,"opencv_superres249.lib")
#pragma comment(lib,"opencv_videostab249.lib")
#endif

#ifdef _EiC 
#define WIN32 
#endif
static CvMemStorage* storage = 0; 
static CvHaarClassifierCascade* cascade = 0;

void detect_and_draw( IplImage* image );

const char* cascade_name = ""; 

int main( int argc, char** argv ) 
{
    // - 下面这个地址是不能错的,这是你安装的OpenCV库下的一个文件的地址,如果出错,无法识别人脸 
    cascade_name = "D:\\Program Files\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
 cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); 
  
    if( !cascade ) 
    { 
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); 
        return -1; 
    } 
    storage = cvCreateMemStorage(0); 
    cvNamedWindow( "人脸识别", 1 ); 
     
    const char* filename = "D:\\1.jpg"; // - 待识别人脸的图片的路径
    IplImage* image = cvLoadImage( filename, 1 );

    if( image ) 
    { 
        detect_and_draw( image ); 
        cvWaitKey(0); 
        cvReleaseImage( &image );   
    }

    cvDestroyWindow("人脸识别"); 
  
    return 0; 
}


void detect_and_draw(IplImage* img ) 
{ 
    double scale=1.2; 
    static CvScalar colors[] = { 
        {{0,0,255}},{{0,128,255}},{{0,255,255}},{{0,255,0}}, 
        {{255,128,0}},{{255,255,0}},{{255,0,0}},{{255,0,255}} 
    };//Just some pretty colors to draw with

    // - 图片预处理
    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); //直方图均衡

    //Detect objects if any 
    // 
    cvClearMemStorage(storage); 
    double t = (double)cvGetTickCount(); 
    CvSeq* objects = cvHaarDetectObjects(small_img, 
  cascade,storage,1.1,2,0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(30,30));

    t = (double)cvGetTickCount() - t; 
    printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

    //Loop through found objects and draw boxes around them 
    for(int i=0;i<(objects? objects->total:0);++i) 
    { 
        CvRect* r=(CvRect*)cvGetSeqElem(objects,i); 
        cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]); 
    } 
    for( int i = 0; i < (objects? objects->total : 0); i++ ) 
    { 
        CvRect* r = (CvRect*)cvGetSeqElem( objects, i ); 
        CvPoint center; 
        int radius; 
        center.x = cvRound((r->x + r->width*0.5)*scale); 
        center.y = cvRound((r->y + r->height*0.5)*scale); 
        radius = cvRound((r->width + r->height)*0.25*scale); 
        cvCircle( img, center, radius, colors[i%8], 3, 8, 0 ); 
    }

    cvShowImage( "人脸识别", img ); 
    cvReleaseImage(&gray); 
    cvReleaseImage(&small_img); 
}

    运行效果如下:

    人脸识别效果图,女神范冰冰