一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

OpenCV入門指南

 BeautymengRoom 2014-07-10


目錄(?)[+]

【OpenCV第一篇】安裝OpenCV

本篇主要介紹如何下載OpenCV安裝程序,如何在VS2008下安裝配置OpenCV,文章最后還介紹了一個(gè)使用OpenCV的簡單小例子。

一.OpenCV的下載

可以到http://www./index.php/Download,然后選一個(gè)較新版本下載。我下的是V2.3.1版本,下載地址是:

http://www./download/OpenCV-2.3.1-win-superpack.exe

下載完成后,雙擊運(yùn)行exe,選擇輸出目錄,我選擇的是D:\opencv。然后解壓縮就完成了安裝。安裝過程如下圖所示:

 

二.在我的電腦中配置OpenCV

在“我的電腦”右擊彈出“系統(tǒng)屬性”對話框,選擇“高級”再點(diǎn)擊“環(huán)境變量”,然后再編輯path,在“編輯用戶變量”對話框的變量值輸入以下三條,注意用“;”來分開。

D:\opencv\opencv\build\x86\vc9\bin;

D:\opencv\opencv\build\x86\mingw\bin;

D:\opencv\opencv\build\common\tbb\ia32\vc9;

 

三.在VS2008中加入OpenCV

VS2008中點(diǎn)擊“工具”,再點(diǎn)擊“選項(xiàng)”,然后選擇“項(xiàng)目和解決方案”,手動加入庫文件,引用文件和包含文件即可完成OpenCVVS2008的導(dǎo)入。 

 

四.第一個(gè)OpenCV程序

下面是最簡單的OpenCV使用例子,功能也很簡單——加載圖像文件并顯示出來。代碼如下:

  1. //顯示圖像文件   

  2. #include <opencv2/opencv.hpp>   

  3. using namespace std;  

  4. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")   

  5. int main()  

  6. {  

  7.     const char *pstrImageName = "沖浪大師賽001.jpg";  

  8.     const char *pstrWindowsTitle = "OpenCV第一個(gè)程序(http://blog.csdn.net/MoreWindows)";  

  9.     //從文件中讀取圖像   

  10.     IplImage *pImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  

  11.     //創(chuàng)建窗口   

  12.     cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE);  

  13.     //在指定窗口中顯示圖像   

  14.     cvShowImage(pstrWindowsTitle, pImage);  

  15.     //等待按鍵事件   

  16.     cvWaitKey();  

  17.     cvDestroyWindow(pstrWindowsTitle);  

  18.     cvReleaseImage(&pImage);  

  19.     return 0;  

  20. }  

  1. //顯示圖像文件  

  2. #include <opencv2/opencv.hpp>  

  3. using namespace std;  

  4. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  5. int main()  

  6. {  

  7.     const char *pstrImageName = "沖浪大師賽001.jpg";  

  8.     const char *pstrWindowsTitle = "OpenCV第一個(gè)程序(http://blog.csdn.net/MoreWindows)";  

  9.     //從文件中讀取圖像  

  10.     IplImage *pImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  

  11.     //創(chuàng)建窗口  

  12.     cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE);  

  13.     //在指定窗口中顯示圖像  

  14.     cvShowImage(pstrWindowsTitle, pImage);  

  15.     //等待按鍵事件  

  16.     cvWaitKey();  

  17.     cvDestroyWindow(pstrWindowsTitle);  

  18.     cvReleaseImage(&pImage);  

  19.     return 0;  

  20. }  

對代碼中的主要函數(shù)進(jìn)行下講解:

1.創(chuàng)建窗口 cvNamedWindow

函數(shù)名稱:cvNamedWindow
函數(shù)功能:創(chuàng)建窗口

函數(shù)原型:
int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );

參數(shù)說明:
第一個(gè)參數(shù)表示
窗口的名字,它被用來區(qū)分不同的窗口,并被顯示為窗口標(biāo)題。被創(chuàng)建的窗口可以通過它們的名字被引用。
第二個(gè)參數(shù)表示
窗口屬性標(biāo)志。目前唯一支持的標(biāo)志是CV_WINDOW_AUTOSIZE。當(dāng)這個(gè)標(biāo)志被設(shè)置后,用戶不能手動改變窗口大小,窗口大小會自動調(diào)整以適合被顯示圖像。
函數(shù)cvNamedWindow創(chuàng)建一個(gè)可以放置圖像和trackbar的窗口。

注意:
如果已經(jīng)存在這個(gè)名字的窗口,這個(gè)函數(shù)將不做任何事情。

2.在指定窗口中顯示圖像 cvShowImage

函數(shù)名稱:cvShowImage
函數(shù)功能:在指定窗口中顯示圖像

函數(shù)原型:
void cvShowImage
( const char* name, const CvArr* image );
參數(shù)說明:

第一個(gè)參數(shù):窗口的名字。
第二個(gè)參數(shù):
被顯示的圖像。

3.等待按鍵事件 cvWaitKey

函數(shù)名稱:cvWaitKey

函數(shù)功能:等待按鍵事件

函數(shù)原型:
int cvWaitKey
( int delay=0 );
參數(shù)說明:

第一個(gè)參數(shù):延遲的毫秒數(shù),當(dāng)delay<=0時(shí)表示無限等待。

函數(shù)返回值:

如果超過指定時(shí)間則返回-1,否則返回被按鍵的值。

編譯,居然出錯(cuò)了?。″e(cuò)誤信息如下:

1>正在鏈接...

1>opencv_test1.obj : error LNK2019:無法解析的外部符號_cvReleaseImage,該符號在函數(shù)_main中被引用

1>opencv_test1.obj : error LNK2019:無法解析的外部符號_cvDestroyWindow,該符號在函數(shù)_main中被引用

1>opencv_test1.obj : error LNK2019:無法解析的外部符號_cvWaitKey,該符號在函數(shù)_main中被引用

1>opencv_test1.obj : error LNK2019:無法解析的外部符號_cvShowImage,該符號在函數(shù)_main中被引用

1>opencv_test1.obj : error LNK2019:無法解析的外部符號_cvNamedWindow,該符號在函數(shù)_main中被引用

1>opencv_test1.obj : error LNK2019:無法解析的外部符號_cvLoadImage,該符號在函數(shù)_main中被引用

現(xiàn)在如何解決這個(gè)問題了?既然是在鏈接時(shí)出的錯(cuò),說明肯定有靜態(tài)庫沒有被編譯器找到。因此我們在VS2008中點(diǎn)擊“項(xiàng)目”,再點(diǎn)擊“屬性”,依次展開“配置屬性”-->“鏈接器”-->“輸入”在“附加依賴項(xiàng)中”添加如下靜態(tài)文件。

