http://blog.csdn.net/chenyujing1234/article/details/7602076
一、OpenCV介绍:
OpenCV是由Intel性能基元(IPP)团队主持,而且几个主要开发者都与IPP团队保持良好的关系,所以OpenCV利用了IPP高度手工优化的代码来实现加速。
使用IPP获得提速是很显著的。
OpenCV使用了优化了的C和C++代码实现,它对IPP不存在任何依赖。但如果安装了IPP,那么OpenCV将会通过自动载入IPP动态链接库获取IPP的优势。
获得IPP并安装: http://www.itel.com/software/products/ipp/index.htm ; 请使用5.1或更新版本,请确认二进制文件路径(eg:c/program files/intel/ipp/5.1/ia32/bin)
被添加到系统环境变量的PATH中。现在OpenCV会自动探测到IPP,并在运行时装载IPP了。
1 、 OpenCV的结构和内容
OpenCV主体分为五个模块:
OpenCV的CV模块包含基本的图像处理函数和高级的计算机视觉算法。
ML是机器学习库,包含一些基于统计的分析和聚类工具。
HighGUI包含图像和视频输入/输出的函数。
CXCore包含OpenCV的一些基本数据结构和相关函数。
CvAux模块,该模块一般存放一些即将被淘汰的算法和函数(如嵌入式隐马尔可夫模型的人脸识别算法),同时还有一些新出现的实验性的算法(如背景和前景的分割)
二、OpenCV库的获得及编译
1、 OpenCV可以直接下载安装文件安装得到lib与dll文件及源码
OpenCV安装的下载(下载最新版本的OpenCV2.1.0)http://sourceforge.net/projects/opencv/
如果是1.1版本的那么安装文件是:
下载安装程序后,运行安装程序。安装程序将安装openCV并注册DirectShow filter,然后进行一些安装后的处理。
现在可以进入.../opencv/_make,使用MSVC++akg MSVC.NET 2005打开opencv.sln,然后生成Debug版本的库或Release版的库。
2、当然也可去下载它的源码来通过CMake自己编译.
转自: http://hi.baidu.com/zgzhaobo/blog/item/5e0df6263d4499058b82a114.html
OpenCV2.1.0编译详细讲解
准备工作
-
OpenCV源文件的下载(下载最新版本的OpenCV2.1.0)http://sourceforge.net/projects/opencv/
-
CMake的安装(2.8.1)http://www.cmake.org/cmake/resources/software.html
-
CodeBlock安装http://sourceforge.net/projects/codeblocks/
-
3rdparty库文件的更新
由于videoInput库文件是基于gcc 4.4.*之前版本编译,所以在Mingw4.4.*编译OpenCV时出现sjlj相应错误。
所以在我们编译OpenCV前务必要更新videoInput的库文件
文件下载:http://code.google.com/p/pyopencv/downloads/list
下载videoInput.a,覆盖OpenCV的解压路径/3rdparty/lib/libvideoInput.a
处理OpenCV源文件
- Cmake交叉编译
按照下面的设置进行配置,上面一行是解压后的OpenCV的路径
下面一行是你需要编译后存放动态链接库的文件目录,可供自由选择
注意:这里两个路径都不能有空格或者中文,不然编译会出现错误
点击下面configure进行配置(第一次点击的时候会挑选编译环境的工具,我们选择codeblock:mingw),会出现上面红色区域内容,勾选你需要的组建,然后再次点击configure,进行配置相关文件。
接下来Generate按钮呈现可用状态,点击Generate进行生成相应的编译环境的工程文件。
到此,我们可以关闭cmake工具,交由codeblock进行处理了。
打开codeblock工具,打开工程文件,选择刚才cmake输出的文件夹下的对应工程文件。界面如下:
工程上面点击右键,进行build,等待漫长的编译过程完成。
此时OpenCV编译完成!
=============================================================================================
当然大家也可以把CMake的编译环境配置成VS的。这样CMake后会产生编译VC工程文件:
三、入门程序的实现
在VC开发环境中,我们要配置它的各项设置,以使OpenCV开发包中的highgui.lib cxcore.lib ml.lib cv.lib库能被正确外国投资,并保证编译器的预处理器能搜索到
opencv/*/include 目录下的各个头文件。
它们一般位于:
D:\Program Files\OpenCV\cv\include
D:\Program Files\OpenCV\cxcore\include
D:\Program Files\OpenCV\ml\include
D:\Program Files\OpenCV\otherlibs\highgui
1、 第一个例子-------显示图像
从磁盘中加载并在屏幕上显示一幅图像的简单OpenCV程序
- #include "highgui.h"
-
- int main( int argc, char** argv )
- {
-
-
-
-
-
- IplImage* img = cvLoadImage( argv[1] );
-
-
-
- cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
-
- cvShowImage("Example1", img );
-
-
-
- cvWaitKey(0);
-
- cvReleaseImage( &img );
-
- cvDestroyWindow("Example1");
- }
2、 第二个例子------播放AVI视频
- #include "highgui.h"
-
- int main( int argc, char** argv ) {
- cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE );
-
-
-
-
- CvCapture* capture = cvCreateFileCapture( argv[1] );
- IplImage* frame;
- while(1) {
-
-
-
-
- frame = cvQueryFrame( capture );
- if( !frame ) break;
- cvShowImage( "Example2", frame );
- char c = cvWaitKey(33);
- if( c == 27 ) break;
- }
- cvReleaseCapture( &capture );
- cvDestroyWindow( "Example2" );
- }
2、1 视频播放控制
上例中我们无法在视频播放时进行快速拖动,我们接下来通过加入一个滚动条来实现这个功能。
HighGUI不仅提供了简单的显示函数,还包括一些图像和视频控制方法,其中之一个经常用到的是滚动条,它可以使我们方便地从视频一帧跳到另外一帧。
我们通过调用cvCreateTrackbar()来创建一个滚动条,并通过设置参数确定滚动条所属于的窗口。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include "highgui.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include <iostream>
- #include <fstream>
- #include "cv.h"
- #include "highgui.h"
-
-
-
-
-
-
-
-
- using namespace std;
-
- int g_slider_position = 0;
- CvCapture* g_capture = NULL;
-
-
-
- void onTrackbarSlide(int pos) {
-
-
-
- cvSetCaptureProperty(
- g_capture,
- CV_CAP_PROP_POS_FRAMES,
- pos
- );
- }
-
-
-
- int getAVIFrames(char * fname) {
- char tempSize[4];
-
- ifstream videoFile( fname , ios::in | ios::binary );
-
- if ( !videoFile ) {
- cout << "Couldn’t open the input file " << fname << endl;
- exit( 1 );
- }
-
- videoFile.seekg( 0x30 , ios::beg );
- videoFile.read( tempSize , 4 );
- int frames = (unsigned char ) tempSize[0] + 0x100*(unsigned char ) tempSize[1] + 0x10000*(unsigned char ) tempSize[2] + 0x1000000*(unsigned char ) tempSize[3];
- videoFile.close( );
- return frames;
- }
-
-
- int main( int argc, char** argv ) {
- cvNamedWindow( "Example2_3", CV_WINDOW_AUTOSIZE );
- g_capture = cvCreateFileCapture("E:\\OpenCV\\openCV1.1Test\\tree.avi" );
- IplImage *foo = cvQueryFrame( g_capture);
-
-
-
- int frames = (int) cvGetCaptureProperty(
- g_capture,
- CV_CAP_PROP_FRAME_COUNT
- );
-
-
- int tmpw = (int) cvGetCaptureProperty(
- g_capture,
- CV_CAP_PROP_FRAME_WIDTH
- );
-
-
- int tmph = (int) cvGetCaptureProperty(
- g_capture,
- CV_CAP_PROP_FRAME_HEIGHT
- );
-
- printf("opencv frames %d w %d h %d\n",frames,tmpw,tmph);
-
-
- frames = getAVIFrames("E:\\OpenCV\\openCV1.1Test\\tree.avi");
-
- printf("hacked frames %d w %d h %d\n",frames,tmpw,tmph);
-
-
-
-
- cvCreateTrackbar(
- "Position",
- "Example2_3",
- &g_slider_position,
- frames,
- onTrackbarSlide
- );
- IplImage* frame;
- frames = 0;
- while(1) {
- frame = cvQueryFrame( g_capture );
- if( !frame ) break;
-
- frames++;
- printf("\nFrame number=%d\n",frames);
- cvSetTrackbarPos("Position","Example2_3",frames);
- cvShowImage( "Example2_3", frame );
- char c = (char)cvWaitKey(10);
- if( c == 27 ) break;
- }
- cvReleaseCapture( &g_capture );
- cvDestroyWindow( "Example2_3" );
- return(0);
- }
2、2 对图像进行简单的变换
现在我们要对视频的播放中的每一帧进行图像平滑处理,通过对图像数据与高斯或者其他核函数进行卷积有效地减少图像信息内容。
OpenCV使得这个卷积操作非常容易。
我们先创建一个窗口“Example4-out" 用来显示处理后的图像。然后在我们调用cvShowImage()来显示新捕捉的图像以后,我们可以计算
和在输出窗口中显示平滑处理后的图像。
效果如下:
- #include "cv.h"
- #include "highgui.h"
-
- void example2_4( IplImage* image )
- {
-
-
-
- cvNamedWindow( "Example2_4-in", CV_WINDOW_AUTOSIZE );
- cvNamedWindow( "Example2_4-out", CV_WINDOW_AUTOSIZE );
-
-
-
- cvShowImage( "Example2_4-in", image );
-
-
-
-
-
-
- IplImage* out = cvCreateImage(
- cvGetSize(image),
- IPL_DEPTH_8U,
- 3
- );
-
-
- cvSmooth( image, out, CV_GAUSSIAN, 5,5 );
-
- cvSmooth( out, out, CV_GAUSSIAN, 5, 5);
-
-
-
- cvShowImage( "Example2_4-out", out );
-
-
-
- cvReleaseImage( &out );
-
-
-
- cvWaitKey( 0 );
- cvDestroyWindow("Example2_4-in" );
- cvDestroyWindow("Example2_4-out" );
-
- }
-
- int main( int argc, char** argv )
- {
- IplImage* img = cvLoadImage("adrian.jpg");
- cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
- cvShowImage("Example1", img );
- example2_4( img );
-
- cvReleaseImage( &img );
- cvDestroyWindow("Example1");
- }
2、3 对图像进行复杂一点的变换
这里我们将用输出来覆盖输入变量。在OpenCV中我们通过函数cvPyrDown()来完成上述功能。
从旧的图像中读取所需的信息;在OpenCV中,所有的重要数据结构都是以结构体的形式实现的,并以结构体指针的形式传递。
openCV中没有私有数据!
- #include "cv.h"
- #include "highgui.h"
-
- IplImage* doPyrDown(
- IplImage* in,
- int filter = IPL_GAUSSIAN_5x5)
- {
-
-
-
-
-
-
-
-
- IplImage* out = cvCreateImage(
- cvSize( in->width/2, in->height/2 ),
- in->depth,
- in->nChannels
- );
- cvPyrDown( in, out );
- return( out );
- };
-
- int main( int argc, char** argv )
- {
- IplImage* img = cvLoadImage("adrian.jpg" );
- IplImage* img2 = cvCreateImage( cvSize( img->width/2,img->height/2 ), img->depth, img->nChannels);
- cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
- cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE );
- cvShowImage("Example1", img );
- img2 = doPyrDown( img );
- cvShowImage("Example2", img2 );
- cvWaitKey(0);
- cvReleaseImage( &img );
- cvReleaseImage( &img2 );
- cvDestroyWindow("Example1");
- cvDestroyWindow("Example2");
- }
2、4 Canny边缘检测
在进行Canny处理前得先进行灰度处理
cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
- #include "cv.h"
- #include "highgui.h"
-
- IplImage* doCanny(
- IplImage* in,
- double lowThresh,
- double highThresh,
- double aperture)
- {
- if (in->nChannels != 1)
- return(0);
- IplImage* out = cvCreateImage(
- cvGetSize( in ),
- in->depth,
- 1);
- cvCanny( in, out, lowThresh, highThresh, aperture );
- return( out );
- };
-
- int main( int argc, char** argv )
- {
- IplImage* img_rgb = cvLoadImage( "adrian.jpg" );
- IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
- cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
- cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
- cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
- cvShowImage("Example Gray", img_gry );
- IplImage* img_cny = doCanny( img_gry, 10, 100, 3 );
- cvShowImage("Example Canny", img_cny );
- cvWaitKey(0);
- cvReleaseImage( &img_rgb);
- cvReleaseImage( &img_gry);
- cvReleaseImage( &img_cny);
- cvDestroyWindow("Example Gray");
- cvDestroyWindow("Example Canny");
- }
接下来我们想缩放图像两次,然后在缩放后的图像中寻找边缘,具体如下所示:
- #include "cv.h"
- #include "highgui.h"
-
- IplImage* doCanny(
- IplImage* in,
- double lowThresh,
- double highThresh,
- double aperture)
- {
- IplImage* out = cvCreateImage(
- cvGetSize( in ),
- in->depth,
- 1);
- cvCanny( in, out, lowThresh, highThresh, aperture );
- return( out );
- };
-
- IplImage* doPyrDown(
- IplImage* in,
- int filter = IPL_GAUSSIAN_5x5)
- {
-
-
-
-
-
- IplImage* out = cvCreateImage(
- cvSize( in->width/2, in->height/2 ),
- in->depth,
- in->nChannels
- );
- cvPyrDown( in, out );
- return( out );
- };
-
- int main( int argc, char** argv )
- {
- IplImage* img_rgb = cvLoadImage( "adrian.jpg" );
- IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
- cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
- IplImage* img_pyr = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );
- IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 );
- IplImage* img_cny = doCanny( img_pyr2, 10, 100, 3 );
-
- cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
- cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );
- cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
- cvShowImage("Example Gray", img_gry );
- cvShowImage("Example Pyr", img_pyr2 );
- cvShowImage("Example Canny", img_cny );
- cvWaitKey(0);
- cvReleaseImage( &img_rgb);
- cvReleaseImage( &img_gry);
- cvReleaseImage( &img_pyr);
- cvReleaseImage( &img_pyr2);
- cvReleaseImage( &img_cny);
- cvDestroyWindow("Example Gray");
- cvDestroyWindow("Example Pyr");
- cvDestroyWindow("Example Canny");
- }
2、4、1 内存释放考虑方面的改进
(1)像下面这样进行嵌套调用是一个不好的主意,因为内存空间的释放会成为一个很困难的问题。
IplImage* img_pyr = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );
IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 );
IplImage* img_cny = doCanny( img_pyr2, 10, 100, 3 );
(2) 在OpenCV中我们必须确认被释放的空间必须是我们分配,但在我们上面的例子中却释放了非显示分配的内存
cvReleaseImage( &img_pyr);
cvReleaseImage( &img_pyr2);
cvReleaseImage( &img_cny);
所以我们把例子改为:
- int main( int argc, char** argv )
- {
- IplImage* img_rgb = cvLoadImage( "adrian.jpg" );
- IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
- cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- IplImage* out;
- cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
- cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );
- cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
-
-
- cvShowImage("Example Gray", img_gry );
- out = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );
-
- cvShowImage("Example Pyr", out );
- out = doPyrDown( out, IPL_GAUSSIAN_5x5 );
-
- out = doCanny( out, 10, 100, 3 );
- cvShowImage("Example Canny", out );
-
- cvWaitKey(0);
- cvReleaseImage( &img_rgb);
- cvReleaseImage( &img_gry);
-
- cvReleaseImage( &out);
- cvDestroyWindow("Example Gray");
- cvDestroyWindow("Example Pyr");
- cvDestroyWindow("Example Canny");
-
-
- }