【OpenCV入門指南】第四篇 影象的二值化
【OpenCV入門指南】第四篇 影象的二值化
在上一篇《【OpenCV入門指南】第三篇Canny邊緣檢測》中介紹了使用Canny運算元對影象進行邊緣檢測。與邊緣檢測相比,輪廓檢測有時能更好的反映影象的內容。而要對影象進行輪廓檢測,則必須要先對影象進行二值化,影象的二值化就是將影象上的畫素點的灰度值設定為0或255,這樣將使整個影象呈現出明顯的黑白效果。在數字影象處理中,二值影象佔有非常重要的地位,影象的二值化使影象中資料量大為減少,從而能凸顯出目標的輪廓。
《OpenCV入門指南》系列文章地址:http://blog.csdn.net/morewindows/article/category/1291764
一. 關鍵函式介紹
下面就介紹OpenCV中對影象進行二值化的關鍵函式——cvThreshold()。
函式功能:採用Canny方法對影象進行邊緣檢測
函式原型:
void cvThreshold(
const CvArr* src,
CvArr* dst,
double threshold,
double max_value,
int threshold_type
);
函式說明:
第一個引數表示輸入影象,必須為單通道灰度圖。
第二個引數表示輸出的邊緣影象,為單通道黑白圖。
第三個引數表示閾值
第四個引數表示最大值。
第五個引數表示運算方法。
在OpenCV的imgproc\types_c.h中可以找到運算方法的定義。
/* Threshold types */
enum
{
CV_THRESH_BINARY =0, /* value = value > threshold ? max_value : 0 */
CV_THRESH_BINARY_INV
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 */
};
註釋已經寫的很清楚了,因此不再用中文來表達了。
二. 示例程式程式碼
下面給出對影象進行二值化的完整的原始碼:
//影象的二值化
//By MoreWindows (http://blog.csdn.net/MoreWindows)
#include <opencv2/opencv.hpp>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
IplImage *g_pGrayImage = NULL;
IplImage *g_pBinaryImage = NULL;
const char *pstrWindowsBinaryTitle = "二值圖(http://blog.csdn.net/MoreWindows)";
void on_trackbar(int pos)
{
// 轉為二值圖
cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);
// 顯示二值圖
cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);
}
int main( int argc, char** argv )
{
const char *pstrWindowsSrcTitle = "原圖(http://blog.csdn.net/MoreWindows)";
const char *pstrWindowsToolBarName = "二值圖閾值";
// 從檔案中載入原圖
IplImage *pSrcImage = cvLoadImage("002.jpg", CV_LOAD_IMAGE_UNCHANGED);
// 轉為灰度圖
g_pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);
// 建立二值圖
g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);
// 顯示原圖
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsSrcTitle, pSrcImage);
// 建立二值圖視窗
cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
// 滑動條
int nThreshold = 0;
cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);
on_trackbar(1);
cvWaitKey(0);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsBinaryTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&g_pGrayImage);
cvReleaseImage(&g_pBinaryImage);
return 0;
}
執行結果如下所示,讀者可以到下載原始檔和程式(Release版本,不用安裝OpenCV也能使用),自己動手除錯下閾值大小,看看生成的二值圖有什麼變化。
OpenCV還有個cvAdaptiveThreshold()函式,這個函式會使用Otsu演算法(大律法或最大類間方差法)(注1)來計算出一個全域性閾值,然後根據這個閾值進行二值化。當然直接使用上一篇《【OpenCV入門指南】第三篇Canny邊緣檢測》中的cvCanny()函式也可以對影象進行二值化(想到怎麼傳引數了嗎?)。
好了,影象的二值化就介紹到這裡了,歡迎繼續瀏覽下面二篇《【OpenCV入門指南】第五篇輪廓檢測上》和《【OpenCV入門指南】第六篇輪廓檢測下》,謝謝。
注1.呼叫cvThreshold()時傳入引數CV_THRESH_OTSU也是使用Otsu演算法來自動生成一個閾值。
轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/8239678
《OpenCV入門指南》系列文章地址:http://blog.csdn.net/morewindows/article/category/1291764
再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!希望你也加入到我們人工智慧的隊伍中來!http://www.captainbed.net