0 引
圖像閾值,即圖像的分割基準,基於此可完成圖像的二值化。圖像二值化可用於OCR成圖像的分割(也是最爲簡單的一種)。這種分割是基於圖像像素值級別的差異,且一般的對象是灰度圖像。
1 圖像二值化
如上所述,圖像閾值的進一步處理就是二值化,二值化包含但不限於“大於閾值爲255,小於閾值爲0”的處理模式。具體如下所示。其實個人理解這些方法只是提供了一種在處理圖像時的思路,並不一定要死記住方法的名字。
爲了更好解釋,假設待處理圖像的直方圖如下。
1.1二進制閾值化
1.2反二進制閾值化
1.3截段閾值化
1.4閾值化0
1.5 反閾值化0
2 OpenCV API
double cvThreshold( const void* srcarr, void*dstarr, double thresh, double maxval, int type );
srcarr源數組,dstarr爲目標數組,thresh爲閾值,maxval爲欲設最大值,type爲閾值處理的類型,有如下幾種:
CV_THRESH_BINARY,表示dsti=(srci>T)?M:0。
CV_THRESH_BINARY_INV,表示dsti=(srci>T)?0:M。
CV_THRESH_TRUNC,表示dsti=(srci>T)?M:srci。
CV_THRESH_TOZERO_INV,表示dsti=(srci>T)?0:srci。
CV_THRESH_TOZERO,表示dsti=(srci>T)?srci:0。
另外,type值還有兩個選擇,可以指定thresh值,此時傳入參數thresh不會起作用。
CV_THRESH_OTSU 使用大津法選擇最優的thresh;
CV_THRESH_TRIANGLE 使用三角法確定thresh;
3 閾值的選擇
上文中介紹API的同時,也介紹了兩種算法確定的thresh:大津法和三角法。
3.1 大津法
大津法又稱爲最大類間方差法。優點計算簡單且不受亮度和對比度的影響。算法的基本思想是找到的閾值滿足low(即低於選擇的閾值)部分與high(即高於閾值部分)的類方差是最大的。
類方差是一個新概念,在正式解釋之前先補充另外一個在算法中使用的概念即前景與後景,前景與後景是根據閾值區分的,即上述的low部分與high部分,至於哪個是前景哪個是後景,需要根據圖像的特徵確定(例如黑背景白字的圖片,那麼前景就是指high部分的白字)。
假設圖像背景是黑色時,且分辨率爲M*N,閾值爲T,記小於T的像素個數爲N0且其平均灰度爲μ0,大於的個數記爲N1且其平均灰度爲μ1,則類方差g的計算公式如下。
ω0=N0/ M×N (1)
ω1=N1/ M×N (2)
N0+N1=M×N (3)
ω0+ω1=1 (4)
μ=ω0*μ0+ω1*μ1 (5)
g=ω0(μ0-μ)^2+ω1(μ1-μ)^2 (6)
將式(5)代入式(6),得到等價公式:
g=ω0ω1(μ0-μ1)^2 (7) 這就是類間方差
而OTSU算法則是找到使類間方差最大的像素值,作爲閾值。代碼演示如下。
int GetOTUSThresh(cv::Matimg) { assert(img.channels() == 1); int gray_cnt[256] = { 0 }; // stastics for (inti = 0; i < img.rows; i++) { for (intj = 0; j < img.cols; j++) { gray_cnt[img.at<unsignedchar>(i, j)]++; } } // otus double max_delta = 0.0; double delta; int thresh; double weight_l, weight_h; double u_l, u_h, u; int cnt_l, cnt_h; for (inti = 0; i < 256; i++) { cnt_l = cnt_h = 0; u_l = u_h = 0.0; for (intj = 0; j < 256; j++) { if (j <i) { cnt_l += gray_cnt[j]; u_l += j * gray_cnt[j]; } else { cnt_h += gray_cnt[j]; u_h += j*gray_cnt[j]; } } u_l = u_l / cnt_l; u_h = u_h / cnt_h; weight_l = (double)cnt_l / (img.rows*img.cols); weight_h = 1 - weight_l; delta = weight_h*weight_l*(u_h -u_l)*(u_h - u_l); if (delta >max_delta) { max_delta =delta; thresh = i; } } return thresh; } |
3.2 三角法
4 自適應圖像閾值
所謂自適應,即將圖像分爲若干個大小相同的block,每個block的閾值會根據周圍局部像素值動態改變待比較的閾值。這樣做的好處是亮處較亮的地方二值化閾值通常較高,而亮度較低的則更低,對噪聲不會那麼敏感。具體的分爲兩種方法,局部鄰域塊的均值和局部鄰域塊的高斯加權和。事實上對於成像效果不好的圖,往往自適應閾值法更加適用。
OPENCV中的API
void adaptiveThreshold(InputArray src,OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double param)
參數 adaptiveMethod:採用的算法兩個取值ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C分別對應局部鄰域塊的均值和局部鄰域塊的高斯加權和。
參數param:引入的微調參數,最終的閾值等於通過adpativeMethod得到的值與param的差值,也可以負數。
5 參考
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/threshold/threshold.html