推广 热搜:
 |  行业设备  |  机械制造  |  机器视觉  |  机械自动化  |  仪器仪表  |  工业机器人  |  编程开发  |  嵌入式  |  电子技术  |  工控自动化  |  电工电气 频道

opencv入门例子

   日期:2018-08-22     浏览:81    评论:0    
核心提示:1、 第一个例子-------显示图像从磁盘中加载并在屏幕上显示一幅图像的简单OpenCV程序[cpp]view plaincopy#includehighgui.hintma
 
1、 第一个例子-------显示图像

从磁盘中加载并在屏幕上显示一幅图像的简单OpenCV程序

[cpp] view plain copy
 
 
 
  1. #include "highgui.h"  
  2.   
  3. int main( int argc, char** argv )  
  4. {  
  5.     // 是一个高层调用接口,它通过文件名确定被加载文件的格式;  
  6.     // 且该函数自动分配图像数据结构所需的内存。  
  7.     // cvLoadImage可以读取大多数格式的图像文件,BMP、DIB、JPEG、JPE、PNG、BBM、PPM  
  8.     // SR、RAS、TIFF  
  9.     // 函数执行完后返回一个指针,此指针指向一块为描述该图像文件的数据结构而分配的内存块。  
  10.     IplImage* img = cvLoadImage( argv[1] );  
  11.     //  cvNamedWindow由HighGUI库提供,用于在屏幕上创建一个窗口,将被显示的图像包含于该窗口中。  
  12.     // 函数第一个参数指定了窗口的的窗口标题。  
  13.     // 如果要使用HighGUI库所提供的其他函数与该窗口进行交互,我们将通过该参数值引用这个窗口中。  
  14.     cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );  
  15.     // 显示该图像  
  16.     cvShowImage("Example1", img );  
  17.     // 使程序暂停,等待用户触发一个按键操作,但如果该函数参数设为一个正数,则程序将暂停一段时间,  
  18.     // 时间长为该整数值个毫秒单位  
  19.     // 如果设置为0,那么将一直等待用户触发按键操作。  
  20.     cvWaitKey(0);  
  21.     // 内存释放功能  
  22.     cvReleaseImage( &img );  
  23.     // 关闭窗口  
  24.     cvDestroyWindow("Example1");  
  25. }  

2、 第二个例子------播放AVI视频
[cpp] view plain copy
 
 
 
  1. #include "highgui.h"  
  2.   
  3. int main( int argc, char** argv ) {   
  4.     cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE );  
  5.     // cvCaptureFromAVI()通过参数设置要读入的AVI文件,返回一个指向cvCapture结构的指针  
  6.     // 这个指针包括了所有关于读入AVI文件的信息,其中包括状态信息。  
  7.     // 在调用这个函数后,返回指针指向的CvCapture结构被初始化到所对应的AVI文件的开头。  
  8.     //CvCapture* capture = cvCaptureFromAVI( argv[1] ); // either one will work  
  9.     CvCapture* capture = cvCreateFileCapture( argv[1] );  
  10.     IplImage* frame;  
  11.     while(1) {  
  12.         // 用来将下一帧视频文件载入内存(实际上是填充或更新CvCapture结构中),返回一个  
  13.         // 对应当前帧的指针  
  14.         // 与cvLoadImage不同的是,cvLoadImage为图像分配内存空间,而cvQueryFram使用已经在  
  15.         // cvCapture结构中分配好的内存,这样的话没必要通过cvReleaseImage()对返回值释放。  
  16.         frame = cvQueryframe( capture );  
  17.         if( !frame ) break;  
  18.         cvShowImage( "Example2", frame );  
  19.         char c = cvWaitKey(33);  
  20.         if( c == 27 ) break;  
  21.     }  
  22.     cvReleaseCapture( &capture );  
  23.     cvDestroyWindow( "Example2" );  
  24. }  

2、1 视频播放控制 

上例中我们无法在视频播放时进行快速拖动,我们接下来通过加入一个滚动条来实现这个功能。

