OpenCV 例子代碼的講解、簡介及庫的安裝 .

轉載請標明是引用於 http://blog.csdn.net/chenyujing1234 html

歡迎你們提出意見,一塊兒討論!linux


1、OpenCV介紹:

OpenCV是由Intel性能基元(IPP)團隊主持,並且幾個主要開發者都與IPP團隊保持良好的關係,因此OpenCV利用了IPP高度手工優化的代碼來實現加速ios

使用IPP得到提速是很顯著的。算法

OpenCV使用了優化了的C和C++代碼實現,它對IPP不存在任何依賴。但若是安裝了IPP,那麼OpenCV將會經過自動載入IPP動態連接庫獲取IPP的優點windows

得到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主體分爲五個模塊:ide

OpenCV的CV模塊包含基本的圖像處理函數和高級的計算機視覺算法函數

ML是機器學習庫,包含一些基於統計的分析和聚類工具。工具

HighGUI包含圖像和視頻輸入/輸出的函數。

CXCore包含OpenCV的一些基本數據結構和相關函數。

CvAux模塊,該模塊通常存放一些即將被淘汰的算法和函數(如嵌入式隱馬爾可夫模型的人臉識別算法),同時還有一些新出現的實驗性的算法(如背景和前景的分割)

 

 

 

2、OpenCV庫的得到及編譯
一、 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版的庫。

二、固然也可去下載它的源碼來經過CMake本身編譯.

轉自: http://hi.baidu.com/zgzhaobo/blog/item/5e0df6263d4499058b82a114.html

OpenCV2.1.0編譯詳細講解

準備工做

  1. OpenCV源文件的下載(下載最新版本的OpenCV2.1.0)http://sourceforge.net/projects/opencv/
  2. CMake的安裝(2.8.1)http://www.cmake.org/cmake/resources/software.html
  3. CodeBlock安裝http://sourceforge.net/projects/codeblocks/
  4. 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源文件

  1. Cmake交叉編譯
    按照下面的設置進行配置,上面一行是解壓後的OpenCV的路徑
    下面一行是你須要編譯後存放動態連接庫的文件目錄,可供自由選擇

    注意:這裏兩個路徑都不能有空格或者中文,否則編譯會出現錯誤


    2010-6-6 22-26-42 
    點擊下面configure進行配置(第一次點擊的時候會挑選編譯環境的工具,咱們選擇codeblock:mingw),會出現上面紅色區域內容,勾選你須要的組建,而後再次點擊configure,進行配置相關文件。
    接下來Generate按鈕呈現可用狀態,點擊Generate進行生成相應的編譯環境的工程文件。
    到此,咱們能夠關閉cmake工具,交由codeblock進行處理了。
    打開codeblock工具,打開工程文件,選擇剛纔cmake輸出的文件夾下的對應工程文件。界面以下:
    2010-6-6 22-33-04
    工程上面點擊右鍵,進行build,等待漫長的編譯過程完成。
    此時OpenCV編譯完成!

=============================================================================================

固然你們也能夠把CMake的編譯環境配置成VS的。這樣CMake後會產生編譯VC工程文件:

 

 3、入門程序的實現

在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

 

一、 第一個例子-------顯示圖像

從磁盤中加載並在屏幕上顯示一幅圖像的簡單OpenCV程序

  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. }  

二、 第二個例子------播放AVI視頻
  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. }  

二、1 視頻播放控制 

上例中咱們沒法在視頻播放時進行快速拖動,咱們接下來經過加入一個滾動條來實現這個功能。

HighGUI不只提供了簡單的顯示函數,還包括一些圖像和視頻控制方法,其中之一個常常用到的是滾動條,它可使咱們方便地從視頻一幀跳到另一幀。

