OpenCV3入門(五)圖像的閾值

1、圖像閾值與二值化

閾值是一種簡單的圖像分割方法,一幅圖像包括目標物體(前景)、背景還有噪聲,要想從數字圖像中直接提取出目標物體,能夠設定一個像素值即閾值,而後用圖像的每個像素點和閾值作比較,給出斷定結果。html

二值化是特殊的閾值分割方法,把圖像分爲兩部分,以閾值T爲分割線,大於T的像素羣和小於T的像素羣,這樣圖像就變爲黑白二色圖像。經過設定一個標準若是大於這個標準就設爲白,若是小於這個標準就設爲黑,而這個標準就是閾值。算法

2、OpenCV閾值threshold

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);函數

(1)第一個參數,InputArray 類型的 src,源圖像。單通道,8 或 32位浮點數類型的深度。學習

(2)第二個參數,OutputArray 類型的 dst,輸出圖像。spa

(3)第三個參數,double 類型的 thresh,選取的閾值。.net

(4)第四個參數,double 類型的 maxval。3d

(5)第五個參數,int 類型的 type。閾值類型。以下所示:code

type類型以下:orm

enum  cv::ThresholdTypes { 
  cv::THRESH_BINARY = 0, 
  cv::THRESH_BINARY_INV = 1, 
  cv::THRESH_TRUNC = 2, 
  cv::THRESH_TOZERO = 3, 
  cv::THRESH_TOZERO_INV = 4, 
  cv::THRESH_MASK = 7, 
  cv::THRESH_OTSU = 8, 
  cv::THRESH_TRIANGLE = 16 
}

不一樣的閾值方法生成關係以下圖。htm

Mat img = Mat::zeros(6, 6, CV_8UC1);
randu(img, 0, 255);

int th = 100;
Mat threshold1, threshold2, threshold3, threshold4, threshold5, threshold6, threshold7, threshold8;
threshold(img, threshold1, th, 200, THRESH_BINARY);
threshold(img, threshold2, th, 200, THRESH_BINARY_INV);
threshold(img, threshold3, th, 200, THRESH_TRUNC);

cout << "raw=\r\n"<<img << "\r\n" << endl;
cout << "THRESH_BINARY=\r\n" << threshold1 << "\r\n" << endl;
cout << "THRESH_BINARY_INV=\r\n" << threshold2 << "\r\n" << endl;
cout << "THRESH_TRUNC=\r\n" << threshold3 << "\r\n" << endl;

上面代碼中randu(img, 0, 255)做用是產出隨機數填充img矩陣。輸出結果以下。

raw=
[ 91,   2,  79, 179,  52, 205;
 236,   8, 181, 239,  26, 248;
 207, 218,  45, 183, 158, 101;
 102,  18, 118,  68, 210, 139;
 198, 207, 211, 181, 162, 197;
 191, 196,  40,   7, 243, 230]

THRESH_BINARY=
[  0,   0,   0, 200,   0, 200;
 200,   0, 200, 200,   0, 200;
 200, 200,   0, 200, 200, 200;
 200,   0, 200,   0, 200, 200;
 200, 200, 200, 200, 200, 200;
 200, 200,   0,   0, 200, 200]

THRESH_BINARY_INV=
[200, 200, 200,   0, 200,   0;
   0, 200,   0,   0, 200,   0;
   0,   0, 200,   0,   0,   0;
   0, 200,   0, 200,   0,   0;
   0,   0,   0,   0,   0,   0;
   0,   0, 200, 200,   0,   0]

THRESH_TRUNC=
[ 91,   2,  79, 100,  52, 100;
 100,   8, 100, 100,  26, 100;
 100, 100,  45, 100, 100, 100;
 100,  18, 100,  68, 100, 100;
 100, 100, 100, 100, 100, 100;
 100, 100,  40,   7, 100, 100]

THRESH_BINARY,thresh=100,maxval=200,大於閾值限定爲200,小於閾值清零。

THRESH_BINARY_INV的做用和THRESH_BINARY 相反,小於閾值置200,大於閾值清。

THRESH_TRUNC的做用是對大於閾值的數據進行截斷,其他值保留原值不變。

圖像閾值例子以下。

Mat img = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic6.bmp", IMREAD_GRAYSCALE);
int th = 100;
Mat threshold1, threshold2, threshold3, threshold4, threshold5, threshold6, threshold7, threshold8;
threshold(img, threshold1, th, 200, THRESH_BINARY);
threshold(img, threshold2, th, 200, THRESH_BINARY_INV);
threshold(img, threshold3, th, 200, THRESH_TRUNC);

imshow("raw pic",img);
imshow("THRESH_BINARY", threshold1);
imshow("THRESH_BINARY_INV", threshold2);
imshow("THRESH_TRUNC", threshold3);

 

3、自動閾值—大津法OTSU

最大類間方差是由日本學者大津(Nobuyuki Otsu)於1979年提出,是一種自適應的閾值肯定方法。算法假設圖像像素可以根據閾值,被分紅背景[background]和目標[objects]兩部分。而後,計算該最佳閾值來區分這兩類像素,使得兩類像素區分度最大。

算法原理爲:

設圖像Img長寬尺寸爲M*N, T爲二值化的閾值;

N0爲灰度小於T的像素的個數,N0的平均灰度爲μ0。

N1 爲灰度大於T的像素的個數,N1的平均灰度爲μ1。

ω0=N0/ M×N                   (1)   //落在N0的機率

ω1=N1/ M×N                   (2)  //落在N1的機率

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)     

OpenCV自帶了OSTU算法。

Mat img = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp", IMREAD_GRAYSCALE);
int th = 100;
Mat threshold1, threshold2, threshold3;
threshold(img, threshold1, th, 255, THRESH_BINARY);
threshold(img, threshold2, th, 255, THRESH_TRUNC);
threshold(img, threshold3, th, 255, THRESH_OTSU); // 閾值隨意設置便可

imshow("raw pic",img);
imshow("THRESH_BINARY", threshold1);
imshow("THRESH_TRUNC",  threshold2);
imshow("THRESH_OTSU",   threshold3);

使用大津法時閾值能夠不設置或隨意設置,函數會自動計算最合適的閾值,輸出圖像以下。

大津法相比其餘二值化方法,能很好的篩選出前景圖和背景圖,讓圖像分類後黑白區分度最大。

四、參考文獻

一、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著

二、Miscellaneous Image Transformations

https://docs.opencv.org/3.1.0/d7/d1b/group__imgproc__misc.html#gae8a4a146d1ca78c626a53577199e9c57

三、OpenCV threshold函數詳解

https://blog.csdn.net/weixin_42296411/article/details/80901080

四、詳細及易讀懂的 大津法(OTSU)原理 和 算法實現

https://blog.csdn.net/u012198575/article/details/81128799

 

尊重原創技術文章,轉載請註明。

http://www.javashuo.com/article/p-whegnigp-mb.html

相關文章
相關標籤/搜索