HighGUI不仅提供了简单的显示函数,还包括一些图像和视频控制方法,其中之一个经常用到的是滚动条,它可以使我们方便地从视频一帧跳到另外一帧。

我们通过调用cvCreateTrackbar()来创建一个滚动条,并通过设置参数确定滚动条所属于的窗口。

[cpp] view plain copy
 
 
 
  1.   
  2. #include "highgui.h"  
  3.   
  4.   
  5.   
  6.   
  7.   
  8. #include <stdio.h>  
  9. #include <iostream>  
  10. #include <fstream>  
  11. #include "cv.h"  
  12. #include "highgui.h"  
  13.   
  14.   
  15.   
  16. using namespace std;  
  17.   
  18. int        g_slider_position = 0;  
  19. CvCapture* g_capture         = NULL;  
  20.   
  21. // 定义全局回调函数,它在滚动条被拖动时调用  
  22. // 滚动条位置会被作为参数传入。  
  23. void onTrackbarSlide(int pos) {  
  24.     // 允许我们设置CvCapture对象的各种属性  
  25.     // CV_CAP_PROP_POS_frameS表我们以帧数来设置读入位置。  
  26.     // 如果我们想通过视频长度比例来设置读入位置,我们可以通过用AVI_RATIO代替frameS。  
  27.     cvSetCaptureProperty(  
  28.         g_capture,  
  29.         CV_CAP_PROP_POS_frameS,  
  30.         pos  
  31.     );  
  32. }  
  33.   
  34. //Hack because sometimes the number of frames in a video is not accessible.   
  35. //Probably delete this on Widows  
  36. int getAVIframes(char * fname) {   
  37.     char tempSize[4];  
  38.     // Trying to open the video file  
  39.     ifstream  videoFile( fname , ios::in | ios::binary );  
  40.     // Checking the availablity of the file  
  41.     if ( !videoFile ) {  
  42.       cout << "Couldn’t open the input file " << fname << endl;  
  43.       exit( 1 );  
  44.     }  
  45.     // get the number of frames  
  46.     videoFile.seekg( 0x30 , ios::beg );  
  47.     videoFile.read( tempSize , 4 );  
  48.     int frames = (unsigned char ) tempSize[0] + 0x100*(unsigned char ) tempSize[1] + 0x10000*(unsigned char ) tempSize[2] +    0x1000000*(unsigned char ) tempSize[3];  
  49.     videoFile.close(  );  
  50.     return frames;  
  51. }  
  52.   
  53.   
  54. int main( int argc, char** argv ) {  
  55.     cvNamedWindow( "Example2_3", CV_WINDOW_AUTOSIZE );  
  56.     g_capture = cvCreateFileCapture("E:\\OpenCV\\openCV1.1Test\\tree.avi"  );  
  57.     IplImage *foo = cvQueryframe( g_capture);  
  58.   
  59.   
  60.     // 获得视频文件的总帧数以对滚动条进行设置。  
  61.     int frames = (int) cvGetCaptureProperty(  
  62.         g_capture,  
  63.         CV_CAP_PROP_frame_COUNT  
  64.     );  
  65.       
  66.     // 获得宽  
  67.     int tmpw = (int) cvGetCaptureProperty(  
  68.         g_capture,  
  69.         CV_CAP_PROP_frame_WIDTH  
  70.     );  
  71.   
  72.     // 获得高  
  73.     int tmph = (int) cvGetCaptureProperty(  
  74.         g_capture,  
  75.         CV_CAP_PROP_frame_HEIGHT  
  76.     );  
  77.   
  78.     printf("opencv frames %d w %d h %d\n",frames,tmpw,tmph);  
  79.   
  80.     // 分析视频文件来获得总共有几帧  
  81.     frames = getAVIframes("E:\\OpenCV\\openCV1.1Test\\tree.avi"); //This is a hack because on linux, getting number of frames often doesn't work  
  82.   
  83.     printf("hacked frames %d w %d h %d\n",frames,tmpw,tmph);  
  84.   
  85.     // 创建滚动条  
  86.     // 可以设置滚动条名称并确定滚动条的所属窗口。  
  87.     // 将一个变量绑定到这个滚动条来表示滚动条的最大值和一个回调函数  
  88.     cvCreateTrackbar(  
  89.         "Position",  
  90.         "Example2_3",  
  91.         &g_slider_position,  
  92.         frames,  
  93.         onTrackbarSlide  
  94.     );  
  95.     IplImage* frame;  
  96.     frames = 0;  
  97.     while(1) {  
  98.         frame = cvQueryframe( g_capture );  
  99.         if( !frame ) break;  
  100. //      int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_frameS);//This should work, sometimes it does not on linux  
  101.     frames++; //My cheat  
  102.     printf("\nframe number=%d\n",frames);  
  103.         cvSetTrackbarPos("Position","Example2_3",frames);  
  104.         cvShowImage( "Example2_3", frame );  
  105.         char c = (char)cvWaitKey(10);  
  106.         if( c == 27 ) break;  
  107.     }  
  108.     cvReleaseCapture( &g_capture );  
  109.     cvDestroyWindow( "Example2_3" );  
  110.     return(0);  
  111. }  

 2、2  对图像进行简单的变换