咱們經過調用cvCreateTrackbar()來建立一個滾動條,並經過設置參數肯定滾動條所屬於的窗口。

  1. /* License: 
  2.    Oct. 3, 2008 
  3.    Right to use this code in any way you want without warrenty, support or any guarentee of it working. 
  4.  
  5.    BOOK: It would be nice if you cited it: 
  6.    Learning OpenCV: Computer Vision with the OpenCV Library 
  7.      by Gary Bradski and Adrian Kaehler 
  8.      Published by O'Reilly Media, October 3, 2008 
  9.   
  10.    AVAILABLE AT:  
  11.      http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134 
  12.      Or: http://oreilly.com/catalog/9780596516130/ 
  13.      ISBN-10: 0596516134 or: ISBN-13: 978-0596516130     
  14.  
  15.    OTHER OPENCV SITES: 
  16.    * The source code is on sourceforge at: 
  17.      http://sourceforge.net/projects/opencvlibrary/ 
  18.    * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back): 
  19.      http://opencvlibrary.sourceforge.net/ 
  20.    * An active user group is at: 
  21.      http://tech.groups.yahoo.com/group/OpenCV/ 
  22.    * The minutes of weekly OpenCV development meetings are at: 
  23.      http://pr.willowgarage.com/wiki/OpenCV 
  24. */  
  25. #include "highgui.h"   
  26.   
  27. /* 
  28. int main( int argc, char** argv ) 
  29. { 
  30.     // 是一個高層調用接口,它經過文件名肯定被加載文件的格式; 
  31.     // 且該函數自動分配圖像數據結構所需的內存。 
  32.     // cvLoadImage能夠讀取大多數格式的圖像文件,BMP、DIB、JPEG、JPE、PNG、BBM、PPM 
  33.     // SR、RAS、TIFF 
  34.     // 函數執行完後返回一個指針,此指針指向一塊爲描述該圖像文件的數據結構而分配的內存塊。 
  35.     IplImage* img = cvLoadImage( argv[1] ); 
  36.     //  cvNamedWindow由HighGUI庫提供,用於在屏幕上建立一個窗口,將被顯示的圖像包含於該窗口中。 
  37.     // 函數第一個參數指定了窗口的的窗口標題。 
  38.     // 若是要使用HighGUI庫所提供的其餘函數與該窗口進行交互,咱們將經過該參數值引用這個窗口中。 
  39.     cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE ); 
  40.     // 顯示該圖像 
  41.     cvShowImage("Example1", img ); 
  42.     // 使程序暫停,等待用戶觸發一個按鍵操做,但若是該函數參數設爲一個正數,則程序將暫停一段時間, 
  43.     // 時間長爲該整數值個毫秒單位 
  44.     // 若是設置爲0,那麼將一直等待用戶觸發按鍵操做。 
  45.     cvWaitKey(0); 
  46.     // 內存釋放功能 
  47.     cvReleaseImage( &img ); 
  48.     // 關閉窗口 
  49.     cvDestroyWindow("Example1"); 
  50. } 
  51.  
  52. */  
  53.   
  54.   
  55. /* License: 
  56.    Oct. 3, 2008 
  57.    Right to use this code in any way you want without warrenty, support or any guarentee of it working. 
  58.  
  59.    BOOK: It would be nice if you cited it: 
  60.    Learning OpenCV: Computer Vision with the OpenCV Library 
  61.      by Gary Bradski and Adrian Kaehler 
  62.      Published by O'Reilly Media, October 3, 2008 
  63.   
  64.    AVAILABLE AT:  
  65.      http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134 
  66.      Or: http://oreilly.com/catalog/9780596516130/ 
  67.      ISBN-10: 0596516134 or: ISBN-13: 978-0596516130     
  68.  
  69.    OTHER OPENCV SITES: 
  70.    * The source code is on sourceforge at: 
  71.      http://sourceforge.net/projects/opencvlibrary/ 
  72.    * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back): 
  73.      http://opencvlibrary.sourceforge.net/ 
  74.    * An active user group is at: 
  75.      http://tech.groups.yahoo.com/group/OpenCV/ 
  76.    * The minutes of weekly OpenCV development meetings are at: 
  77.      http://pr.willowgarage.com/wiki/OpenCV 
  78. */  
  79. #include <stdio.h>   
  80. #include <iostream>   
  81. #include <fstream>   
  82. #include "cv.h"   
  83. #include "highgui.h"   
  84. /* 
  85. OK, you caught us.  Video playback under linux is still just bad.  Part of this is due to FFMPEG, part of this 
  86. is due to lack of standards in video files.  But the position slider here will often not work. We tried to at least 
  87. find number of frames using the "getAVIFrames" hack below.  Terrible.  But, this file shows something of how to 
  88. put a slider up and play with it.  Sorry. 
  89. */  
  90.   
  91.   
  92. using namespace std;  
  93.   
  94. int        g_slider_position = 0;  
  95. CvCapture* g_capture         = NULL;  
  96.   
  97. // 定義全局回調函數,它在滾動條被拖動時調用   
  98. // 滾動條位置會被做爲參數傳入。   
  99. void onTrackbarSlide(int pos) {  
  100.     // 容許咱們設置CvCapture對象的各類屬性   
  101.     // CV_CAP_PROP_POS_FRAMES表咱們以幀數來設置讀入位置。   
  102.     // 若是咱們想經過視頻長度比例來設置讀入位置,咱們能夠經過用AVI_RATIO代替FRAMES。   
  103.     cvSetCaptureProperty(  
  104.         g_capture,  
  105.         CV_CAP_PROP_POS_FRAMES,  
  106.         pos  
  107.     );  
  108. }  
  109.   
  110. //Hack because sometimes the number of frames in a video is not accessible.    
  111. //Probably delete this on Widows   
  112. int getAVIFrames(char * fname) {   
  113.     char tempSize[4];  
  114.     // Trying to open the video file   
  115.     ifstream  videoFile( fname , ios::in | ios::binary );  
  116.     // Checking the availablity of the file   
  117.     if ( !videoFile ) {  
  118.       cout << "Couldn’t open the input file " << fname << endl;  
  119.       exit( 1 );  
  120.     }  
  121.     // get the number of frames   
  122.     videoFile.seekg( 0x30 , ios::beg );  
  123.     videoFile.read( tempSize , 4 );  
  124.     int frames = (unsigned char ) tempSize[0] + 0x100*(unsigned char ) tempSize[1] + 0x10000*(unsigned char ) tempSize[2] +    0x1000000*(unsigned char ) tempSize[3];  
  125.     videoFile.close(  );  
  126.     return frames;  
  127. }  
  128.   
  129.   
  130. int main( int argc, char** argv ) {  
  131.     cvNamedWindow( "Example2_3", CV_WINDOW_AUTOSIZE );  
  132.     g_capture = cvCreateFileCapture("E:\\OpenCV\\openCV1.1Test\\tree.avi" /*argv[1]*/ );  
  133.     IplImage *foo = cvQueryFrame( g_capture);  
  134.   
  135.   
  136.     // 得到視頻文件的總幀數以對滾動條進行設置。   
  137.     int frames = (int) cvGetCaptureProperty(  
  138.         g_capture,  
  139.         CV_CAP_PROP_FRAME_COUNT  
  140.     );  
  141.       
  142.     // 得到寬   
  143.     int tmpw = (int) cvGetCaptureProperty(  
  144.         g_capture,  
  145.         CV_CAP_PROP_FRAME_WIDTH  
  146.     );  
  147.   
  148.     // 得到高   
  149.     int tmph = (int) cvGetCaptureProperty(  
  150.         g_capture,  
  151.         CV_CAP_PROP_FRAME_HEIGHT  
  152.     );  
  153.   
  154.     printf("opencv frames %d w %d h %d\n",frames,tmpw,tmph);  
  155.   
  156.     // 分析視頻文件來得到總共有幾幀   
  157.     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   
  158.   
  159.     printf("hacked frames %d w %d h %d\n",frames,tmpw,tmph);  
  160.   
  161.     // 建立滾動條   
  162.     // 能夠設置滾動條名稱並肯定滾動條的所屬窗口。   
  163.     // 將一個變量綁定到這個滾動條來表示滾動條的最大值和一個回調函數   
  164.     cvCreateTrackbar(  
  165.         "Position",  
  166.         "Example2_3",  
  167.         &g_slider_position,  
  168.         frames,  
  169.         onTrackbarSlide  
  170.     );  
  171.     IplImage* frame;  
  172.     frames = 0;  
  173.     while(1) {  
  174.         frame = cvQueryFrame( g_capture );  
  175.         if( !frame ) break;  
  176. //      int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES);//This should work, sometimes it does not on linux   
  177.     frames++; //My cheat   
  178.     printf("\nFrame number=%d\n",frames);  
  179.         cvSetTrackbarPos("Position","Example2_3",frames);  
  180.         cvShowImage( "Example2_3", frame );  
  181.         char c = (char)cvWaitKey(10);  
  182.         if( c == 27 ) break;  
  183.     }  
  184.     cvReleaseCapture( &g_capture );  
  185.     cvDestroyWindow( "Example2_3" );  
  186.     return(0);  
  187. }  

 二、2  對圖像進行簡單的變換