opencv_calib3d231d.lib opencv_contrib231d.lib opencv_core231d.lib opencv_features2d231d.lib opencv_flann231d.lib opencv_gpu231d.lib opencv_highgui231d.lib opencv_imgproc231d.lib opencv_legacy231d.lib opencv_ml231d.lib opencv_objdetect231d.lib opencv_ts231d.lib opencv_video231d.lib

再編譯,成功。程序運(yùn)行結(jié)果如下圖所示:

呵呵,很酷的沖浪~~

【OpenCV入門指南】第二篇 縮放圖像

 一. 主要函數(shù)介紹

1.1 cvResize

函數(shù)功能:圖像大小變換

函數(shù)原型:

voidcvResize(

  const CvArr*src,

  CvArr*dst,

  intinterpolation=CV_INTER_LINEAR

);

函數(shù)說明:

第一個(gè)參數(shù)表示輸入圖像。

第二個(gè)參數(shù)表示輸出圖像。

第三個(gè)參數(shù)表示插值方法,可以有以下四種:

CV_INTER_NN -最近鄰插值,

CV_INTER_LINEAR -雙線性插值 (缺省使用)

CV_INTER_AREA -使用象素關(guān)系重采樣。當(dāng)圖像縮小時(shí)候,該方法可以避免波紋出現(xiàn)。當(dāng)圖像放大時(shí),類似于 CV_INTER_NN方法..

CV_INTER_CUBIC -立方插值.

這個(gè)函數(shù)在功能上與Win32 API中的StretchBlt()函數(shù)類似。

1.2 cvCreateImage

函數(shù)功能:創(chuàng)建圖像

函數(shù)原型:

IplImage*cvCreateImage(CvSizesize, intdepth,intchannels);

函數(shù)說明:

第一個(gè)參數(shù)表示圖像的大小。

第二個(gè)參數(shù)表示圖像的深度,可以為IPL_DEPTH_8U,IPL_DEPTH_16U等等。

第三個(gè)參數(shù)表示圖像的通道數(shù)。

二. 示例程序代碼

有了這二個(gè)函數(shù)后,不難寫出代碼:

  1. //縮放圖像文件   

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)   

  3. #include <opencv2/opencv.hpp>   

  4. using namespace std;  

  5. //隱藏控制臺窗口   

  6. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")   

  7. int main()  

  8. {  

  9.     const char *pstrImageName = "沖浪大師賽001.jpg";  

  10.     const char *pstrSaveImageName = "沖浪大師賽001縮放圖.jpg";  

  11.     const char *pstrWindowsSrcTitle = "原圖 (http://blog.csdn.net/MoreWindows)";  

  12.     const char *pstrWindowsDstTitle = "縮放圖 (http://blog.csdn.net/MoreWindows)";  

  13.     double fScale = 0.314;      //縮放倍數(shù)   

  14.     CvSize czSize;              //目標(biāo)圖像尺寸   

  15.     //從文件中讀取圖像     

  16.     IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  

  17.     IplImage *pDstImage = NULL;   

  18.     //計(jì)算目標(biāo)圖像大小   

  19.     czSize.width = pSrcImage->width * fScale;  

  20.     czSize.height = pSrcImage->height * fScale;  

  21.     //創(chuàng)建圖像并縮放   

  22.     pDstImage = cvCreateImage(czSize, pSrcImage->depth, pSrcImage->nChannels);  

  23.     cvResize(pSrcImage, pDstImage, CV_INTER_AREA);  

  24.     //創(chuàng)建窗口   

  25.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  26.     cvNamedWindow(pstrWindowsDstTitle, CV_WINDOW_AUTOSIZE);  

  27.     //在指定窗口中顯示圖像   

  28.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  29.     cvShowImage(pstrWindowsDstTitle, pDstImage);  

  30.     //等待按鍵事件   

  31.     cvWaitKey();  

  32.     //保存圖片   

  33.     cvSaveImage(pstrSaveImageName, pDstImage);  

  34.     cvDestroyWindow(pstrWindowsSrcTitle);  

  35.     cvDestroyWindow(pstrWindowsDstTitle);  

  36.     cvReleaseImage(&pSrcImage);  

  37.     cvReleaseImage(&pDstImage);  

  38.     return 0;  

  39. }  

  1. //縮放圖像文件  

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)  

  3. #include <opencv2/opencv.hpp>  

  4. using namespace std;  

  5. //隱藏控制臺窗口  

  6. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  7. int main()  

  8. {  

  9.     const char *pstrImageName = "沖浪大師賽001.jpg";  

  10.     const char *pstrSaveImageName = "沖浪大師賽001縮放圖.jpg";  

  11.     const char *pstrWindowsSrcTitle = "原圖 (http://blog.csdn.net/MoreWindows)";  

  12.     const char *pstrWindowsDstTitle = "縮放圖 (http://blog.csdn.net/MoreWindows)";  

  13.     double fScale = 0.314;      //縮放倍數(shù)  

  14.     CvSize czSize;              //目標(biāo)圖像尺寸  

  15.     //從文件中讀取圖像    

  16.     IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  

  17.     IplImage *pDstImage = NULL;   

  18.     //計(jì)算目標(biāo)圖像大小  

  19.     czSize.width = pSrcImage->width * fScale;  

  20.     czSize.height = pSrcImage->height * fScale;  

  21.     //創(chuàng)建圖像并縮放  

  22.     pDstImage = cvCreateImage(czSize, pSrcImage->depth, pSrcImage->nChannels);  

  23.     cvResize(pSrcImage, pDstImage, CV_INTER_AREA);  

  24.     //創(chuàng)建窗口  

  25.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  26.     cvNamedWindow(pstrWindowsDstTitle, CV_WINDOW_AUTOSIZE);  

  27.     //在指定窗口中顯示圖像  

  28.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  29.     cvShowImage(pstrWindowsDstTitle, pDstImage);  

  30.     //等待按鍵事件  

  31.     cvWaitKey();  

  32.     //保存圖片  

  33.     cvSaveImage(pstrSaveImageName, pDstImage);  

  34.     cvDestroyWindow(pstrWindowsSrcTitle);  

  35.     cvDestroyWindow(pstrWindowsDstTitle);  

  36.     cvReleaseImage(&pSrcImage);  

  37.     cvReleaseImage(&pDstImage);  

  38.     return 0;  

  39. }  

程序運(yùn)行結(jié)果如下:

【OpenCV入門指南】第三篇Canny邊緣檢測

    圖像的邊緣檢測的原理是檢測出圖像中所有灰度值變化較大的點(diǎn),而且這些點(diǎn)連接起來就構(gòu)成了若干線條,這些線條就可以稱為圖像的邊緣。

    Canny邊緣檢測算子是John F. Canny 1986年開發(fā)出來的一個(gè)多級邊緣檢測算法。Canny 邊緣檢測的數(shù)學(xué)原理和算法實(shí)現(xiàn)這里就不再了,有興趣的讀者可以查閱專業(yè)書籍,本文主要介紹如何在OpenCV中對圖像進(jìn)行Canny邊緣檢測,下面就來看看這個(gè)函數(shù)的原型。

