opencv 图像阈值分割图像
-
最簡單的圖像分割的方法。
-
應(yīng)用舉例:從一副圖像中利用閾值分割出我們需要的物體部分(當(dāng)然這里的物體可以是一部分或者整體)。這樣的圖像分割方法是基于圖像中物體與背景之間的灰度差異,而且此分割屬于像素級的分割。
-
為了從一副圖像中提取出我們需要的部分,應(yīng)該用圖像中的每一個像素點(diǎn)的灰度值與選取的閾值進(jìn)行比較,并作出相應(yīng)的判斷。(注意:閾值的選取依賴于具體的問題。即:物體在不同的圖像中有可能會有不同的灰度值。
-
一旦找到了需要分割的物體的像素點(diǎn),我們可以對這些像素點(diǎn)設(shè)定一些特定的值來表示。(例如:可以將該物體的像素點(diǎn)的灰度值設(shè)定為:‘0’(黑色),其他的像素點(diǎn)的灰度值為:‘255’(白色);當(dāng)然像素點(diǎn)的灰度值可以任意,但最好設(shè)定的兩種顏色對比度較強(qiáng),方便觀察結(jié)果)。
閾值化的類型:
-
OpenCV中提供了閾值(threshold)函數(shù):?threshold?。
-
這個函數(shù)有5種閾值化類型,在接下來的章節(jié)中將會具體介紹。
-
為了解釋閾值分割的過程,我們來看一個簡單有關(guān)像素灰度的圖片,該圖如下。該圖中的藍(lán)色水平線代表著具體的一個閾值。
閾值類型1:二進(jìn)制閾值化
-
該閾值化類型如下式所示:
-
解釋:在運(yùn)用該閾值類型的時候,先要選定一個特定的閾值量,比如:125,這樣,新的閾值產(chǎn)生規(guī)則可以解釋為大于125的像素點(diǎn)的灰度值設(shè)定為最大值(如8位灰度值最大為255),灰度值小于125的像素點(diǎn)的灰度值設(shè)定為0。
閾值類型2:反二進(jìn)制閾值化
-
該閾值類型如下式所示:
-
解釋:該閾值化與二進(jìn)制閾值化相似,先選定一個特定的灰度值作為閾值,不過最后的設(shè)定值相反。(在8位灰度圖中,例如大于閾值的設(shè)定為0,而小于該閾值的設(shè)定為255)。
閾值類型3:截斷閾值化
-
該閾值化類型如下式所示:
-
解釋:同樣首先需要選定一個閾值,圖像中大于該閾值的像素點(diǎn)被設(shè)定為該閾值,小于該閾值的保持不變。(例如:閾值選取為125,那小于125的閾值不改變,大于125的灰度值(230)的像素點(diǎn)就設(shè)定為該閾值)。
閾值類型4:閾值化為0
-
該閾值類型如下式所示:
-
解釋:先選定一個閾值,然后對圖像做如下處理:1 像素點(diǎn)的灰度值大于該閾值的不進(jìn)行任何改變;2 像素點(diǎn)的灰度值小于該閾值的,其灰度值全部變?yōu)?。
閾值類型5:反閾值化為0
-
該閾值類型如下式所示:
-
解釋:原理類似于0閾值,但是在對圖像做處理的時候相反,即:像素點(diǎn)的灰度值小于該閾值的不進(jìn)行任何改變,而大于該閾值的部分,其灰度值全部變?yōu)?。
代碼示范:
簡單的代碼如下。同樣也可以在網(wǎng)站中?下載?以下代碼。
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdlib.h> #include <stdio.h>using namespace cv;/// 全局變量定義及賦值int threshold_value = 0; int threshold_type = 3;; int const max_value = 255; int const max_type = 4; int const max_BINARY_value = 255;Mat src, src_gray, dst; char* window_name = "Threshold Demo";char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted"; char* trackbar_value = "Value";/// 自定義函數(shù)聲明 void Threshold_Demo( int, void* );/** * @主函數(shù) */ int main( int argc, char** argv ) {/// 讀取一副圖片,不改變圖片本身的顏色類型(該讀取方式為DOS運(yùn)行模式)src = imread( argv[1], 1 );/// 將圖片轉(zhuǎn)換成灰度圖片cvtColor( src, src_gray, CV_RGB2GRAY );/// 創(chuàng)建一個窗口顯示圖片namedWindow( window_name, CV_WINDOW_AUTOSIZE );/// 創(chuàng)建滑動條來控制閾值createTrackbar( trackbar_type,window_name, &threshold_type,max_type, Threshold_Demo );createTrackbar( trackbar_value,window_name, &threshold_value,max_value, Threshold_Demo );/// 初始化自定義的閾值函數(shù)Threshold_Demo( 0, 0 );/// 等待用戶按鍵。如果是ESC健則退出等待過程。while(true){int c;c = waitKey( 20 );if( (char)c == 27 ){ break; }}}/** * @自定義的閾值函數(shù) */ void Threshold_Demo( int, void* ) {/* 0: 二進(jìn)制閾值 1: 反二進(jìn)制閾值 2: 截斷閾值 3: 0閾值 4: 反0閾值 */threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );imshow( window_name, dst ); }解釋:
先看一下整個程序的結(jié)構(gòu):
-
先讀取一副圖片,如果是圖片顏色類型是RGB3色類型,則轉(zhuǎn)換成灰度類型的圖像。轉(zhuǎn)換顏色類型可以運(yùn)用OpenCV中的 cvtColor<> 函數(shù)。
src = imread( argv[1], 1 );/// 顏色類型從RGB 轉(zhuǎn)換成灰度 cvtColor( src, src_gray, CV_RGB2GRAY ); -
然后創(chuàng)建一個窗口來顯示該圖片可以檢驗轉(zhuǎn)換結(jié)果
namedWindow( window_name, CV_WINDOW_AUTOSIZE ); -
接著該程序創(chuàng)建兩個滾動條來等待用戶的輸入:
- 第一個滾動條作用:選擇閾值類型:二進(jìn)制,反二進(jìn)制,截斷,0,反0。
- 第二個滾動條作用:選擇閾值的大小。
-
在這里等到用戶拖動滾動條來輸入閾值類型以及閾值的大小,或者是用戶鍵入ESC健退出程序。
-
無論何時拖動滾動條,用戶自定義的閾值函數(shù)都將會被調(diào)用。
/** * @自定義的閾值函數(shù) */ void Threshold_Demo( int, void* ) {/* 0: 二進(jìn)制閾值 1: 反二進(jìn)制閾值 2: 截斷閾值 3: 0閾值 4: 反0閾值 */threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );imshow( window_name, dst ); }就像你看到的那樣,在這樣的過程中,函數(shù) threshold<> 會接受到5個參數(shù):
- src_gray: 輸入的灰度圖像的地址。
- dst: 輸出圖像的地址。
- threshold_value: 進(jìn)行閾值操作時閾值的大小。
- max_BINARY_value: 設(shè)定的最大灰度值(該參數(shù)運(yùn)用在二進(jìn)制與反二進(jìn)制閾值操作中)。
- threshold_type: 閾值的類型。從上面提到的5種中選擇出的結(jié)果。
結(jié)果:
程序編譯過后,從正確的路徑中讀取一張圖片。例如,該輸入圖片如下所示:
首先,閾值類型選擇為反二進(jìn)制閾值類型。我們希望灰度值大于閾值的變暗,即這一部分像素的灰度值設(shè)定為0。從下圖中可以很清楚的看到這樣的變化。(在原圖中,狗的嘴和眼睛部分比圖像中的其他部分要亮,在結(jié)果圖中可以看到由于反二進(jìn)制閾值分割,這兩部分變的比其他圖像的都要暗。原理具體參見本節(jié)中反二進(jìn)制閾值部分解釋)
現(xiàn)在,閾值的類型選擇為0閾值。在這種情況下,我們希望那些在圖像中最黑的像素點(diǎn)徹底的變成黑色,而其他大于閾值的像素保持原來的面貌。其結(jié)果如下圖所示:
總結(jié)
以上是生活随笔為你收集整理的opencv 图像阈值分割图像的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: opencv 其他形态学变换
- 下一篇: opencv 线性滤波器