如今咱們要對視頻的播放中的每一幀進行圖像平滑處理,經過對圖像數據與高斯或者其餘核函數進行卷積有效地減小圖像信息內容

OpenCV使得這個卷積操做很是容易。

咱們先建立一個窗口「Example4-out" 用來顯示處理後的圖像。而後在咱們調用cvShowImage()來顯示新捕捉的圖像之後,咱們能夠計算

和在輸出窗口中顯示平滑處理後的圖像。

效果以下:

  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. }  

二、3  對圖像進行復雜一點的變換

這裏咱們將用輸出來覆蓋輸入變量。在OpenCV中咱們經過函數cvPyrDown()來完成上述功能。

從舊的圖像中讀取所需的信息;在OpenCV中,全部的重要數據結構都是以結構體的形式實現的,並以結構體指針的形式傳遞。
  openCV中沒有私有數據!

 

  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. }  


二、4  Canny邊緣檢測

在進行Canny處理前得先進行灰度處理

cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);

  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. }  


接下來咱們想縮放圖像兩次,而後在縮放後的圖像中尋找邊緣,具體以下所示:

 

 

  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. }  


二、四、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);

因此咱們把例子改成:

  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.     IplImage* img_pyr  = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 ); 
  9.     IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 ); 
  10.     IplImage* img_cny  = doCanny( img_pyr2, 10, 100, 3 ); 
  11.  
  12.     cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE ); 
  13.     cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE ); 
  14.     cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE ); 
  15.     cvShowImage("Example Gray", img_gry ); 
  16.     cvShowImage("Example Pyr", img_pyr2 ); 
  17.     cvShowImage("Example Canny", img_cny ); 
  18.  
  19.     cvWaitKey(0); 
  20.     cvReleaseImage( &img_rgb); 
  21.     cvReleaseImage( &img_gry); 
  22.     cvReleaseImage( &img_pyr); 
  23.     cvReleaseImage( &img_pyr2); 
  24.     cvReleaseImage( &img_cny); 
  25.     cvDestroyWindow("Example Gray"); 
  26.     cvDestroyWindow("Example Pyr"); 
  27.     cvDestroyWindow("Example Canny"); 
  28.     */  
  29.   
  30.   
  31.     // 像上面這樣進行嵌套調用是一個很差的主意,由於內存空間的釋放會成爲一個很困難的問題。   
  32.     IplImage* out;  
  33.     cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );  
  34.     cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );  
  35.     cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );  
  36.   
  37.     // 第一次縮放   
  38.     cvShowImage("Example Gray", img_gry );  
  39.     out = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 );  
  40.     // 第一次縮放   
  41.     cvShowImage("Example Pyr", out );  
  42.     out = doPyrDown( out, IPL_GAUSSIAN_5x5 );  
  43.     // Canny處理   
  44.     out  = doCanny( out, 10, 100, 3 );  
  45.     cvShowImage("Example Canny", out );  
  46.   
  47.     cvWaitKey(0);  
  48.     cvReleaseImage( &img_rgb);  
  49.     cvReleaseImage( &img_gry);  
  50.     // 在OpenCV中咱們必須確認被釋放的空間必須是咱們分配的   
  51.     cvReleaseImage( &out);  
  52.     cvDestroyWindow("Example Gray");  
  53.     cvDestroyWindow("Example Pyr");  
  54.     cvDestroyWindow("Example Canny");  
  55.   
  56.       
  57. }  
相關文章
相關標籤/搜索