OpenCV阈值分割
什么是閾值?
最簡單的圖像分割的方法。
應用舉例:從一副圖像中利用閾值分割出我們需要的物體部分(當然這里的物體可以是一部分或者整體)。這樣的圖像分割方法是基于圖像中物體與背景之間的灰度差異,而且此分割屬于像素級的分割。
為了從一副圖像中提取出我們需要的部分,應該用圖像中的每一個像素點的灰度值與選取的閾值進行比較,并作出相應的判斷。(注意:閾值的選取依賴于具體的問題。即:物體在不同的圖像中有可能會有不同的灰度值。
一旦找到了需要分割的物體的像素點,我們可以對這些像素點設定一些特定的值來表示。(例如:可以將該物體的像素點的灰度值設定為:‘0’(黑色),其他的像素點的灰度值為:‘255’(白色);當然像素點的灰度值可以任意,但最好設定的兩種顏色對比度較強,方便觀察結果)。
?
閾值化的類型
二進制閾值化 0: THRESH_BINARY ? ? ? ? -當前點值大于閾值時,取Maxval,否則設置為0
-
該閾值化類型如下式所示:
-
解釋:在運用該閾值類型的時候,先要選定一個特定的閾值量,比如:125,這樣,新的閾值產生規則可以解釋為大于125的像素點的灰度值設定為最大值(如8位灰度值最大為255),灰度值小于125的像素點的灰度值設定為0。
反二進制閾值化1: THRESH_BINARY_INV ? ? -當前點值大于閾值時,設置為0,否則設置為Maxval
-
該閾值類型如下式所示:
-
解釋:該閾值化與二進制閾值化相似,先選定一個特定的灰度值作為閾值,不過最后的設定值相反。(在8位灰度圖中,例如大于閾值的設定為0,而小于該閾值的設定為255)。
?
截斷閾值化?2: THRESH_TRUNC ? ? ? ? ?-當前點值大于閾值時,設置為閾值,否則不改變
-
該閾值化類型如下式所示:
-
解釋:同樣首先需要選定一個閾值,圖像中大于該閾值的像素點被設定為該閾值,小于該閾值的保持不變。
-
(例如:閾值選取為125,那小于125的閾值不改變,大于125的灰度值(230)的像素點就設定為該閾值)。
閾值化為0?3: THRESH_TOZERO ? ? ? ? -當前點值大于閾值時,不改變,否則設置為0
-
該閾值類型如下式所示:
-
解釋:先選定一個閾值,然后對圖像做如下處理:像素點的灰度值大于該閾值的不進行任何改變;?像素點的灰度值小于該閾值的,其灰度值全部變為0。
反閾值化為0?4: THRESH_TOZERO_INV ? ? -當前點值大于閾值時,設置為0,否則不改變
-
該閾值類型如下式所示:
-
解釋:原理類似于0閾值,但是在對圖像做處理的時候相反,即:像素點的灰度值小于該閾值的不進行任何改變,而大于該閾值的部分,其灰度值全部變為0。
?
還有其他的常用:CV_THRESH_OTSU?大津閾值和自適應閾值adaptiveThreshold
大津法OTSU(最大類間方差法)
Otsu分割方法求取閾值是求得使類間方差最大的閾值,Otsu方法加權地使用了兩類的灰度均值信息和概率密度信息,考慮了兩類的分布,在實際的應用中取得了很好的效果
在實際運用過程中,大津法表現得最穩定,且無需參數,對于現實圖像保持了最好的均勻性和形狀特性,而且被商業軟件GIMP 和學術軟件Matlab采納為自動閾值法。
大津算法可以從圖像直方圖上有一個更為直觀的理解:大津閾值大致上是直方圖兩個峰值之間低谷的值。
Otsu 方法也不是萬能的。當目標與背景的大小比例懸殊時,類間方差準則函數可能呈現雙峰或多峰,此時效果不好。這時就要考慮其他的辦法了
示例代碼C++:
/************************************************************************/ /* OpenCV閾值分割函數:threshold() 函數原型: double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type) 參數含義: InputArray src -原圖像 OutputArray dst -輸出圖像 double thresh -閾值大小 double maxval -最大值 int type -閾值模式 閾值模式有以下幾種類型 0: THRESH_BINARY -當前點值大于閾值時,取Maxval,否則設置為0 1: THRESH_BINARY_INV -當前點值大于閾值時,設置為0,否則設置為Maxval 2: THRESH_TRUNC -當前點值大于閾值時,設置為閾值,否則不改變 3: THRESH_TOZERO -當前點值大于閾值時,不改變,否則設置為0 4: THRESH_TOZERO_INV -當前點值大于閾值時,設置為0,否則不改變 // CV_THRESH_MASK =7 CV_THRESH_OTSU =8 */ /************************************************************************/#include <opencv2\imgproc\imgproc.hpp> #include <opencv2\highgui\highgui.hpp> #include <iostream>using namespace cv; using namespace std;#define WINDOW_NAME "閾值處理"//定義滑動條初始值 int g_nThresholdValue=100; //閾值初始值 int g_nThresholdType=0; //閾值模式初始值Mat g_srcImage,g_grayImage,g_dstImage;void on_Threshold(int ,void*);//回調函數int main() {g_srcImage=imread("dog.jpg");//讀入圖片if(!g_srcImage.data){cout<<"讀入錯誤"<<endl;return -1;}//轉換為灰度圖cvtColor(g_srcImage,g_grayImage,COLOR_RGB2GRAY);//更多轉換方式參見官方文檔//顯示原圖imshow("原圖",g_srcImage);//大津閾值threshold(g_grayImage,g_dstImage,0,255,CV_THRESH_OTSU); //自適應閾值//adaptiveThreshold(g_grayImage,g_dstImage,255,0,0,7,9);imshow(WINDOW_NAME,g_dstImage); waitKey();//創建滑動條namedWindow(WINDOW_NAME);createTrackbar("模式",WINDOW_NAME,&g_nThresholdType,4,on_Threshold);createTrackbar("閾值",WINDOW_NAME,&g_nThresholdValue,255,on_Threshold);//使用回調函數顯示圖像on_Threshold(0,0);waitKey();return 0; }void on_Threshold(int,void*) {//進行閾值分割threshold(g_grayImage,g_dstImage,g_nThresholdValue,255,g_nThresholdType);//顯示結果imshow(WINDOW_NAME,g_dstImage); }?
效果展示:
大津閾值:
?
其他基本類型:
?
最大熵閾值分割
二維最大熵閾值分割原理
OpenCV - 區域生長算法
?
文獻參考:
1.https://blog.csdn.net/xw20084898/article/details/22101323
2.http://www.cnblogs.com/Tang-tangt/p/9420405.html
?
總結
以上是生活随笔為你收集整理的OpenCV阈值分割的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vtkImageData处理之阈值分割
- 下一篇: DSP实验报告—实验1