一. 主要函數(shù)

1.1 cvCanny

函數(shù)功能:采用Canny方法對圖像進(jìn)行邊緣檢測

函數(shù)原型:

voidcvCanny(

  constCvArr* image,

  CvArr*edges,

  doublethreshold1,doublethreshold2,

  intaperture_size=3

);

函數(shù)說明:

第一個(gè)參數(shù)表示輸入圖像,必須為單通道灰度圖。

第二個(gè)參數(shù)表示輸出的邊緣圖像,為單通道黑白圖。

第三個(gè)參數(shù)和第四個(gè)參數(shù)表示閾值,這二個(gè)閾值中當(dāng)中的小閾值用來控制邊緣連接,大的閾值用來控制強(qiáng)邊緣的初始分割即如果一個(gè)像素的梯度大與上限值,則被認(rèn)為是邊緣像素,如果小于下限閾值,則被拋棄。如果該點(diǎn)的梯度在兩者之間則當(dāng)這個(gè)點(diǎn)與高于上限值的像素點(diǎn)連接時(shí)我們才保留,否則刪除。

第五個(gè)參數(shù)表示Sobel算子大小,默認(rèn)為3即表示一個(gè)3*3的矩陣。Sobel算子與高斯拉普拉斯算子都是常用的邊緣算子,詳細(xì)的數(shù)學(xué)原理可以查閱專業(yè)書籍。

為了更好的使用cvCanny()函數(shù),下面再介紹二個(gè)實(shí)用的函數(shù),這二個(gè)函數(shù)對后面的程序?qū)崿F(xiàn)非常有幫助。

1.2 cvCreateTrackbar

函數(shù)功能:創(chuàng)建trackbar并添加到指定窗口

函數(shù)原型:

intcvCreateTrackbar(

  constchar* trackbar_name,

  constchar* window_name,

  int*value,

  intcount,

  CvTrackbarCallbackon_change

);

函數(shù)說明:

第一個(gè)參數(shù)表示該trackbar的名稱。

第二個(gè)參數(shù)表示窗口名稱,該trackbar將顯示在這個(gè)窗口內(nèi)。

第三個(gè)參數(shù)表示創(chuàng)建時(shí)滑塊的位置。

第四個(gè)參數(shù)表示滑塊位置的最大值,最小值固定為0。

第五個(gè)參數(shù)表示回調(diào)函數(shù)。當(dāng)滑塊位置有變化時(shí),系統(tǒng)會調(diào)用該回調(diào)函數(shù)。

注:被創(chuàng)建的trackbar默認(rèn)顯示在指定窗口的頂端,可以通過函數(shù)cvGetTrackbarPos()來獲取trackbar顯示的位置信息,以及通過函數(shù)cvSetTrackbarPos()來重新設(shè)置trackbar的顯示位置。

1.3  CvTrackbarCallback

函數(shù)功能:cvCreateTrackbar()函數(shù)所使用的回調(diào)函數(shù)

函數(shù)定義:

typedef void (CV_CDECL *CvTrackbarCallback)(int pos)

函數(shù)說明:

當(dāng)trackbar位置被改變的時(shí),系統(tǒng)會調(diào)用這個(gè)回調(diào)函數(shù),并將參數(shù)pos設(shè)置為表示trackbar位置的數(shù)值。

二. 示例程序代碼

下面就給出在OpenCV中使用Canny 邊緣檢測的程序代碼:

  1. //圖像的Canny邊緣檢測   

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)   

  3. #include <opencv2/opencv.hpp>   

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")   

  6. IplImage *g_pSrcImage, *g_pCannyImg;  

  7. const char *pstrWindowsCannyTitle = "邊緣檢測圖(http://blog.csdn.net/MoreWindows)";  

  8. //cvCreateTrackbar的回調(diào)函數(shù)   

  9. void on_trackbar(int threshold)  

  10. {  

  11.     //canny邊緣檢測   

  12.     cvCanny(g_pSrcImage, g_pCannyImg, threshold, threshold * 3, 3);  

  13.     cvShowImage(pstrWindowsCannyTitle, g_pCannyImg);  

  14. }  

  15. int main()  

  16. {  

  17.     const char *pstrImageName = "001.jpg";  

  18.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  19.     const char *pstrWindowsToolBar = "Threshold";  

  20.     //從文件中載入圖像的灰度圖CV_LOAD_IMAGE_GRAYSCALE - 灰度圖   

  21.     g_pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_GRAYSCALE);  

  22.     g_pCannyImg = cvCreateImage(cvGetSize(g_pSrcImage), IPL_DEPTH_8U, 1);  

  23.     //創(chuàng)建窗口   

  24.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  25.     cvNamedWindow(pstrWindowsCannyTitle, CV_WINDOW_AUTOSIZE);  

  26. //創(chuàng)建滑動條   

  27.     int nThresholdEdge = 1;  

  28.     cvCreateTrackbar(pstrWindowsToolBar, pstrWindowsCannyTitle, &nThresholdEdge, 100, on_trackbar);  

  29.     //在指定窗口中顯示圖像   

  30.     cvShowImage(pstrWindowsSrcTitle, g_pSrcImage);  

  31.     on_trackbar(1);  

  32.     //等待按鍵事件   

  33.     cvWaitKey();  

  34.     cvDestroyWindow(pstrWindowsSrcTitle);  

  35.     cvDestroyWindow(pstrWindowsCannyTitle);  

  36.     cvReleaseImage(&g_pSrcImage);  

  37.     cvReleaseImage(&g_pCannyImg);  

  38.     return 0;  

  39. }  

  1. //圖像的Canny邊緣檢測  

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)  

  3. #include <opencv2/opencv.hpp>  

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  6. IplImage *g_pSrcImage, *g_pCannyImg;  

  7. const char *pstrWindowsCannyTitle = "邊緣檢測圖(http://blog.csdn.net/MoreWindows)";  

  8. //cvCreateTrackbar的回調(diào)函數(shù)  

  9. void on_trackbar(int threshold)  

  10. {  

  11.     //canny邊緣檢測  

  12.     cvCanny(g_pSrcImage, g_pCannyImg, threshold, threshold * 3, 3);  

  13.     cvShowImage(pstrWindowsCannyTitle, g_pCannyImg);  

  14. }  

  15. int main()  

  16. {  

  17.     const char *pstrImageName = "001.jpg";  

  18.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  19.     const char *pstrWindowsToolBar = "Threshold";  

  20.     //從文件中載入圖像的灰度圖CV_LOAD_IMAGE_GRAYSCALE - 灰度圖  

  21.     g_pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_GRAYSCALE);  

  22.     g_pCannyImg = cvCreateImage(cvGetSize(g_pSrcImage), IPL_DEPTH_8U, 1);  

  23.     //創(chuàng)建窗口  

  24.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  25.     cvNamedWindow(pstrWindowsCannyTitle, CV_WINDOW_AUTOSIZE);  

  26. //創(chuàng)建滑動條  

  27.     int nThresholdEdge = 1;  

  28.     cvCreateTrackbar(pstrWindowsToolBar, pstrWindowsCannyTitle, &nThresholdEdge, 100, on_trackbar);  

  29.     //在指定窗口中顯示圖像  

  30.     cvShowImage(pstrWindowsSrcTitle, g_pSrcImage);  

  31.     on_trackbar(1);  

  32.     //等待按鍵事件  

  33.     cvWaitKey();  

  34.     cvDestroyWindow(pstrWindowsSrcTitle);  

  35.     cvDestroyWindow(pstrWindowsCannyTitle);  

  36.     cvReleaseImage(&g_pSrcImage);  

  37.     cvReleaseImage(&g_pCannyImg);  

  38.     return 0;  

  39. }  

運(yùn)行效果如圖所示:

本篇介紹了Canny邊緣檢測,這種方法能有效的找出圖像中的所有邊緣。

【OpenCV入門指南】第四篇 圖像的二值化

   在上一篇《【OpenCV入門指南】第三篇Canny邊緣檢測》中介紹了使用Canny算子對圖像進(jìn)行邊緣檢測。與邊緣檢測相比,輪廓檢測有時(shí)能更好的反映圖像的內(nèi)容。而要對圖像進(jìn)行輪廓檢測,則必須要先對圖像進(jìn)行二值化,圖像的二值化就是將圖像上的像素點(diǎn)的灰度值設(shè)置為0255,這樣將使整個(gè)圖像呈現(xiàn)出明顯的黑白效果。在數(shù)字圖像處理中,二值圖像占有非常重要的地位,圖像的二值化使圖像中數(shù)據(jù)量大為減少,從而能凸顯出目標(biāo)的輪廓。

一. 關(guān)鍵函數(shù)介紹

下面就介紹OpenCV中對圖像進(jìn)行二值化的關(guān)鍵函數(shù)——cvThreshold()。

函數(shù)功能:采用Canny方法對圖像進(jìn)行邊緣檢測

函數(shù)原型:

voidcvThreshold(

  constCvArr* src,

  CvArr*dst,

  doublethreshold,

  doublemax_value,

  intthreshold_type

);

函數(shù)說明:

第一個(gè)參數(shù)表示輸入圖像,必須為單通道灰度圖。

第二個(gè)參數(shù)表示輸出的邊緣圖像,為單通道黑白圖。

第三個(gè)參數(shù)表示閾值

第四個(gè)參數(shù)表示最大值。

第五個(gè)參數(shù)表示運(yùn)算方法。

OpenCVimgproc\types_c.h中可以找到運(yùn)算方法的定義。

/* Threshold types */

enum

{

    CV_THRESH_BINARY      =0,  /* value = value > threshold ? max_value : 0      */

    CV_THRESH_BINARY_INV  =1,  /* value = value > threshold ? 0 : max_value      */

    CV_THRESH_TRUNC       =2,  /* value = value > threshold ? threshold : value  */

    CV_THRESH_TOZERO      =3,  /* value = value > threshold ? value : 0          */

    CV_THRESH_TOZERO_INV  =4,  /* value = value > threshold ? 0 : value          */

    CV_THRESH_MASK        =7,

   CV_THRESH_OTSU        =8  /* use Otsu algorithm to choose the optimal threshold value; combine the flag with one of the above CV_THRESH_* values */

};

注釋已經(jīng)寫的很清楚了,因此不再用中文來表達(dá)了。

二. 示例程序代碼

下面給出對圖像進(jìn)行二值化的完整的源代碼:

  1. //圖像的二值化   

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)   

  3. #include <opencv2/opencv.hpp>   

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")   

  6. IplImage *g_pGrayImage = NULL;  

  7. IplImage *g_pBinaryImage = NULL;  

  8. const char *pstrWindowsBinaryTitle = "二值圖(http://blog.csdn.net/MoreWindows)";  

  9. void on_trackbar(int pos)  

  10. {  

  11.     // 轉(zhuǎn)為二值圖   

  12.     cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);  

  13.     // 顯示二值圖   

  14.     cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);  

  15. }  

  16. int main( int argc, char** argv )  

  17. {     

  18.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  19.     const char *pstrWindowsToolBarName = "二值圖閾值";  

  20.     // 從文件中加載原圖   

  21.     IplImage *pSrcImage = cvLoadImage("002.jpg", CV_LOAD_IMAGE_UNCHANGED);  

  22.     // 轉(zhuǎn)為灰度圖   

  23.     g_pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

  24.     cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);  

  25.     // 創(chuàng)建二值圖   

  26.     g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);  

  27.     // 顯示原圖   

  28.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  29.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  30.     // 創(chuàng)建二值圖窗口   

  31.     cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);  

  32.     // 滑動條     

  33.     int nThreshold = 0;  

  34.     cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);  

  35.     on_trackbar(1);  

  36.     cvWaitKey(0);  

  37.     cvDestroyWindow(pstrWindowsSrcTitle);  

  38.     cvDestroyWindow(pstrWindowsBinaryTitle);  

  39.     cvReleaseImage(&pSrcImage);  

  40.     cvReleaseImage(&g_pGrayImage);  

  41.     cvReleaseImage(&g_pBinaryImage);  

  42.     return 0;  

  43. }  

  1. //圖像的二值化  

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)  

  3. #include <opencv2/opencv.hpp>  

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  6. IplImage *g_pGrayImage = NULL;  

  7. IplImage *g_pBinaryImage = NULL;  

  8. const char *pstrWindowsBinaryTitle = "二值圖(http://blog.csdn.net/MoreWindows)";  

  9. void on_trackbar(int pos)  

  10. {  

  11.     // 轉(zhuǎn)為二值圖  

  12.     cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);  

  13.     // 顯示二值圖  

  14.     cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);  

  15. }  

  16. int main( int argc, char** argv )  

  17. {     

  18.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  19.     const char *pstrWindowsToolBarName = "二值圖閾值";  

  20.     // 從文件中加載原圖  

  21.     IplImage *pSrcImage = cvLoadImage("002.jpg", CV_LOAD_IMAGE_UNCHANGED);  

  22.     // 轉(zhuǎn)為灰度圖  

  23.     g_pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

  24.     cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);  

  25.     // 創(chuàng)建二值圖  

  26.     g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);  

  27.     // 顯示原圖  

  28.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  29.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  30.     // 創(chuàng)建二值圖窗口  

  31.     cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);  

  32.     // 滑動條    

  33.     int nThreshold = 0;  

  34.     cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);  

  35.     on_trackbar(1);  

  36.     cvWaitKey(0);  

  37.     cvDestroyWindow(pstrWindowsSrcTitle);  

  38.     cvDestroyWindow(pstrWindowsBinaryTitle);  

  39.     cvReleaseImage(&pSrcImage);  

  40.     cvReleaseImage(&g_pGrayImage);  

  41.     cvReleaseImage(&g_pBinaryImage);  

  42.     return 0;  

  43. }  

