圖像二值化
一、閾值概念
閾值:簡單來說就是一把分割圖像像素的標尺,在二值化處理中有固定閾值和自適應(yīng)閾值兩種形式。
那么什么時候用固定閾值,什么時候使用自適應(yīng)閾值呢?
答:當圖像質(zhì)量較好,且目標和背景容易區(qū)分時,可以采用固定閾值
當圖像質(zhì)量差,且有陰影過度,雖然使用大津法和三角形法也可以自己尋找閾值,但整個圖像閾值都是相同,所以最終分割效果較差。
所以,可以用自適應(yīng),或者將整個圖像分割成幾行幾列,對每個部分運用大津法或者三角形法,最后將圖形整合,這樣每一部分的閾值就不相同,分割效果也會更好。
二、固定閾值二值化threshold()
double**threshold**(
?
InputArray src,
OutputArray dst,
double thresh,
double maxval,
int type 閾值類型如下
);
2.1閾值類型
binary:二進制的
type | 作用 |
---|---|
THRESH_BINARY | 灰度值高于閾值的為最大,其余為0 |
THRESH_BINARY_INV | 灰度值高于閾值的為0,其余為最大 |
THRESH_TOZERO | 高于閾值的為0,低于閾值的保留 |
THRESH_TOZERO_INV | 高于閾值的保留,低于閾值的為0 |
THRESH_TRUNC | 高于閾值的為閾值,低于閾值的保留 |
THRESH_OTSU | 大津法自動求閾值 THRESH_OTUS 大津閾值算法配合其它閾值使用,最適用于雙波峰。 |
THRESH_TRIANGLE | 三角形法自動求閾值 根據(jù)直方圖自行計算閾值,最適用于單個波峰,最開始用于醫(yī)學分割細胞等 |
THRESH_OTUS 大津閾值算法配合其它閾值使用,最適用于雙波峰。
THRESH_TRIANGLE 三角形的二值化法根據(jù)直方圖自行計算閾值,最適用于單個波峰,最開始用于醫(yī)學分割細胞等
大津法(Otsu's method)和三角形法(Triangle method)是兩種常用于圖像處理中自動確定閾值的方法。
2.2 大津法原理:
大津法是一種基于直方圖的自適應(yīng)閾值確定方法,其基本原理是尋找一個閾值,使得根據(jù)該閾值將圖像分割成前景(目標)和背景兩部分后,目標與背景之間的類間方差最大。類間方差用于衡量目標和背景之間的差異程度,方差越大表示目標和背景之間的差異越大,分割效果越好。
大津法的步驟如下: 1) 計算圖像的灰度直方圖。 2) 對每個可能的閾值t(0到255),計算目標和背景的像素數(shù)目和像素值的平均值。 3) 根據(jù)當前閾值t,計算類間方差作為衡量指標:類間方差 = 目標像素數(shù)目 * 背景像素數(shù)目 * (目標平均灰度值 - 背景平均灰度值)^2。 4) 找到使得類間方差最大的閾值作為最終閾值。
2.3 三角形法原理:
三角形法是一種基于直方圖的閾值選擇方法,其基本原理是找到直方圖的峰值處對應(yīng)的閾值,通過將直方圖峰值對應(yīng)的斜率定義為三角形的高,并找到使得該三角形面積最大的閾值作為最終閾值。
三角形法的步驟如下: 1) 計算圖像的灰度直方圖。 2) 找到直方圖的峰值處,即直方圖中像素數(shù)目最多的灰度級別。 3) 以峰值處對應(yīng)的灰度級別為基準,向兩側(cè)尋找直方圖中像素數(shù)目小于峰值處像素數(shù)目一半的兩個灰度級別作為邊界。 4) 計算基準灰度級別和兩個邊界之間的直方圖的斜率,斜率定義為三角形的高。在這種情況下,可以將這兩個邊界之間的距離作為三角形的底部。 5) 找到使得三角形面積最大的斜率對應(yīng)的閾值作為最終閾值。另一種做法是將直方圖整體的范圍作為底部,即使用整個直方圖的最小和最大灰度級別之間的距離作為三角形的底部。
三、自適應(yīng)閾值處理
上邊固定閾值的方法適用于比較理想的場景,實際在使用時,由于圖片的光線條件變化,固定的閾值往往不能很好的將目標與背景分離,這個時候就需要用到自適應(yīng)閾值的方法,自適應(yīng)閾值會根據(jù)一小片區(qū)域的值來動態(tài)調(diào)整閾值,使最后的輸出更合理。用到的函數(shù)是adaptiveThreshold()
adaptiveThreshold(
src,
dst,
maxval,
thresh_type, //只能為BINARY或者其INV
type,
Block
Size,
C )
-
thresh_type: 閾值的計算方法,包含以下2種類型:
類型 | 含義 |
---|---|
cv2.ADAPTIVE_THRESH_MEAN_C | 計算均值時每個像素的權(quán)值是相等的 |
cv2.ADAPTIVE_THRESH_GAUSSIAN_C | 計算均值時每個像素的權(quán)值根據(jù)其到中心點的距離通過高斯方程得到 |
-
Block Size: 圖片中分塊的大小
-
C :閾值計算方法中的常數(shù)項
關(guān)于Block Size和C的取值,一般Block Size取3~17比較合適,C也不宜太大,可取3~9,具體的值需要自己測試調(diào)節(jié)。
下圖為對一幅圖片用不同方法進行閾值化時的效果,可以看到,相對于一般的閾值化操作,當圖像中出現(xiàn)較大的明暗差異時,自適應(yīng)閾值是非常有效的
函數(shù)cvAdaptiveThreshold的確可以將灰度圖像二值化,但它的主要功能應(yīng)該是邊緣提取,并且參數(shù)C主要是用來控制邊緣的類型和粗細的.
關(guān)鍵是里面的block_size參數(shù),該參數(shù)是決定局部閾值的block的大小,
1)當block很小時,如block_size=3 or 5 or 7時,“自適應(yīng)”的程度很高,即容易出現(xiàn)block里面的像素值都差不多,這樣便無法二值化,而只能在邊緣等梯度大的地方實現(xiàn)二值化,結(jié)果顯得它是邊緣提取函數(shù)。
2)當把block_size設(shè)為比較大的值時,如block_size=21 or 31 or41時,cvAdaptiveThreshold便是二值化函數(shù)了 3)src與dst 這兩個都要是單通道的圖像。 參數(shù)blockSize: 1.要取奇數(shù),如果取偶數(shù)運行后就會報錯??!原因看源碼,發(fā)現(xiàn)要做一個掩模,所以參數(shù)必須是奇數(shù)。OpenCV也做了一個檢測,在函數(shù)adaptiveThreshold一開始就有CV_Assert( blockSize %2 == 1 && blockSize > 1 )。
2.cvAdaptiveThreshold既可以做邊緣提取,也可以實現(xiàn)二值化,是由你所選擇的鄰域所確定的,如果你所選擇的鄰域非常?。ū热?×3),那么很顯然閾值的“自適應(yīng)程度”就非常高,這在結(jié)果圖像中就表現(xiàn)為邊緣檢測的效果。如果鄰域選擇的比較大(比如31×31),那么閾值的“自適應(yīng)程度”就比較低,這在結(jié)果圖像中就表現(xiàn)為二值化的效果。
3.一般情況下,濾波器寬度應(yīng)該大于被識別物體的寬度。block_size太小,無法代表背景,太大的話會影響到臨近物體。
選定合適的block_size后,我們就可以選定一個更大的閾值param1,更好的抑制噪聲
4.1 THRESH_BINARY和THRESH_BINARY_INV
Mat img = imread("lena.png");
if (img.empty())
{
cout << "讀取失敗!"<<endl;
return -1;
}
//GARY PICTURE
Mat gary;
cvtColor(img, gary, COLOR_BGR2GRAY);
?
//ORINGIN'SBINARY
Mat ori_bin, ori_bin_inv, gary_bin, gary_bin_inv;
threshold(img,ori_bin, 125, 255, THRESH_BINARY);
threshold(img, ori_bin_inv, 125, 255, THRESH_BINARY_INV);
imshow("ori_bin", ori_bin);
imshow("ori_bin_inv", ori_bin_inv);
?
?
threshold(gary, gary_bin, 125, 255, THRESH_BINARY);
threshold(gary, gary_bin_inv, 125, 255, THRESH_BINARY_INV);
imshow("ori_bin", gary_bin);
imshow("ori_bin_inv", gary_bin_inv);
這段代碼將彩圖原圖和灰度化后的圖像分別進行二進制二值化處理;得到下面四個圖像。還有原圖和灰度圖略過:
?
?
可見多通道是將各個通道分離后進行二值化后再組合在一起,所以不是單純的黑白圖片而是一些帶有特點的色彩的圖片,RGB的組合
?
轉(zhuǎn)化為單通道灰度圖后可見左右兩圖片互補
4.2 THRESH_TOZERO和THRESH_TOZERO_INV
Mat img = imread("lena.png");
if (img.empty())
{
cout << "讀取失敗!"<<endl;
return -1;
}
Mat gary;
cvtColor(img, gary, COLOR_BGR2GRAY);
?
//ORINGIN'S
Mat ori_tozero, ori_bin_tozero_inv, gary_tozero, gary_tozero_inv;
threshold(img, ori_tozero, 125, 255, THRESH_TOZERO);
threshold(img, ori_bin_tozero_inv, 125, 255, THRESH_TOZERO_INV);
imshow("THRESH_TOZERO", THRESH_TOZERO);
imshow("THRESH_TOZERO_INV", THRESH_TOZERO_INV);
?
?
threshold(gary, gary_tozero, 125, 255, THRESH_TOZERO);
threshold(gary, gary_tozero_inv, 125, 255, THRESH_TOZERO_INV);
imshow("gary_tozero", gary_tozero);
imshow("gary_tozero_inv", gary_tozero_inv);
?
從左到右分別為原圖、zero、inv;可見zero是將高于閾值的保留,低于閾值的置位0,而inv則將高于閾值的置位0,低于閾值的保留
?
從左到右分別為灰度圖、zero、inv;
4.3 THRESH_TRUNC
將高于閾值的設(shè)為閾值,低于閾值的保留,比較簡單,就放兩張圖片的前后對比。
?
四、使用時機
請問THERSH_BINARY、THRESH_TRUNC、THRESH_TOZERO、THRESH_OTSU、 THRESH_TRIANGLE、ADAPTIVE_THRESH_MEAN_C、ADAPTIVE_THRESH_GAUSSIAN_C都是二值化處理方法,我怎么知道什么時候用哪一個合適?
答:對于選擇合適的二值化處理方法,以下是一些指導(dǎo)原則:
-
THRESH_BINARY:將圖像灰度值大于閾值的像素設(shè)置為最大值(通常為255),小于等于閾值的像素設(shè)置為0。適用于對比度明顯的圖像,目標與背景之間有明顯的灰度差異。
-
THRESH_TRUNC:將圖像灰度值大于閾值的像素設(shè)置為閾值,小于等于閾值的像素保持不變。適用于希望保留目標灰度信息同時進行部分抑制的情況。
-
THRESH_TOZERO:將圖像灰度值大于閾值的像素保持不變,小于等于閾值的像素設(shè)置為0。適用于希望保留亮度較高區(qū)域的細節(jié)信息的情況。
-
THRESH_OTSU:利用大津法(Otsu's method)自動計算閾值,使得目標與背景之間的類間方差最大化。適用于圖像的目標與背景之間有明顯的灰度分離,但具體閾值不確定的情況。
-
THRESH_TRIANGLE:利用三角形法(Triangle method)自動計算閾值,使得基于直方圖的三角形面積最大化。適用于圖像的目標與背景之間有明顯的灰度分離,但具體閾值不確定的情況。
-
ADAPTIVE_THRESH_MEAN_C:基于局部圖像均值的自適應(yīng)閾值方法,根據(jù)每個像素周圍的鄰域計算閾值。適用于圖像中不同區(qū)域具有不同光照條件的情況。
-
ADAPTIVE_THRESH_GAUSSIAN_C:基于局部圖像加權(quán)平均的自適應(yīng)閾值方法,根據(jù)每個像素周圍的鄰域計算閾值。使用高斯權(quán)重來計算局部平均值,適用于圖像中不同區(qū)域具有不同光照條件的情況。
選擇合適的方法取決于圖像的特點和應(yīng)用需求。如果圖像具有明顯的目標與背景分離,可以嘗試使用THRESH_BINARY、THRESH_OTSU或THRESH_TRIANGLE。如果圖像具有不同光照條件或需要保留細節(jié)信息,可以考慮使用自適應(yīng)閾值方法(ADAPTIVE_THRESH_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C)。
ADAPTIVE_THRESH_GAUSSIAN_C和ADAPTIVE_THRESH_MEAN_C在底層實現(xiàn)過程有什么區(qū)別?
答:ADAPTIVE_THRESH_MEAN_C和ADAPTIVE_THRESH_GAUSSIAN_C是兩種不同的自適應(yīng)閾值方法,在底層實現(xiàn)過程中有以下區(qū)別:
ADAPTIVE_THRESH_MEAN_C(基于局部均值的自適應(yīng)閾值方法)的實現(xiàn)過程如下:
-
對于圖像中的每個像素,確定一個局部鄰域(大小由指定的塊大小參數(shù)決定)。
-
計算該鄰域內(nèi)像素的平均值(局部均值)。
-
將該局部均值作為當前像素的閾值。
-
根據(jù)當前像素的灰度值與其對應(yīng)的局部均值進行比較,將像素設(shè)置為白色或黑色。
ADAPTIVE_THRESH_GAUSSIAN_C(基于局部加權(quán)平均的自適應(yīng)閾值方法)的實現(xiàn)過程如下:
-
對于圖像中的每個像素,確定一個局部鄰域(大小由指定的塊大小參數(shù)決定)。
-
計算該鄰域內(nèi)像素的加權(quán)平均值,其中權(quán)重由高斯窗口函數(shù)計算得出(離中心像素距離越近,權(quán)重越大)。
-
將加權(quán)平均值作為當前像素的閾值。
-
根據(jù)當前像素的灰度值與其對應(yīng)的閾值進行比較,將像素設(shè)置為白色或黑色。
區(qū)別:
-
計算閾值的方式不同:ADAPTIVE_THRESH_MEAN_C使用局部均值作為閾值,而ADAPTIVE_THRESH_GAUSSIAN_C使用局部加權(quán)平均值作為閾值。
-
權(quán)重計算方式不同:ADAPTIVE_THRESH_MEAN_C不考慮像素之間的權(quán)重,而ADAPTIVE_THRESH_GAUSSIAN_C使用高斯窗口函數(shù)計算權(quán)重,使得距離中心像素更近的像素具有更高的權(quán)重。
-
效果不同:由于權(quán)重計算的差異,ADAPTIVE_THRESH_GAUSSIAN_C對于圖像的平滑和噪聲抑制效果較好,而ADAPTIVE_THRESH_MEAN_C則更加簡單直接。文章來源:http://www.zghlxwxcb.cn/news/detail-726140.html
選擇使用哪種方法取決于圖像的特點和應(yīng)用需求。如果圖像中有明顯的噪聲或需要更好的平滑效果,可以考慮使用ADAPTIVE_THRESH_GAUSSIAN_C。如果簡單的平均處理足以滿足需求,或者需要更快的計算速度,可以選擇ADAPTIVE_THRESH_MEAN_C。文章來源地址http://www.zghlxwxcb.cn/news/detail-726140.html
到了這里,關(guān)于【C++ OpenCV】閾值二值化、閾值反二值化、截斷、閾值取零、閾值反取零、自適應(yīng)閾值使用方法以及時機的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!