自適應的閾值化

2021-07-25 23:25:16 字數 1956 閱讀 4529

對影象應用閾值建立二值影象,是提取有意義元素的好方法。但有的時候單一閾值達不到目標提取的效果。

下面比較一下幾種方法的效果。例如,給定一幅圖如下,將「富貴白頭」四個字提取出來。

通過opencv閾值化函式cv::threshold(),純手工選擇引數,進行固定閾值二值化,發現當閾值設為80時效果最好。

//採用固定閾值

cv::threshold(image, binaryfixed, 80, 255, cv::thresh_binary);

固定閾值(取為80)的效果,其實還行了,只不過閾值還是得手工微調:

採用最大類間方差法怎麼樣?自動選擇最優閾值(其實還是單一閾值)。

//大津法

std::cout

<70,255,cv::thresh_otsu);//經測試cout輸出為143

可見大津法算出的閾值為143。但是閾值化效果是很差的:

下面採用opencv的自適應閾值化方法:

cv::adaptivethreshold(image,binaryadaptive,255,cv::adaptive_thresh_mean_c,cv::thresh_binary,7,-4);
效果如下,還不錯,同時花樹的輪廓也描繪出了:

自適應閾值是一種區域性方法。它的原理是根據每個畫素的鄰域計算閾值,包括上面語句採用的將每個畫素的值與鄰域的平均值進行比較。如果某畫素的值與它的區域性平均值差別很大,就會被當做異常值在閾值化過程中被分離。

**實現:

1、使用積分影象實現自適應閾值化

//自己實現自定義閾值

cv::mat iimage;

cv::integral(image,iimage,cv_32s);

cv::mat binary;

image.copyto(binary);

int blocksize = 7;

int threshold = -4;//畫素將與(mean-threshold)比較

int halfsize = blocksize / 2;

for (int j = halfsize; j < image.rows-halfsize-1;j++)

}cv::imshow("thresholdadaptive",binary);

為了簡化計算,計算畫素周圍方形鄰域畫素的和,採用了積分影象。假設鄰域塊的大小為blocksize*blocksize,不採用積分影象,每次需要計算blocksize*blocksize次加法運算;而採用積分影象,運算複雜度並不隨鄰域大小而改變,每次只需計算2次加法和2次減法。

2、使用盒子濾波實現自適應閾值化

cv::mat filtered;

cv::mat binaryfiltered;

cv::boxfilter(image,filtered,cv_8u,cv::size(7,7));//這個盒子濾波相當於平均的效果

filtered = filtered + 4;

binaryfiltered = image >= filtered;

imshow("thresholdbox",binaryfiltered);

自適應閾值

自適應閾值函式 void vcadaptivethreshold cvarr src,cvarr dst,double max val,int adaptive method cv adaptive thresh mean c,int threshold type cv thresh binary,...

自適應閾值二值化

二值化原理 把乙個灰度影象二值化,其實就是找到乙個閾值,使這個較低中,灰度大於這個閾值的,設定成255,灰度小於這個閾值的,設定為0。閾值自適應二值化 非自適應的二值化呢,有乙個問題,就是乙個閾值往往只對應一類影象,如果影象的光照變暗了,那個單閾值情況的二值化效果會大大的折扣。自適應二值化其實就是一...

全域性固定閾值化和區域性自適應閾值化

在影象處理應用中二值化操作是乙個很常用的處理方式,較為常用的影象二值化方法有 1 全域性固定閾值 2 區域性自適應閾值 3 otsu等。全域性固定閾值化 對整幅影象都是用乙個統一的閾值來進行二值化 區域性自適應閾值化 根據畫素的鄰域塊的畫素值分布來確定該畫素位置上的二值化閾值。這樣做的好處在於每個畫...