運(yùn)行結(jié)果如下所示,讀者可以到下載源文件和程序(Release版本,不用安裝OpenCV也能使用),自己動手調(diào)試下閾值大小,看看生成的二值圖有什么變化。

OpenCV還有個(gè)cvAdaptiveThreshold()函數(shù),這個(gè)函數(shù)會使用Otsu算法(大律法或最大類間方差法)(注1)來計(jì)算出一個(gè)全局閾值,然后根據(jù)這個(gè)閾值進(jìn)行二值化。當(dāng)然直接使用上一篇《OpenCV入門指南】第三篇Canny邊緣檢測》中的cvCanny()函數(shù)也可以對圖像進(jìn)行二值化(想到怎么傳參數(shù)了嗎?)。

1.調(diào)用cvThreshold()時(shí)傳入?yún)?shù)CV_THRESH_OTSU也是使用Otsu算法來自動生成一個(gè)閾值。

【OpenCV入門指南】第五篇 輪廓檢測 上

OpenCV入門指南】第三篇Canny邊緣檢測》中介紹了邊緣檢測,本篇介紹輪廓檢測,輪廓檢測的原理通俗的說就是掏空內(nèi)部點(diǎn),比如原圖中有3*3的矩形點(diǎn)。那么就可以將中間的那一點(diǎn)去掉。

       OpenCV中使用輪廓檢測是非常方便。直接使用cvFindContours函數(shù)就能完成對圖像輪廓的檢測。下面就來看看這個(gè)函數(shù)的用法。 

一.關(guān)鍵函數(shù)

1.1  cvFindContours

函數(shù)功能:對圖像進(jìn)行輪廓檢測,這個(gè)函數(shù)將生成一條鏈表以保存檢測出的各個(gè)輪廓信息,并傳出指向這條鏈表表頭的指針。

函數(shù)原型:

intcvFindContours(

  CvArr*image,

  CvMemStorage*storage,

  CvSeq**first_contour,   

  intheader_size=sizeof(CvContour),

  intmode=CV_RETR_LIST,  

  intmethod=CV_CHAIN_APPROX_SIMPLE,

  CvPointoffset=cvPoint(0,0)

);

函數(shù)說明:

第一個(gè)參數(shù)表示輸入圖像,必須為一個(gè)8位的二值圖像。圖像的二值化請參見《OpenCV入門指南】第四篇圖像的二值化》。

第二參數(shù)表示存儲輪廓的容器。為CvMemStorage類型,定義在OpenCV\core\types_c.h中。

第三個(gè)參數(shù)為輸出參數(shù),這個(gè)參數(shù)將指向用來存儲輪廓信息的鏈表表頭。

第四個(gè)參數(shù)表示存儲輪廓鏈表的表頭大小,當(dāng)?shù)诹鶄€(gè)參數(shù)傳入CV_CHAIN_CODE時(shí),要設(shè)置成sizeof(CvChain),其它情況統(tǒng)一設(shè)置成sizeof(CvContour)。

第五個(gè)參數(shù)為輪廓檢測的模式,有如下取值:

CV_RETR_EXTERNAL:只檢索最外面的輪廓;

  CV_RETR_LIST:檢索所有的輪廓,并將其保存到一條鏈表當(dāng)中;

  CV_RETR_CCOMP:檢索所有的輪廓,并將他們組織為兩層:頂層是各部分的外部邊界,第二層是空洞的邊界;

CV_RETR_TREE:檢索所有的輪廓,并重構(gòu)嵌套輪廓的整個(gè)層次,可以參見下圖。

第六個(gè)參數(shù)用來表示輪廓邊緣的近似方法的,常用值如下所示:

CV_CHAIN_CODE:以Freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點(diǎn)的序列)。

  CV_CHAIN_APPROX_SIMPLE:壓縮水平的、垂直的和斜的部分,也就是,函數(shù)只保留他們的終點(diǎn)部分。

第七個(gè)參數(shù)表示偏移量,比如你要從圖像的(100, 0)開始進(jìn)行輪廓檢測,那么就傳入(100, 0)。

使用cvFindContours函數(shù)能檢測出圖像的輪廓,將輪廓繪制出來則需要另一函數(shù)——cvDrawContours來配合了。下面介紹cvDrawContours函數(shù)。

1.2  cvDrawContours

函數(shù)功能:在圖像上繪制外部和內(nèi)部輪廓

函數(shù)原型:

voidcvDrawContours(

  CvArr *img,

  CvSeq*contour,

  CvScalarexternal_color,

  CvScalarhole_color,

  intmax_level,

  intthickness=1,

  intline_type=8,

  CvPointoffset=cvPoint(0,0)

);

第一個(gè)參數(shù)表示輸入圖像,函數(shù)將在這張圖像上繪制輪廓。

第二個(gè)參數(shù)表示指向輪廓鏈表的指針。

第三個(gè)參數(shù)和第四個(gè)參數(shù)表示顏色,繪制時(shí)會根據(jù)輪廓的層次來交替使用這二種顏色。

第五個(gè)參數(shù)表示繪制輪廓的最大層數(shù),如果是0,只繪制contour;如果是1,追加繪制和contour同層的所有輪廓;如果是2,追加繪制比contour低一層的輪廓,以此類推;如果值是負(fù)值,則函數(shù)并不繪制contour后的輪廓,但是將畫出其子輪廓,一直到abs(max_level) - 1層。

第六個(gè)參數(shù)表示輪廓線的寬度,如果為CV_FILLED則會填充輪廓內(nèi)部。

第七個(gè)參數(shù)表示輪廓線的類型。

第八個(gè)參數(shù)表示偏移量,如果傳入(10,20),那繪制將從圖像的(10,20)處開始。

二.示例程序代碼

