如何开始一个简单的opencv示例程序程序

&&&&&&&&&&&
最近刚刚开始接触OpenCV,在这里把自己学习过程中的收获和问题写在这里与大家一起分享讨论,毕竟一个人的力量和精力有限,希望与大家一起共勉。
声明:1.本人也是初学,水平有限,如有错误之处,欢迎大家批评指正。
      2.环境:Win7 ultimate 64bit + VS2010 + OpenCV2.4.3。
Chapter 1:介绍
在这篇博文中将为大家介绍OpenCV基础原理以及向大家展示如何完成最基础的一些任务:例如读取,显示和保存图片等。在开始编写OpenCV程序之前,需要先安装OpenCV Library,同时你也需要一个好的环境(IDE),在这里我用的是Microsoft Visual Studio 2010。
Chapter 2:安装OpenCV Library
OpenCV是一个用来开发计算机视图应用程序的开源库,其可用在大学或者商业程序中,在BSD证书下允许免费使用,传播或者改编它。这一节将说明如何安装OpenCV Library。
2.1 准备工作
访问OpenCV的可以找到最新的发行包以及在线文档和许多其他跟OpenCV有关的资源。
注:这里强烈建议大家下载新版的OpenCV Library,因为2.3以后的版本安装时会自动生成一个Build文件夹,里面有编译好的Lib和DLL,可以直接使用,如果是2.3之前的版本,则需要自己手动编译,编译的过程还是较为繁琐的,这里就不一一介绍了。而且版本越新功能也就越强大,何乐而不为呢?
从官网的下载界面里找到相应的平台,这里我们选择Windows,下好安装包之后解压能看到一个build文件夹,里面包含了要用到的模块。具体安装之后的目录如下图(安装过程很简单,选择一个要解压到的文件夹即可,这里就不具体说明了):
(接下来这一步可以不做,但是后章中提到包含头文件和库文件的时候要注意选择相应的目录)新建一个OpenCV的目录,可以在这目录下再新建不同的文件夹来存放不同版本的文件,这里为了方便把需要用到的文件:include文件夹和X64下的文件夹拷贝到刚刚新建好的文件夹里(如果是32bit的系统就拷贝X86下的文件夹),我是放在C:\Program Files\OpenCV\VS2010文件夹下,最后的结果如下图(如果是VS2008则拷贝VC9目录代替VC10):
2.3 OpenCV是如何工作的
从2.2版本开始,OpenCV Library分成了几个模块,这些模块编译生成的Library文件都被放在“lib”目录下,它们分别是:
opencv_core:包含库的核心功能,特别是基本数据结构和算法逻辑函数。
opencv_highgui:包含图像,视频的读写功能函数和其他的用户接口函数。
opencv_imgproc:包含图像处理函数。
opencv_features2d:表明检测器,描述器和匹配的框架等特征。
opencv_calib3d:包含摄像校对,二维几何估值,三维立体处理函数等。
opencv_vidio:包含了动态预测,特征跟踪以及前景提取的函数和类。
opecv_objdetect:包含对象检测函数,例如人脸识别等。
当然,还包括其他一些功能的库,像opencv_ml,opencv_flann,opencv_contrib,opencv_legacy,opencv_gpu等。
在include同文件中有与这些模块相关联的头文件,一般OpenCV C++代码开始的时候都要包含所需的模块头文件,例如(推荐用这样的形式来声明):
1: #include &opencv2/core/core.hpp&
2: #include &opencv2/imgproc/imgproc.hpp&
3: #include &opencv2/highgui/highgui.hpp&
如果你看到下面这种OpenCV代码:
1: #include “cv.h&
这是因为它用了在OpenCV库重组成模块之前的格式。
Chapter 3:创建OpenCV的工程:
这一节来向大家展示怎么创建一个简单的OpenCV工程,首先,通过VS2010的File|New Project|Project…菜单选项新建一个工程,这里选择Win32 Console Application(Win32 控制台程序),如下图:
点击OK,然后点击next
接下来选择Empty project,点击finish:
这样我们就创建了一个空的OpenCV的工程,首先,在编译和运行OpenCV程序之前,需要先告诉Visual C++去哪里找OpenCV的库和头文件,由于将来我们可能会创建一些OpenCV的工程,所以在这里最好的做法是创建一个属性表,这个属性表可以重用在其他的OpenCV工程中,这样我们就不需要每次编写OpenCV工程的时候去配置库和头文件目录了。打开Property Manager(属性管理器,如果找不到可以通过View|Property Manager打开)。
在Visual C++ 2010中,属性表是一个描述工程设置的XML文件,通过右键点击Debug|Win32,选择Add New Project Property Sheet选项,可以见到下图:
点击Add按钮后,就添加了一张属性表,现在我们要对它进行编辑,双击刚刚新建好的属性表,选择VC++ Directories,如下图:
编辑Include Directories文本框,添加OpenCV库头文件所在的include路径(以各位自己安装OpenCV的路径为准),如下图(下图是我自己的路径):
同样处理Library Directories,这次我们添加OpenCV的库文件路径:
下一步要指明代码需要链接的OpenCV库文件来生成可执行程序。根据应用程序的不同需要不同的OpenCV模块,因为我们希望属性表可以被重用在所有的OpenCV工程中,我们简单的添加几个需要用到的库模块,在Input文本框中选择Linker节点,如下图:
编辑Additional Dependencies文本框然后添加下面的库模块:
注意这里我们指定的库名字末尾有个字母&d”,这说明是Debug模式,我们需要创建另外一个Release模式的属性表,重复上面的步骤,不过需要在Release|Win32节点下添加,在添加库木块的时候,不需要在末尾加上字母&d”,如下图:
接下来我们准备创建,编译和运行第一个OpenCV应用程序。在Solution Explorer中,右击Source Files节点,选择Add New Item…创建一个main.cpp的C++文件。然后我们在main.cpp中添加如下代码:
1: #include &iostream&
2: #include &opencv2/core/core.hpp&
3: #include &opencv2/highgui/highgui.hpp&
4: using namespace
5: using namespace
7: int main( int argc, char** argv )
//read an image
if ( argc != 2 )
cout && &Usage: display_image ImageToLoadAndDisplay& &&
return -1;
cout && &size: & && image.size().height && & , &
&& image.size().width &&
// Read the file
image = imread(argv[1], CV_LOAD_IMAGE_COLOR);
// Check for invalid input
if (!image.data)
cout && &Could not open or find the image& &&
return -1;
// Create a window for display.
namedWindow( &Display window&, CV_WINDOW_AUTOSIZE );
// Show our image inside it.
imshow(&Display window&, image);
//Wait for a keystroke in the window
waitKey(0);
现在要设置输入图片的位置,在Solution Explorer中,右击OpenCVConsole工程名,选择Property,在Debugging节点中的Command Arguments文本框中输入图片的全路径,如下图:
然后按Ctrl+F5看下运行的效果吧!
Chapter 4 总结及问题
在上述开发过程中遇到一个问题,如果将上述的代码改成图片路径不通过参数传递,而是指定一个图片,并将该图片放在相应的Debug或Release目录下,则会出现错误,希望大家如果能解决这个问题的告诉我解决方法,谢谢。附代码和图:
1: #include &iostream&
2: #include &opencv2/core/core.hpp&
3: #include &opencv2/highgui/highgui.hpp&
4: using namespace
5: using namespace
7: int main( void )
//read an image
cout && &size: & && image.size().height && & , &
&& image.size().width &&
// Read the file
image = imread(&1.jpg&, CV_LOAD_IMAGE_COLOR);
// Check for invalid input
if (!image.data)
cout && &Could not open or find the image& &&
return -1;
// Create a window for display.
namedWindow( &Display window&, CV_WINDOW_AUTOSIZE );
// Show our image inside it.
imshow(&Display window&, image);
//Wait for a keystroke in the window
waitKey(0);
如有错误的地方希望大家批评指正,转载需注明出处,谢谢大家支持。
阅读(...) 评论()6694人阅读
转载请标明是引用于 &
欢迎大家提出意见,一起讨论!
一、OpenCV介绍:
OpenCV是由Intel性能基元(IPP)团队主持,而且几个主要开发者都与IPP团队保持良好的关系,所以OpenCV利用了IPP高度手工优化的代码来实现加速。
使用IPP获得提速是很显著的。
OpenCV使用了优化了的C和C++代码实现,它对IPP不存在任何依赖。但如果安装了IPP,那么OpenCV将会通过自动载入IPP动态链接库获取IPP的优势。
获得IPP并安装: & ; 请使用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)
如果是1.1版本的那么安装文件是:
下载安装程序后,运行安装程序。安装程序将安装openCV并注册DirectShow filter,然后进行一些安装后的处理。
现在可以进入.../opencv/_make,使用MSVC++akg MSVC.NET 2005打开opencv.sln,然后生成Debug版本的库或Release版的库。
2、当然也可去下载它的源码来通过CMake自己编译.
OpenCV2.1.0编译详细讲解
OpenCV源文件的下载(下载最新版本的OpenCV2.1.0)
CMake的安装(2.8.1)
CodeBlock安装
3rdparty库文件的更新
由于videoInput库文件是基于gcc 4.4.*之前版本编译,所以在Mingw4.4.*编译OpenCV时出现sjlj相应错误。
所以在我们编译OpenCV前务必要更新videoInput的库文件
文件下载:
下载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 )
// 是一个高层调用接口,它通过文件名确定被加载文件的格式;
// 且该函数自动分配图像数据结构所需的内存。
// cvLoadImage可以读取大多数格式的图像文件,BMP、DIB、JPEG、JPE、PNG、BBM、PPM
// SR、RAS、TIFF
// 函数执行完后返回一个指针,此指针指向一块为描述该图像文件的数据结构而分配的内存块。
IplImage* img = cvLoadImage( argv[1] );
cvNamedWindow由HighGUI库提供,用于在屏幕上创建一个窗口,将被显示的图像包含于该窗口中。
// 函数第一个参数指定了窗口的的窗口标题。
// 如果要使用HighGUI库所提供的其他函数与该窗口进行交互,我们将通过该参数值引用这个窗口中。
cvNamedWindow(&Example1&, CV_WINDOW_AUTOSIZE );
// 显示该图像
cvShowImage(&Example1&, img );
// 使程序暂停,等待用户触发一个按键操作,但如果该函数参数设为一个正数,则程序将暂停一段时间,
// 时间长为该整数值个毫秒单位
// 如果设置为0,那么将一直等待用户触发按键操作。
cvWaitKey(0);
// 内存释放功能
cvReleaseImage( &img );
// 关闭窗口
cvDestroyWindow(&Example1&);
2、 第二个例子------播放AVI视频
#include &highgui.h&
int main( int argc, char** argv ) {
cvNamedWindow( &Example2&, CV_WINDOW_AUTOSIZE );
// cvCaptureFromAVI()通过参数设置要读入的AVI文件,返回一个指向cvCapture结构的指针
// 这个指针包括了所有关于读入AVI文件的信息,其中包括状态信息。
// 在调用这个函数后,返回指针指向的CvCapture结构被初始化到所对应的AVI文件的开头。
//CvCapture* capture = cvCaptureFromAVI( argv[1] ); // either one will work
CvCapture* capture = cvCreateFileCapture( argv[1] );
while(1) {
// 用来将下一帧视频文件载入内存(实际上是填充或更新CvCapture结构中),返回一个
// 对应当前帧的指针
// 与cvLoadImage不同的是,cvLoadImage为图像分配内存空间,而cvQueryFram使用已经在
// cvCapture结构中分配好的内存,这样的话没必要通过cvReleaseImage()对返回值释放。
frame = cvQueryFrame( capture );
if( !frame )
cvShowImage( &Example2&, frame );
char c = cvWaitKey(33);
if( c == 27 )
cvReleaseCapture( &capture );
cvDestroyWindow( &Example2& );
2、1&视频播放控制&
上例中我们无法在视频播放时进行快速拖动,我们接下来通过加入一个滚动条来实现这个功能。
HighGUI不仅提供了简单的显示函数,还包括一些图像和视频控制方法,其中之一个经常用到的是滚动条,它可以使我们方便地从视频一帧跳到另外一帧。
我们通过调用cvCreateTrackbar()来创建一个滚动条,并通过设置参数确定滚动条所属于的窗口。
/* License:
Oct. 3, 2008
Right to use this code in any way you want without warrenty, support or any guarentee of it working.
BOOK: It would be nice if you cited it:
Learning OpenCV: Computer Vision with the OpenCV Library
by Gary Bradski and Adrian Kaehler
Published by O'Reilly Media, October 3, 2008
AVAILABLE AT:
/Learning-OpenCV-Computer-Vision-Library/dp/
Or: /catalog/0/
or: ISBN-13: 978-
OTHER OPENCV SITES:
* The source code is on sourceforge at:
http://sourceforge.net/projects/opencvlibrary/
* The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
http://opencvlibrary.sourceforge.net/
* An active user group is at:
http://tech./group/OpenCV/
* The minutes of weekly OpenCV development meetings are at:
/wiki/OpenCV
#include &highgui.h&
int main( int argc, char** argv )
// 是一个高层调用接口,它通过文件名确定被加载文件的格式;
// 且该函数自动分配图像数据结构所需的内存。
// cvLoadImage可以读取大多数格式的图像文件,BMP、DIB、JPEG、JPE、PNG、BBM、PPM
// SR、RAS、TIFF
// 函数执行完后返回一个指针,此指针指向一块为描述该图像文件的数据结构而分配的内存块。
IplImage* img = cvLoadImage( argv[1] );
cvNamedWindow由HighGUI库提供,用于在屏幕上创建一个窗口,将被显示的图像包含于该窗口中。
// 函数第一个参数指定了窗口的的窗口标题。
// 如果要使用HighGUI库所提供的其他函数与该窗口进行交互,我们将通过该参数值引用这个窗口中。
cvNamedWindow(&Example1&, CV_WINDOW_AUTOSIZE );
// 显示该图像
cvShowImage(&Example1&, img );
// 使程序暂停,等待用户触发一个按键操作,但如果该函数参数设为一个正数,则程序将暂停一段时间,
// 时间长为该整数值个毫秒单位
// 如果设置为0,那么将一直等待用户触发按键操作。
cvWaitKey(0);
// 内存释放功能
cvReleaseImage( &img );
// 关闭窗口
cvDestroyWindow(&Example1&);
/* License:
Oct. 3, 2008
Right to use this code in any way you want without warrenty, support or any guarentee of it working.
BOOK: It would be nice if you cited it:
Learning OpenCV: Computer Vision with the OpenCV Library
by Gary Bradski and Adrian Kaehler
Published by O'Reilly Media, October 3, 2008
AVAILABLE AT:
/Learning-OpenCV-Computer-Vision-Library/dp/
Or: /catalog/0/
or: ISBN-13: 978-
OTHER OPENCV SITES:
* The source code is on sourceforge at:
http://sourceforge.net/projects/opencvlibrary/
* The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
http://opencvlibrary.sourceforge.net/
* An active user group is at:
http://tech./group/OpenCV/
* The minutes of weekly OpenCV development meetings are at:
/wiki/OpenCV
#include &stdio.h&
#include &iostream&
#include &fstream&
#include &cv.h&
#include &highgui.h&
OK, you caught us.
Video playback under linux is still just bad.
Part of this is due to FFMPEG, part of this
is due to lack of standards in video files.
But the position slider here will often not work. We tried to at least
find number of frames using the &getAVIFrames& hack below.
But, this file shows something of how to
put a slider up and play with it.
g_slider_position = 0;
CvCapture* g_capture
// 定义全局回调函数,它在滚动条被拖动时调用
// 滚动条位置会被作为参数传入。
void onTrackbarSlide(int pos) {
// 允许我们设置CvCapture对象的各种属性
// CV_CAP_PROP_POS_FRAMES表我们以帧数来设置读入位置。
// 如果我们想通过视频长度比例来设置读入位置,我们可以通过用AVI_RATIO代替FRAMES。
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
//Hack because sometimes the number of frames in a video is not accessible.
//Probably delete this on Widows
int getAVIFrames(char * fname) {
char tempSize[4];
// Trying to open the video file
videoFile( fname , ios::in | ios::binary );
// Checking the availablity of the file
if ( !videoFile ) {
cout && &Couldn’t open the input file & && fname &&
exit( 1 );
// get the number of frames
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(
int main( int argc, char** argv ) {
cvNamedWindow( &Example2_3&, CV_WINDOW_AUTOSIZE );
g_capture = cvCreateFileCapture(&E:\\OpenCV\\openCV1.1Test\\tree.avi& /*argv[1]*/ );
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&/*argv[1]*/); //This is a hack because on linux, getting number of frames often doesn't work
printf(&hacked frames %d w %d h %d\n&,frames,tmpw,tmph);
// 创建滚动条
// 可以设置滚动条名称并确定滚动条的所属窗口。
// 将一个变量绑定到这个滚动条来表示滚动条的最大值和一个回调函数
cvCreateTrackbar(
&Position&,
&Example2_3&,
&g_slider_position,
onTrackbarSlide
frames = 0;
while(1) {
frame = cvQueryFrame( g_capture );
if( !frame )
int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES);//This should work, sometimes it does not on linux
frames++; //My cheat
printf(&\nFrame number=%d\n&,frames);
cvSetTrackbarPos(&Position&,&Example2_3&,frames);
cvShowImage( &Example2_3&, frame );
char c = (char)cvWaitKey(10);
if( c == 27 )
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 )
// Create some windows to show the input
// and output images in.
cvNamedWindow( &Example2_4-in&, CV_WINDOW_AUTOSIZE );
cvNamedWindow( &Example2_4-out&, CV_WINDOW_AUTOSIZE );
// Create a window to show our input image
cvShowImage( &Example2_4-in&, image );
// 分配自己的图像结构空间用来存储平滑处理后的图像
// 第一个参数说明了当前图像结构的大小
// 第二个参数告诉了我们各通道每个像素点的数据类型
// 最后一个参数说明了通道的总数。
IplImage* out = cvCreateImage(
cvGetSize(image),
IPL_DEPTH_8U,
// 我们通过使用每个像素周围3*3区域进行高斯平滑处理
cvSmooth( image, out, CV_GAUSSIAN, 5,5 );
// 输入与输出可以是相同的,这将会使我们的程序更加有效。
cvSmooth( out, out, CV_GAUSSIAN, 5, 5);
// Show the smoothed image in the output window
cvShowImage( &Example2_4-out&, out );
// Be tidy
cvReleaseImage( &out );
// Wait for the user to hit a key, then clean up the windows
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 );
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow(&Example1&);
2、3& 对图像进行复杂一点的变换
这里我们将用输出来覆盖输入变量。在OpenCV中我们通过函数cvPyrDown()来完成上述功能。
从旧的图像中读取所需的信息;在OpenCV中,所有的重要数据结构都是以结构体的形式实现的,并以结构体指针的形式传递。
& openCV中没有私有数据!
#include &cv.h&
#include &highgui.h&
IplImage* doPyrDown(
IplImage* in,
filter = IPL_GAUSSIAN_5x5)
// 确保输入的宽高能被2整除.
//assert( in-&width%2 == 0 && in-&height%2 == 0 );
// 从旧的图像中读取所需的信息
// 在OpenCV中,所有的重要数据结构都是以结构体的形式实现的,并以结构体指针的形式传递。
// openCV中没有私有数据!
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,
lowThresh,
highThresh,
if (in-&nChannels != 1)
return(0); // Canny 仅处理多通道图像
IplImage* out = cvCreateImage(
cvGetSize( in ),
in-&depth, //IPL_DEPTH_8U,
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,
lowThresh,
highThresh,
IplImage* out = cvCreateImage(
cvGetSize( in ),
in-&depth, //IPL_DEPTH_8U,
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
IplImage* doPyrDown(
IplImage* in,
filter = IPL_GAUSSIAN_5x5)
// Best to make sure input image is divisible by two.
//assert( in-&width%2 == 0 && in-&height%2 == 0 );
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* 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&);
// 像上面这样进行嵌套调用是一个不好的主意,因为内存空间的释放会成为一个很困难的问题。
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 );
// Canny处理
= doCanny( out, 10, 100, 3 );
cvShowImage(&Example Canny&, out );
cvWaitKey(0);
cvReleaseImage( &img_rgb);
cvReleaseImage( &img_gry);
// 在OpenCV中我们必须确认被释放的空间必须是我们分配的
cvReleaseImage( &out);
cvDestroyWindow(&Example Gray&);
cvDestroyWindow(&Example Pyr&);
cvDestroyWindow(&Example Canny&);
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1091552次
积分:13146
积分:13146
排名:第340名
原创:242篇
转载:263篇
评论:332条
(5)(1)(1)(1)(2)(5)(4)(1)(1)(4)(3)(2)(6)(5)(14)(6)(4)(29)(20)(33)(25)(45)(49)(61)(55)(56)(69)

我要回帖

更多关于 opencv人脸识别程序 的文章

 

随机推荐