现在我们要对视频的播放中的每一帧进行图像平滑处理,通过对图像数据与高斯或者其他核函数进行卷积有效地减少图像信息内容

OpenCV使得这个卷积操作非常容易。

我们先创建一个窗口“Example4-out" 用来显示处理后的图像。然后在我们调用cvShowImage()来显示新捕捉的图像以后,我们可以计算

和在输出窗口中显示平滑处理后的图像。

效果如下:

[cpp] view plain copy
 
 
 
  1. #include "cv.h"  
  2. #include "highgui.h"  
  3.   
  4. void example2_4( IplImage* image )  
  5. {  
  6.     // Create some windows to show the input  
  7.     // and output images in.  
  8.     //  
  9.     cvNamedWindow( "Example2_4-in", CV_WINDOW_AUTOSIZE );  
  10.     cvNamedWindow( "Example2_4-out", CV_WINDOW_AUTOSIZE );  
  11.   
  12.     // Create a window to show our input image  
  13.     //  
  14.     cvShowImage( "Example2_4-in", image );  
  15.   
  16.   
  17.     // 分配自己的图像结构空间用来存储平滑处理后的图像  
  18.     // 第一个参数说明了当前图像结构的大小  
  19.     // 第二个参数告诉了我们各通道每个像素点的数据类型  
  20.     // 最后一个参数说明了通道的总数。  
  21.     IplImage* out = cvCreateImage(  
  22.         cvGetSize(image),  
  23.         IPL_DEPTH_8U,  
  24.         3  
  25.         );  
  26.   
  27.     // 我们通过使用每个像素周围3*3区域进行高斯平滑处理  
  28.     cvSmooth( image, out, CV_GAUSSIAN, 5,5 );  
  29.     // 输入与输出可以是相同的,这将会使我们的程序更加有效。  
  30.     cvSmooth( out, out, CV_GAUSSIAN, 5, 5);  
  31.   
  32.     // Show the smoothed image in the output window  
  33.     //  
  34.     cvShowImage( "Example2_4-out", out );  
  35.   
  36.     // Be tidy  
  37.     //  
  38.     cvReleaseImage( &out );  
  39.   
  40.     // Wait for the user to hit a key, then clean up the windows  
  41.     //  
  42.     cvWaitKey( 0 );   
  43.     cvDestroyWindow("Example2_4-in" );  
  44.     cvDestroyWindow("Example2_4-out" );  
  45.   
  46. }  
  47.   
  48. int main( int argc, char** argv )  
  49. {  
  50.     IplImage* img = cvLoadImage("adrian.jpg");  
  51.     cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );  
  52.     cvShowImage("Example1", img );  
  53.     example2_4( img );  
  54.     //  cvWaitKey(0);  
  55.     cvReleaseImage( &img );  
  56.     cvDestroyWindow("Example1");  
  57. }  