下面用一個(gè)非常簡單的例子展示如何使用輪廓檢測。

  1. //圖像的輪廓檢測上   

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)   

  3. #include <opencv2/opencv.hpp>   

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")   

  6. int main( int argc, char** argv )  

  7. {     

  8.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  9.     const char *pstrWindowsOutLineTitle = "輪廓圖(http://blog.csdn.net/MoreWindows)";  

  10.     const int IMAGE_WIDTH = 400;  

  11.     const int IMAGE_HEIGHT = 200;  

  12.     // 創(chuàng)建圖像   

  13.     IplImage *pSrcImage = cvCreateImage(cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 3);  

  14.     // 填充成白色   

  15.     cvRectangle(pSrcImage, cvPoint(0, 0), cvPoint(pSrcImage->width, pSrcImage->height), CV_RGB(255, 255, 255), CV_FILLED);  

  16.     // 畫圓   

  17.     CvPoint ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2);  

  18.     int nRadius = 80;  

  19.     cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 0), CV_FILLED);  

  20.     ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2);  

  21.     nRadius = 30;  

  22.     cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 255), CV_FILLED);  

  23.     // 畫矩形   

  24.     CvPoint ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 20, 20);  

  25.     CvPoint ptRightBottom = cvPoint(IMAGE_WIDTH - 20, IMAGE_HEIGHT - 20);  

  26.     cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(0, 255, 255), CV_FILLED);  

  27.     ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 60, 40);  

  28.     ptRightBottom = cvPoint(IMAGE_WIDTH - 60, IMAGE_HEIGHT - 40);  

  29.     cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(255, 255, 255), CV_FILLED);  

  30.     // 顯示原圖   

  31.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  32.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  33.     // 轉(zhuǎn)為灰度圖   

  34.     IplImage *pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

  35.     cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  

  36.     // 轉(zhuǎn)為二值圖   

  37.     IplImage *pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);  

  38.     cvThreshold(pGrayImage, pBinaryImage, 250, 255, CV_THRESH_BINARY);  

  39.     // 檢索輪廓并返回檢測到的輪廓的個(gè)數(shù)   

  40.     CvMemStorage *pcvMStorage = cvCreateMemStorage();  

  41.     CvSeq *pcvSeq = NULL;  

  42.     cvFindContours(pBinaryImage, pcvMStorage, &pcvSeq, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));  

  43.     // 畫輪廓圖   

  44.     IplImage *pOutlineImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3);  

  45.     int nLevels = 5;  

  46.     // 填充成白色   

  47.     cvRectangle(pOutlineImage, cvPoint(0, 0), cvPoint(pOutlineImage->width, pOutlineImage->height), CV_RGB(255, 255, 255), CV_FILLED);  

  48.     cvDrawContours(pOutlineImage, pcvSeq, CV_RGB(255,0,0), CV_RGB(0,255,0), nLevels, 2);  

  49.     // 顯示輪廓圖   

  50.     cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);  

  51.     cvShowImage(pstrWindowsOutLineTitle, pOutlineImage);  

  52.     cvWaitKey(0);  

  53.     cvReleaseMemStorage(&pcvMStorage);  

  54.     cvDestroyWindow(pstrWindowsSrcTitle);  

  55.     cvDestroyWindow(pstrWindowsOutLineTitle);  

  56.     cvReleaseImage(&pSrcImage);  

  57.     cvReleaseImage(&pGrayImage);  

  58.     cvReleaseImage(&pBinaryImage);  

  59.     cvReleaseImage(&pOutlineImage);  

  60.     return 0;  

  61. }  

  1. //圖像的輪廓檢測上  

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)  

  3. #include <opencv2/opencv.hpp>  

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  6. int main( int argc, char** argv )  

  7. {     

  8.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  9.     const char *pstrWindowsOutLineTitle = "輪廓圖(http://blog.csdn.net/MoreWindows)";  

  10.     const int IMAGE_WIDTH = 400;  

  11.     const int IMAGE_HEIGHT = 200;  

  12.     // 創(chuàng)建圖像  

  13.     IplImage *pSrcImage = cvCreateImage(cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 3);  

  14.     // 填充成白色  

  15.     cvRectangle(pSrcImage, cvPoint(0, 0), cvPoint(pSrcImage->width, pSrcImage->height), CV_RGB(255, 255, 255), CV_FILLED);  

  16.     // 畫圓  

  17.     CvPoint ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2);  

  18.     int nRadius = 80;  

  19.     cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 0), CV_FILLED);  

  20.     ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2);  

  21.     nRadius = 30;  

  22.     cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 255), CV_FILLED);  

  23.     // 畫矩形  

  24.     CvPoint ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 20, 20);  

  25.     CvPoint ptRightBottom = cvPoint(IMAGE_WIDTH - 20, IMAGE_HEIGHT - 20);  

  26.     cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(0, 255, 255), CV_FILLED);  

  27.     ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 60, 40);  

  28.     ptRightBottom = cvPoint(IMAGE_WIDTH - 60, IMAGE_HEIGHT - 40);  

  29.     cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(255, 255, 255), CV_FILLED);  

  30.     // 顯示原圖  

  31.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  32.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  33.     // 轉(zhuǎn)為灰度圖  

  34.     IplImage *pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

  35.     cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  

  36.     // 轉(zhuǎn)為二值圖  

  37.     IplImage *pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);  

  38.     cvThreshold(pGrayImage, pBinaryImage, 250, 255, CV_THRESH_BINARY);  

  39.     // 檢索輪廓并返回檢測到的輪廓的個(gè)數(shù)  

  40.     CvMemStorage *pcvMStorage = cvCreateMemStorage();  

  41.     CvSeq *pcvSeq = NULL;  

  42.     cvFindContours(pBinaryImage, pcvMStorage, &pcvSeq, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));  

  43.     // 畫輪廓圖  

  44.     IplImage *pOutlineImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3);  

  45.     int nLevels = 5;  

  46.     // 填充成白色  

  47.     cvRectangle(pOutlineImage, cvPoint(0, 0), cvPoint(pOutlineImage->width, pOutlineImage->height), CV_RGB(255, 255, 255), CV_FILLED);  

  48.     cvDrawContours(pOutlineImage, pcvSeq, CV_RGB(255,0,0), CV_RGB(0,255,0), nLevels, 2);  

  49.     // 顯示輪廓圖  

  50.     cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);  

  51.     cvShowImage(pstrWindowsOutLineTitle, pOutlineImage);  

  52.     cvWaitKey(0);  

  53.     cvReleaseMemStorage(&pcvMStorage);  

  54.     cvDestroyWindow(pstrWindowsSrcTitle);  

  55.     cvDestroyWindow(pstrWindowsOutLineTitle);  

  56.     cvReleaseImage(&pSrcImage);  

  57.     cvReleaseImage(&pGrayImage);  

  58.     cvReleaseImage(&pBinaryImage);  

  59.     cvReleaseImage(&pOutlineImage);  

  60.     return 0;  

  61. }  

運(yùn)行結(jié)果如下圖所示:

由圖可以看出,輪廓線已經(jīng)按層次交替的繪制成功了,讀者可以修改程序中的cvDrawContours中的nLevels參數(shù),看看圖形會有什么變化。

