在圖像閾值化操作中,更關(guān)注的是從二值化圖像中,,分離目標區(qū)域和背景區(qū)域,,但是僅僅通過設(shè)定固定閾值很難達到理想的分割效果,。而自適應(yīng)閾值,則是根據(jù)像素的鄰域塊的像素值分布來確定該像素位置上的二值化閾值,。這樣做的好處: 1. 每個像素位置處的二值化閾值不是固定不變的,,而是由其周圍鄰域像素的分布來決定的。 2. 亮度較高的圖像區(qū)域的二值化閾值通常會較高,,而亮度低的圖像區(qū)域的二值化閾值則會相適應(yīng)的變小。 3. 不同亮度,、對比度,、紋理的局部圖像區(qū)域?qū)碛邢鄬?yīng)的局部二值化閾值。 函數(shù)原型 1. void adaptiveThreshold(InputArray src, OutputArray dst, 2. double maxValue, int adaptiveMethod, 3. int thresholdType, int bolckSize, double C) 參數(shù)說明 參數(shù)1:InputArray類型的src,,輸入圖像,,填單通道,單8位浮點類型Mat即可,。 對參數(shù)4與參數(shù)7內(nèi)容的解釋:
自適應(yīng)閾值化計算大概過程是為每一個象素點單獨計算的閾值,,即每個像素點的閾值都是不同的,,就是將該像素點周圍B*B區(qū)域內(nèi)的像素加權(quán)平均,然后減去一個常數(shù)C,,從而得到該點的閾值,。B由參數(shù)6指定,,常數(shù)C由參數(shù)7指定。
ADAPTIVE_THRESH_MEAN_C,,為局部鄰域塊的平均值,,該算法是先求出塊中的均值,再減去常數(shù)C,。 ADAPTIVE_THRESH_GAUSSIAN_C,,為局部鄰域塊的高斯加權(quán)和。該算法是在區(qū)域中(x, y)周圍的像素根據(jù)高斯函數(shù)按照他們離中心點的距離進行加權(quán)計算,,再減去常數(shù)C,。 舉個例子:如果使用平均值方法,平均值mean為190,,差值delta(即常數(shù)C)為30,。那么灰度小于160的像素為0,大于等于160的像素為255,。如下圖: 如果是反向二值化,,如下圖: delta(常數(shù)C)選擇負值也是可以的。 代碼演示 /* 自適應(yīng)閾值:adaptiveThreshold()函數(shù) */ #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; int main() { //------------【1】讀取源圖像并檢查圖像是否讀取成功------------ Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\build.jpg"); if (!srcImage.data) { cout << "讀取圖片錯誤,,請重新輸入正確路徑,!\n"; system("pause"); return -1; } imshow("【源圖像】", srcImage); //------------【2】灰度轉(zhuǎn)換------------ Mat srcGray; cvtColor(srcImage, srcGray, CV_RGB2GRAY); imshow("【灰度圖】", srcGray); //------------【3】初始化相關(guān)變量--------------- Mat dstImage; //初始化自適應(yīng)閾值參數(shù) const int maxVal = 255; int blockSize = 3; //取值3、5,、7....等 int constValue = 10; int adaptiveMethod = 0; int thresholdType = 1; /* 自適應(yīng)閾值算法 0:ADAPTIVE_THRESH_MEAN_C 1:ADAPTIVE_THRESH_GAUSSIAN_C -------------------------------------- 閾值類型 0:THRESH_BINARY 1:THRESH_BINARY_INV */ //---------------【4】圖像自適應(yīng)閾值操作------------------------- adaptiveThreshold(srcGray, dstImage, maxVal, adaptiveMethod, thresholdType, blockSize, constValue); imshow("【自適應(yīng)閾值】", dstImage); waitKey(0); return 0; } 顯示結(jié)果
可以發(fā)現(xiàn)自適應(yīng)閾值能很好的觀測到邊緣信息,。閾值的選取是算法自動完成的,很方便,。 濾波處理 另外,,做不做濾波處理等對圖像分割影響也比較大。 1. adaptiveThreshold分割 Mat img=imread("D:/ImageTest/sudoku.png",CV_LOAD_IMAGE_COLOR); Mat dst1; Mat dst2; Mat dst3; cv::cvtColor(img,img,COLOR_RGB2GRAY);//進行,,灰度處理 medianBlur(img,img,5);//中值濾波 threshold(img,dst1, 127, 255, THRESH_BINARY);//閾值分割 adaptiveThreshold(img,dst2,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,11,2);//自動閾值分割,鄰域均值 adaptiveThreshold(img,dst3,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,11,2);//自動閾值分割,,高斯鄰域 //ADAPTIVE_THRESH_MEAN_C : threshold value is the mean of neighbourhood area //ADAPTIVE_THRESH_GAUSSIAN_C : threshold value is the weighted sum of neighbourhood values where weights are a gaussian window. imshow("dst1", dst1); imshow("dst2", dst2); imshow("dst3", dst3); imshow("img", img); waitKey(0); 效果對比,很明顯加入鄰域權(quán)重后處理更理想: 2. 加入濾波處理的最大類間方差分割 Mat img=imread("D:/ImageTest/pic2.png",CV_LOAD_IMAGE_COLOR); Mat dst1; Mat dst2; Mat dst3; cv::cvtColor(img,img,COLOR_RGB2GRAY);//進行,,灰度處理 // medianBlur(img,img,5); threshold(img,dst1, 127, 255, THRESH_BINARY); threshold(img,dst2,0, 255, THRESH_OTSU);//最大類間方差法分割 Otsu algorithm to choose the optimal threshold value Mat img2=img.clone(); GaussianBlur(img2,img2,Size(5,5),0);//高斯濾波去除小噪點 threshold(img2,dst3, 0, 255, THRESH_OTSU); imshow("BINARY dst1", dst1); imshow("OTSU dst2", dst2); imshow("GaussianBlur OTSU dst3", dst3); imshow("original img", img); waitKey(0); 效果如下,,顯然不濾波和濾波差別明顯:
參考文章:https://blog.csdn.net/sinat_36264666/article/details/77586964 https://blog.csdn.net/abcvincent/article/details/78822191 |
|