2、3  对图像进行复杂一点的变换

这里我们将用输出来覆盖输入变量。在OpenCV中我们通过函数cvPyrDown()来完成上述功能。

从旧的图像中读取所需的信息;在OpenCV中,所有的重要数据结构都是以结构体的形式实现的,并以结构体指针的形式传递。
  openCV中没有私有数据!

 

[cpp] view plain copy
 
 
 
  1. #include "cv.h"  
  2. #include "highgui.h"  
  3.   
  4. IplImage* doPyrDown(  
  5.                     IplImage* in,  
  6.                     int       filter = IPL_GAUSSIAN_5x5)  
  7. {  
  8.   
  9.     // 确保输入的宽高能被2整除.  
  10.     //  
  11.     //assert( in->width%2 == 0 && in->height%2 == 0 );  
  12.   
  13.     // 从旧的图像中读取所需的信息  
  14.     // 在OpenCV中,所有的重要数据结构都是以结构体的形式实现的,并以结构体指针的形式传递。  
  15.     // openCV中没有私有数据!  
  16.     IplImage* out = cvCreateImage(   
  17.         cvSize( in->width/2, in->height/2 ),  
  18.         in->depth,  
  19.         in->nChannels  
  20.         );  
  21.     cvPyrDown( in, out );  
  22.     return( out );  
  23. };  
  24.   
  25. int main( int argc, char** argv )  
  26. {  
  27.     IplImage* img = cvLoadImage("adrian.jpg" );  
  28.     IplImage* img2 = cvCreateImage( cvSize( img->width/2,img->height/2 ), img->depth, img->nChannels);  
  29.     cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );  
  30.     cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE );  
  31.     cvShowImage("Example1", img );  
  32.     img2 = doPyrDown( img );  
  33.     cvShowImage("Example2", img2 );  
  34.     cvWaitKey(0);  
  35.     cvReleaseImage( &img );  
  36.     cvReleaseImage( &img2 );  
  37.     cvDestroyWindow("Example1");  
  38.     cvDestroyWindow("Example2");  
  39. }  


2、4  Canny边缘检测

在进行Canny处理前得先进行灰度处理

cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);

[cpp] view plain copy
 
 
 
  1. #include "cv.h"  
  2. #include "highgui.h"  
  3.   
  4. IplImage* doCanny(  
  5.                   IplImage* in,  
  6.                   double    lowThresh,  
  7.                   double    highThresh,  
  8.                   double    aperture)  
  9. {  
  10.     if (in->nChannels != 1)  
  11.         return(0); // Canny 仅处理多通道图像  
  12.     IplImage* out = cvCreateImage(   
  13.         cvGetSize( in ),  
  14.         in->depth, //IPL_DEPTH_8U,      
  15.         1);  
  16.     cvCanny( in, out, lowThresh, highThresh, aperture );  
  17.     return( out );  
  18. };  
  19.   
  20. int main( int argc, char** argv )  
  21. {  
  22.     IplImage* img_rgb = cvLoadImage( "adrian.jpg" );  
  23.     IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);  
  24.     cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);  
  25.     cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );  
  26.     cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );  
  27.     cvShowImage("Example Gray", img_gry );  
  28.     IplImage* img_cny = doCanny( img_gry, 10, 100, 3 );  
  29.     cvShowImage("Example Canny", img_cny );  
  30.     cvWaitKey(0);  
  31.     cvReleaseImage( &img_rgb);  
  32.     cvReleaseImage( &img_gry);  
  33.     cvReleaseImage( &img_cny);  
  34.     cvDestroyWindow("Example Gray");  
  35.     cvDestroyWindow("Example Canny");  
  36. }  


接下来我们想缩放图像两次,然后在缩放后的图像中寻找边缘,具体如下所示:

 

 