OpenCV入門指南】第六篇 輪廓檢測 下

上一篇《OpenCV入門指南】第五篇輪廓檢測上》介紹了cvFindContours函數(shù)和cvDrawContours函數(shù),并作了一個(gè)簡單的使用示范。本篇將展示一個(gè)實(shí)例,讓大家對輪廓檢測有個(gè)更加深入的認(rèn)識。

代碼如下:

  1. //圖像的輪廓檢測下   

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)   

  3. #include <opencv2/opencv.hpp>   

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")   

  6. IplImage *g_pGrayImage = NULL;  

  7. const char *pstrWindowsBinaryTitle = "二值圖(http://blog.csdn.net/MoreWindows)";  

  8. const char *pstrWindowsOutLineTitle = "輪廓圖(http://blog.csdn.net/MoreWindows)";  

  9. CvSeq *g_pcvSeq = NULL;  

  10. void on_trackbar(int pos)  

  11. {  

  12.     // 轉(zhuǎn)為二值圖   

  13.     IplImage *pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);  

  14.     cvThreshold(g_pGrayImage, pBinaryImage, pos, 255, CV_THRESH_BINARY);  

  15.     // 顯示二值圖   

  16.     cvShowImage(pstrWindowsBinaryTitle, pBinaryImage);  

  17.     CvMemStorage* cvMStorage = cvCreateMemStorage();  

  18.     // 檢索輪廓并返回檢測到的輪廓的個(gè)數(shù)   

  19.     cvFindContours(pBinaryImage,cvMStorage, &g_pcvSeq);  

  20.     IplImage *pOutlineImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 3);  

  21.     int _levels = 5;  

  22.     cvZero(pOutlineImage);  

  23.     cvDrawContours(pOutlineImage, g_pcvSeq, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels);  

  24.     cvShowImage(pstrWindowsOutLineTitle, pOutlineImage);  

  25.     cvReleaseMemStorage(&cvMStorage);  

  26.     cvReleaseImage(&pBinaryImage);  

  27.     cvReleaseImage(&pOutlineImage);  

  28. }  

  29. int main( int argc, char** argv )  

  30. {     

  31.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  32.     const char *pstrWindowsToolBarName = "二值化";  

  33.     // 從文件中加載原圖   

  34.     IplImage *pSrcImage = cvLoadImage("003.jpg", CV_LOAD_IMAGE_UNCHANGED);  

  35.     // 顯示原圖   

  36.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  37.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  38.     // 轉(zhuǎn)為灰度圖   

  39.     g_pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

  40.     cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);  

  41.     // 創(chuàng)建二值圖和輪廓圖窗口   

  42.     cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);  

  43.     cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);  

  44.     // 滑動條     

  45.     int nThreshold = 0;  

  46.     cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);  

  47.     on_trackbar(1);  

  48.     cvWaitKey(0);  

  49.     cvDestroyWindow(pstrWindowsSrcTitle);  

  50.     cvDestroyWindow(pstrWindowsBinaryTitle);  

  51.     cvDestroyWindow(pstrWindowsOutLineTitle);  

  52.     cvReleaseImage(&pSrcImage);  

  53.     cvReleaseImage(&g_pGrayImage);  

  54.     return 0;  

  55. }  

  1. //圖像的輪廓檢測下  

  2. //By MoreWindows (http://blog.csdn.net/MoreWindows)  

  3. #include <opencv2/opencv.hpp>  

  4. using namespace std;  

  5. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  

  6. IplImage *g_pGrayImage = NULL;  

  7. const char *pstrWindowsBinaryTitle = "二值圖(http://blog.csdn.net/MoreWindows)";  

  8. const char *pstrWindowsOutLineTitle = "輪廓圖(http://blog.csdn.net/MoreWindows)";  

  9. CvSeq *g_pcvSeq = NULL;  

  10. void on_trackbar(int pos)  

  11. {  

  12.     // 轉(zhuǎn)為二值圖  

  13.     IplImage *pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);  

  14.     cvThreshold(g_pGrayImage, pBinaryImage, pos, 255, CV_THRESH_BINARY);  

  15.     // 顯示二值圖  

  16.     cvShowImage(pstrWindowsBinaryTitle, pBinaryImage);  

  17.     CvMemStorage* cvMStorage = cvCreateMemStorage();  

  18.     // 檢索輪廓并返回檢測到的輪廓的個(gè)數(shù)  

  19.     cvFindContours(pBinaryImage,cvMStorage, &g_pcvSeq);  

  20.     IplImage *pOutlineImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 3);  

  21.     int _levels = 5;  

  22.     cvZero(pOutlineImage);  

  23.     cvDrawContours(pOutlineImage, g_pcvSeq, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels);  

  24.     cvShowImage(pstrWindowsOutLineTitle, pOutlineImage);  

  25.     cvReleaseMemStorage(&cvMStorage);  

  26.     cvReleaseImage(&pBinaryImage);  

  27.     cvReleaseImage(&pOutlineImage);  

  28. }  

  29. int main( int argc, char** argv )  

  30. {     

  31.     const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";  

  32.     const char *pstrWindowsToolBarName = "二值化";  

  33.     // 從文件中加載原圖  

  34.     IplImage *pSrcImage = cvLoadImage("003.jpg", CV_LOAD_IMAGE_UNCHANGED);  

  35.     // 顯示原圖  

  36.     cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);  

  37.     cvShowImage(pstrWindowsSrcTitle, pSrcImage);  

  38.     // 轉(zhuǎn)為灰度圖  

  39.     g_pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  

  40.     cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);  

  41.     // 創(chuàng)建二值圖和輪廓圖窗口  

  42.     cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);  

  43.     cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);  

  44.     // 滑動條    

  45.     int nThreshold = 0;  

  46.     cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);  

  47.     on_trackbar(1);  

  48.     cvWaitKey(0);  

  49.     cvDestroyWindow(pstrWindowsSrcTitle);  

  50.     cvDestroyWindow(pstrWindowsBinaryTitle);  

  51.     cvDestroyWindow(pstrWindowsOutLineTitle);  

  52.     cvReleaseImage(&pSrcImage);  

  53.     cvReleaseImage(&g_pGrayImage);  

  54.     return 0;  

  55. }  

程序運(yùn)行結(jié)果如下所示:

可以明顯看出,由于圖像的二值化處理只是根據(jù)圖像中單個(gè)像素的值來決定,因此這種最簡單輪廓檢測所產(chǎn)生的結(jié)果和人眼觀測的實(shí)際感覺肯定是有比較大的區(qū)別的。

輪廓檢測另外還有一個(gè)重要的函數(shù)cvApproxPoly,它的函數(shù)原型如下所示

CVAPI(CvSeq*) cvApproxPoly(

  constvoid* src_seq,

  intheader_size,

  CvMemStorage*storage,

  intmethod,

  doubleparameter,

  intparameter2 CV_DEFAULT(0)

);

