在http://www.opencv.org.cn/forum/viewtopic.php?f=10&t=3355 看到了一篇類似的帖子,正好看到這裏,簡單總結一下:
固定閾值化函數cvThreshold,其實它也有一種自適應閾值方法,那就是OSTU(大津法)!!只需要設定參數thresh_type的值爲CV_THRESH_OTSU即可。
Otsu適用於直方圖爲雙峯的圖像,但是不均勻的照明等會導致不滿足雙峯條件,此時應採用動態閾值分割法,基本原理如下:局部區域中感興趣的物體經常要比背景更亮或更暗,局部背景可以通過平滑處理估計,將圖像與其局部背景進行比較。
再看看 cvAdaptiveThreshold用法:
cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value,
int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C),
int threshold_type CV_DEFAULT(CV_THRESH_BINARY),
int block_size CV_DEFAULT(3),
double param1 CV_DEFAULT(5));
分析參數blockSize。這個參數相當重要,
1.要取奇數,如果取偶數運行後就會報錯!!原因看源碼,發現要做一個掩模,所以參數必須是奇數。OpenCV也做了一個檢測,在函數adaptiveThreshold一開始就有CV_Assert(
blockSize % 2 == 1 && blockSize > 1 )。
2.cvAdaptiveThreshold既可以做邊緣提取,也可以實現二值化,是由你所選擇的鄰域所確定的,如果你所選擇的鄰域非常小(比如3×3),那麼很顯然閾值的“自適應程度”就非常高,這在結果圖像中就表現爲邊緣檢測的效果。如果鄰域選擇的比較大(比如31×31),那麼閾值的“自適應程度”就比較低,這在結果圖像中就表現爲二值化的效果。
3.一般情況下,濾波器寬度應該大於被識別物體的寬度。block_size太小,無法代表背景,太大的話會影響到臨近物體。
選定合適的block_size後,我們就可以選定一個更大的閾值param1,更好的抑制噪聲
4.自適應二值化對於光照不均的文字,條碼等,效果很好。