[cpp] view plain copy
 
 
 
  1. #include "cv.h"  
  2. #include "highgui.h"  
  3.   
  4. IplImage* doCanny(  
  5.                   IplImage* in,  
  6.                   double    lowThresh,  
  7.                   double    highThresh,  
  8.                   double    aperture)  
  9. {  
  10.     IplImage* out = cvCreateImage(   
  11.         cvGetSize( in ),  
  12.         in->depth, //IPL_DEPTH_8U,      
  13.         1);  
  14.     cvCanny( in, out, lowThresh, highThresh, aperture );  
  15.     return( out );  
  16. };  
  17.   
  18. IplImage* doPyrDown(  
  19.                     IplImage* in,  
  20.                     int       filter = IPL_GAUSSIAN_5x5)  
  21. {  
  22.   
  23.     // Best to make sure input image is divisible by two.  
  24.     //  
  25.     //assert( in->width%2 == 0 && in->height%2 == 0 );  
  26.   
  27.     IplImage* out = cvCreateImage(   
  28.         cvSize( in->width/2, in->height/2 ),  
  29.         in->depth,  
  30.         in->nChannels  
  31.         );  
  32.     cvPyrDown( in, out );  
  33.     return( out );  
  34. };  
  35.   
  36. int main( int argc, char** argv )  
  37. {  
  38.     IplImage* img_rgb  = cvLoadImage( "adrian.jpg" );  
  39.     IplImage* img_gry  = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);  
  40.     cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);  
  41.     IplImage* img_pyr  = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );  
  42.     IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 );  
  43.     IplImage* img_cny  = doCanny( img_pyr2, 10, 100, 3 );  
  44.   
  45.     cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );  
  46.     cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );  
  47.     cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );  
  48.     cvShowImage("Example Gray", img_gry );  
  49.     cvShowImage("Example Pyr", img_pyr2 );  
  50.     cvShowImage("Example Canny", img_cny );  
  51.     cvWaitKey(0);  
  52.     cvReleaseImage( &img_rgb);  
  53.     cvReleaseImage( &img_gry);  
  54.     cvReleaseImage( &img_pyr);  
  55.     cvReleaseImage( &img_pyr2);  
  56.     cvReleaseImage( &img_cny);  
  57.     cvDestroyWindow("Example Gray");  
  58.     cvDestroyWindow("Example Pyr");  
  59.     cvDestroyWindow("Example Canny");  
  60. }  

 

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);

所以我们把例子改为:

[cpp] view plain copy
 
 
 
  1. int main( int argc, char** argv )  
  2. {  
  3.     IplImage* img_rgb  = cvLoadImage( "adrian.jpg" );  
  4.     IplImage* img_gry  = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);  
  5.     cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);  
  6.       
  7.       
  8.   
  9.   
  10.     // 像上面这样进行嵌套调用是一个不好的主意,因为内存空间的释放会成为一个很困难的问题。  
  11.     IplImage* out;  
  12.     cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );  
  13.     cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );  
  14.     cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );  
  15.   
  16.     // 第一次缩放  
  17.     cvShowImage("Example Gray", img_gry );  
  18.     out = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );  
  19.     // 第一次缩放  
  20.     cvShowImage("Example Pyr", out );  
  21.     out = doPyrDown( out, IPL_GAUSSIAN_5x5 );  
  22.     // Canny处理  
  23.     out  = doCanny( out, 10, 100, 3 );  
  24.     cvShowImage("Example Canny", out );  
  25.   
  26.     cvWaitKey(0);  
  27.     cvReleaseImage( &img_rgb);  
  28.     cvReleaseImage( &img_gry);  
  29.     // 在OpenCV中我们必须确认被释放的空间必须是我们分配的  
  30.     cvReleaseImage( &out);  
  31.     cvDestroyWindow("Example Gray");  
  32.     cvDestroyWindow("Example Pyr");  
  33.     cvDestroyWindow("Example Canny");  
  34.   
  35.       
  36. }  
 
打赏
 
更多>同类编程
0相关评论

推荐图文
推荐编程
点击排行

网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报