這是一個(gè)輪廓的多邊形輪廓逼近函數(shù),這個(gè)函數(shù)用指定精度逼近一個(gè)或多個(gè) 曲線,并返回逼近結(jié)果。一開始覺得這個(gè)函數(shù)沒什么必要,因?yàn)槿绻皇且唵蔚奶崛『惋@示圖像輪廓的話只要cvFindContours函數(shù)就夠了,那么為什么還要這個(gè)函數(shù)呢?后來百度了下,在opencv論壇上找到了答案。

首先,輪廓的多邊形逼近指的是:使用多邊形來近似表示一個(gè)輪廓。其次,多邊形逼近的目的是為了減少輪廓的頂點(diǎn)數(shù)目。但多邊形逼近的結(jié)果依然是一個(gè)輪廓,只是這個(gè)輪廓相對要粗曠一些。

下面看下測試代碼:

#include<cv.h>   
  1. #include<highgui.h>   

  2. int main()  

  3. {  

  4.     IplImage* src = NULL;  

  5.     IplImage* img = NULL;  

  6.     IplImage* dst = NULL;  

  7.     CvMemStorage* storage = cvCreateMemStorage (0);  

  8.     CvMemStorage* storage1 = cvCreateMemStorage (0);  

  9.     CvSeq* contour = 0;  

  10.     CvSeq* cont;  

  11.     CvSeq* mcont;  

  12.     src = cvLoadImage ("8.jpg", 1);  

  13.     img = cvCreateImage (cvGetSize(src), IPL_DEPTH_8U, 1);  

  14.     dst = cvCreateImage (cvGetSize(src), src->depth, src->nChannels);  

  15.     cvCvtColor (src, img, CV_BGR2GRAY);  

  16.     cvThreshold (img, img, 100, 200, CV_THRESH_BINARY);  

  17.     cvFindContours (img, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);  

  18.     if (contour)  

  19.     {  

  20.         CvTreeNodeIterator iterator;  

  21.         cvInitTreeNodeIterator (&iterator, contour,  1);  

  22.         while (0 != (cont = (CvSeq*)cvNextTreeNode (&iterator)))  

  23.         {  

  24.             mcont = cvApproxPoly (cont, sizeof(CvContour), storage1, CV_POLY_APPROX_DP, cvContourPerimeter(cont)*0.02,0);  

  25.             cvDrawContours (dst, mcont, CV_RGB(255,0,0),CV_RGB(0,0,100),1,2,8,cvPoint(0,0));  

  26.         }  

  27.     }  

  28.     cvNamedWindow ("Contour", 1);  

  29.     cvShowImage ("Contour", dst);  

  30.     cvWaitKey (0);  

  31.     cvReleaseMemStorage (&storage);  

  32.     cvReleaseImage (&src);  

  33.     cvReleaseImage (&img);  

  34.     cvReleaseImage (&dst);  

  35.     return 0;  

  36. }  

  1. #include<cv.h>  

  2. #include<highgui.h>  

  3. int main()  

  4. {  

  5.     IplImage* src = NULL;  

  6.     IplImage* img = NULL;  

  7.     IplImage* dst = NULL;  

  8.     CvMemStorage* storage = cvCreateMemStorage (0);  

  9.     CvMemStorage* storage1 = cvCreateMemStorage (0);  

  10.     CvSeq* contour = 0;  

  11.     CvSeq* cont;  

  12.     CvSeq* mcont;  

  13.     src = cvLoadImage ("8.jpg", 1);  

  14.     img = cvCreateImage (cvGetSize(src), IPL_DEPTH_8U, 1);  

  15.     dst = cvCreateImage (cvGetSize(src), src->depth, src->nChannels);  

  16.     cvCvtColor (src, img, CV_BGR2GRAY);  

  17.     cvThreshold (img, img, 100, 200, CV_THRESH_BINARY);  

  18.     cvFindContours (img, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);  

  19.     if (contour)  

  20.     {  

  21.         CvTreeNodeIterator iterator;  

  22.         cvInitTreeNodeIterator (&iterator, contour,  1);  

  23.         while (0 != (cont = (CvSeq*)cvNextTreeNode (&iterator)))  

  24.         {  

  25.             mcont = cvApproxPoly (cont, sizeof(CvContour), storage1, CV_POLY_APPROX_DP, cvContourPerimeter(cont)*0.02,0);  

  26.             cvDrawContours (dst, mcont, CV_RGB(255,0,0),CV_RGB(0,0,100),1,2,8,cvPoint(0,0));  

  27.         }  

  28.     }  

  29.     cvNamedWindow ("Contour", 1);  

  30.     cvShowImage ("Contour", dst);  

  31.     cvWaitKey (0);  

  32.     cvReleaseMemStorage (&storage);  

  33.     cvReleaseImage (&src);  

  34.     cvReleaseImage (&img);  

  35.     cvReleaseImage (&dst);  

  36.     return 0;  

  37. }  

源圖:

           

多邊形逼近的結(jié)果圖:                                               直接用cvFindContours得到的輪廓圖


                     

對比兩個(gè)圖(輪廓顏色不用管),可以發(fā)現(xiàn)多邊形逼近的結(jié)果確實(shí)相對粗曠點(diǎn)。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    中文字幕五月婷婷免费| 亚洲中文字幕剧情在线播放| 99热九九在线中文字幕| 久久亚洲国产视频三级黄| 开心久久综合激情五月天| 国产精品免费不卡视频| 国产免费观看一区二区| 欧美熟妇一区二区在线| 亚洲一级二级三级精品| 国产成人一区二区三区久久| 熟女一区二区三区国产| 日韩视频在线观看成人| 日韩女优视频国产一区| 久久99精品国产麻豆婷婷洗澡| 亚洲熟女诱惑一区二区| 91一区国产中文字幕| 亚洲精品熟女国产多毛| 麻豆国产精品一区二区三区| 欧美在线观看视频三区| 亚洲中文字幕日韩在线| 黑丝袜美女老师的小逼逼| 色鬼综合久久鬼色88| 国产真人无遮挡免费视频一区| 男人大臿蕉香蕉大视频| 国产在线视频好看不卡| 久草精品视频精品视频精品 | 国产色一区二区三区精品视频| 久久国产精品热爱视频| 中文字幕一区二区久久综合| 一区二区三区日韩中文| 91播色在线免费播放| 亚洲一区二区欧美激情| 欧美人妻一区二区三区| 亚洲午夜av久久久精品| 国产成人精品视频一二区| 亚洲永久一区二区三区在线| 99一级特黄色性生活片| 国产又色又粗又黄又爽| 不卡中文字幕在线视频| 亚洲精品福利视频在线观看| 国产福利在线播放麻豆|