圖像二值化
簡介
-
圖像二值化就是將圖像像素的灰度值設置成只有最大值和最小值兩種取值,使整個圖像呈現出 “非黑即白” 的效果,是最簡單的圖像分割的方法
-
應用舉例:從一副圖像中利用閾值分割出我們需要的物體部分(當然這里的物體可以是一部分或者整體)。這樣的圖像分割方法是基於圖像中物體與背景之間的灰度差異,而且此分割屬於像素級的分割
threshold()
簡介
該函數是眾多二值化方法的集成,所有的方法都實現了一個功能,就是給定一個閾值,計算所有像素灰度值與這個閾值的關系,得到最終的比較結果
double cv::threshold(src, dst, thresh, maxval, type)
-
src:輸入圖像,只能是CV_8U和CV_32F兩種數據類型
-
dst:輸出圖像,與輸入圖像具有相同的尺寸、數據類型和通道數
-
thresh:二值化閾值
-
maxval:二值化過程中的最大值
-
type:選擇圖像二值化方法的標志,可選擇的標志及含義如下
標志參數 簡記 作用 THRESH_BINARY 0 灰度值大於閾值的為最大值,其他值為0 THRESH_BINARY_INV 1 灰度值大於閾值的為0,其他值為最大值 THRESH_TURNC 2 灰度值大於閾值的為閾值,其他值不變 THRESH_TOZERO 3 灰度值大於閾值的不變,其他值為0 THRESH_TOZERO_INV 4 灰度值大於閾值的為0,其他值不變 THRESH_OTSU 8 大津法自動尋求全局閾值 THRESH_TRIANGLE 16 三角形法自動尋求全局閾值
注,THRESH_OTSU和THRESH_TRIANGLE是獲取閾值的方法,並不是閾值比較方法的標志,這兩個標志可以與前面5種標志一起使用,例如 THRESH_BINARY | THRESH_OTSU
。這兩個標志分別利用大津法(OTUS)和三角形法(TRIANGLE)結合圖像灰度值分布特性獲取二值化的閾值,並將閾值以函數返回值的形式給出。因此,如果該函數最后一個參數設置了這兩個標志中的任何一個,那么該函數第三個參數thresh將由系統自動給出,但是在調用函數時仍然不能默認,只是程序不會使用這個數值。另外,這兩個標志目前只支持輸入CV_8UC1類型的圖像
實現
示例代碼:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat_<Vec3b> img = imread("/home/kslas/OpenCV/lena.tif");
imshow("Original", img);
Mat_<uchar> gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
// 彩色圖像二值化
Mat_<Vec3b> img_B, img_B_V;
threshold(img, img_B, 125, 255, THRESH_BINARY);
threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV);
imshow("img_B", img_B);
imshow("imgB_V", img_B_V);
// 灰度圖BINARY二值化
Mat_<uchar> gray_B, gray_B_V;
threshold(gray, gray_B, 125, 255, THRESH_BINARY);
threshold(gray, gray_B_V, 125, 255, THRESH_BINARY_INV);
imshow("gray_B", gray_B);
imshow("gray_B_V", gray_B_V);
// 灰度值TOZERO變換
Mat_<uchar> gray_T, gray_T_V;
threshold(gray, gray_T, 125, 255, THRESH_TOZERO);
threshold(gray, gray_T_V, 125, 255, THRESH_TOZERO_INV);
imshow("gray_T", gray_T);
imshow("gray_T_V", gray_T_V);
// 灰度值TRUNC變換
Mat_<uchar> gray_TRUNC;
threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC);
imshow("gray_TRUNC", gray_TRUNC);
// 灰度圖像大津法和三角形法二值化
Mat_<uchar> img_Thr = imread("/home/kslas/OpenCV/dark.png", 0);
Mat_<uchar> img_Thr_O, img_Thr_T;
threshold(img_Thr, img_Thr_O, 100, 255, THRESH_BINARY | THRESH_OTSU);
threshold(img_Thr, img_Thr_T, 125, 255, THRESH_BINARY | THRESH_TRIANGLE);
imshow("img_Thr", img_Thr);
imshow("img_Thr_O", img_Thr_O);
imshow("img_Thr_T", img_Thr_T);
waitKey(0);
destroyAllWindows();
return 0;
}
運行結果:
adaptiveThreshold()
簡介
threshold()
函數全局只使用一個閾值,在實際情況中,由於光照不均勻以及陰影的存在,全局只有一個閾值會使得在陰影處的白色區域也會被函數二值化成黑色,因此adaptiveThreshold()
函數提供了兩種局部自適應閾值的二值化方法
void cv::adaptiveThreshold(src, dst, maxValue, adaptiveMethod, thresholdType, blockSize, C)
- src:輸入圖像,只能是CV_8UC1類型
- dst:輸出圖像
- maxValue:二值化的最大值
- adaptiveMethod:自適應確定閾值的方法,分為均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C兩種
- thresholdType:選擇圖像二值化方法的標志,只能是THRESH_BINARY和THRESH_BINARY_INV
- blockSize:自適應確定閾值的像素鄰域大小,一般為3、5、7的奇數
- C:從平均值或加權平均值中減去的常數,可以為正,也可以為負
實現
示例代碼:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat_<uchar> img_Thr = imread("/home/kslas/OpenCV/dark.png", 0);
// 灰度圖像自適應二值化
Mat_<uchar> adaptive_mean, adaptive_gauss;
adaptiveThreshold(img_Thr, adaptive_mean, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 55, 0);
adaptiveThreshold(img_Thr, adaptive_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0);
imshow("img_Thr", img_Thr);
imshow("adaptive_mean", adaptive_mean);
imshow("adaptive_gauss", adaptive_gauss);
waitKey(0);
destroyAllWindows();
return 0;
}
運行結果: