局部自適應閾值二值化html
相對全局閾值二值化,天然就有局部自適應閾值二值化,本文利用Emgu CV實現局部自適應閾值二值化算法,並經過調節block大小,實現圖像的邊緣檢測。算法
1、理論概述(轉載自《OpenCV_基於局部自適應閾值的圖像二值化》)編程
局部自適應閾值則是根據像素的鄰域塊的像素值分佈來肯定該像素位置上的二值化閾值。這樣作的好處在於每一個像素位置處的二值化閾值不是固定不變的,而是由其周圍鄰域像素的分佈來決定的。亮度較高的圖像區域的二值化閾值一般會較高,而亮度較低的圖像區域的二值化閾值則會相適應地變小。不一樣亮度、對比度、紋理的局部圖像區域將會擁有相對應的局部二值化閾值。經常使用的局部自適應閾值有:1)局部鄰域塊的均值;2)局部鄰域塊的高斯加權和。 函數
2、程序實現spa
一、關鍵函數.net
關鍵函數 CvInvoke.cvAdaptiveThreshold Method3d
函數功能:code
Transforms grayscale image to binary image. Threshold calculated individually for each pixel. For the method CV_ADAPTIVE_THRESH_MEAN_C it is a mean of blockSize x blockSize pixel neighborhood, subtracted by param1. For the method CV_ADAPTIVE_THRESH_GAUSSIAN_C it is a weighted sum (gaussian) of blockSize x blockSize pixel neighborhood, subtracted by param1.orm
函數原型:htm
public static void cvAdaptiveThreshold(
IntPtr src,
IntPtr dst,
double maxValue,
ADAPTIVE_THRESHOLD_TYPE adaptiveType,
THRESH thresholdType,
int blockSize,
double param1
)
第一個參數src表示輸入圖像,必須爲單通道灰度圖。
第二個參數dst表示輸出的邊緣圖像,爲單通道黑白圖。
第三個參數maxValue表示採用CV_THRESH_BINARY 和CV_THRESH_BINARY_INV門限類型的最大值。
第四個參數adaptiveType表示局部二值化閾值的取值方法,自適應閾值算法使用:CV_ADAPTIVE_THRESH_MEAN_C
或 CV_ADAPTIVE_THRESH_GAUSSIAN_C,
ADAPTIVE_THRESHOLD_TYPE枚舉類型
Member name | Value | Description |
---|---|---|
CV_ADAPTIVE_THRESH_MEAN_C | 0 | indicates that "Mean minus C" should be used for adaptive threshold. |
CV_ADAPTIVE_THRESH_GAUSSIAN_C | 1 | indicates that "Gaussian minus C" should be used for adaptive threshold. |
第五個參數thresholdType表示取閾值類型:必須是下者之一
CV_THRESH_BINARY,
CV_THRESH_BINARY_INV
第六個參數block_size表明用來計算閾值的象素鄰域大小,例如:3,5,7…
第七個參數表示均值或高斯加權平均值所須要減去的一個常數,相似一我的工干預的閾值調整。
對方法 CV_ADAPTIVE_THRESH_MEAN_C,先求出塊中的均值,再減掉param1。
對方法 CV_ADAPTIVE_THRESH_GAUSSIAN_C ,先求出塊中的加權和(gaussian), 再減掉param1。
二、編程實現
採用均值法設定局部適應閾值,塊大小爲25,參數取值爲5.
//局部二值化 Image<Gray, Byte> adaptivethreshimg = new Image<Gray, Byte>(graymi.width, graymi.height); CvInvoke.cvAdaptiveThreshold(grayimg, adaptivethreshimg, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY, 25, 5); pictureBox4.Image = adaptivethreshimg.ToBitmap();
採用本文算法獲取的二值化圖像
第五個參數本文用的是Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY,恰好與原文相反,所以一個是白底,一個是黑底。
轉載請標明出處,原文地址:http://www.cnblogs.com/MobileBo/p/3923599.html
3、結果分析
一、邊緣提取做用
有人提出cvAdaptiveThreshold的做用不是二值化而是提取對象邊緣的觀點
參考文獻:http://wuyiwangyi.blog.163.com/blog/static/3214949520093834537412/
關鍵是裏面的block_size參數,該參數是決定局部閾值的block的大小,當block很小時,如block_size=3 or 5 or 7時,「自適應」的程度很高,即容易出現block裏面的像素值都差很少,這樣便沒法二值化,而只能在邊緣等梯度大的地方實現二值化,結果顯得它是邊緣提取函數。當把block_size設爲比較大的值時,如block_size=21 or 31 or 41時,cvAdaptiveThreshold即是二值化函數啦~
二、block_size取值問題
編程過程當中,發現block_size通常取奇數,若是取偶數會報錯,錯誤內容是"blockSize % 2 == 1 && blockSize > 1"。固然,編程文檔說明提示是3,5,7,...,並無要求是奇數,是這種算法在原理上就要這麼要求嗎?仍是編程須要?我沒法解答。
網上說源代碼要求就是 if( size <= 1 || (size&1) == 0 )
CV_ERROR( CV_StsOutOfRange, "Neighborhood size must be >=3 and odd (3, 5, 7, ...)" );
我的感受是圖像處理算法自己致使的,與編程無關。 原文:http://www.cnblogs.com/MobileBo/p/3923599.html