OpenCV C++教程目錄
1.在Windows Visual Studio中安裝OpenCV C++版本
2.圖像的基本操作
3.顏色空間轉(zhuǎn)換
4.閾值分割
5.圖像變換(縮放、裁剪、仿射變換)
6.圖像濾波
7.Canny邊緣檢測
8.輪廓檢測
9.透視變換(perspective transform)
10.光流
什么是閾值分割?
閾值法的基本思想是基于圖像的顏色特征來標(biāo)定一個(gè)或多個(gè)閾值,并將圖像中每個(gè)像素的值與閾值相比較,最后將像素根據(jù)比較結(jié)果分到合適的類別中。因此,該類方法最為關(guān)鍵的一步就是按照某個(gè)準(zhǔn)則函數(shù)來求解最佳閾值。
以下面的圖片為例,我們可以看到綠色背景下有四張白底黑字的方格圖,今天的目標(biāo)是用OpenCV閾值分割分別提取出綠色背景和方格圖。

sample.jpg
首先根據(jù)定義,我們要基于圖像特征標(biāo)定出一個(gè)用于分割圖像的閾值。我們可以看到示例圖片是由綠色背景和四個(gè)方格圖組成的。其中綠色背景是由大量相似的像素組成的,因此非常適合作為閾值的標(biāo)定。通過OpenCV的Image watch 插件,我們在圖片中選取一個(gè)綠色像素,可以看到該像素的值為[16, 150, 60] 分別對應(yīng)B, G, R三個(gè)通道的值。
pixel_green.PNG
注意圖中的綠色像素有深有淺,并非完全相同,因此在進(jìn)行提取的時(shí)候,我們可以設(shè)定一個(gè)閾值,認(rèn)為在此閾值范圍內(nèi)的像素都是綠色背景。這里我們設(shè)置的閾值是50。利用設(shè)定好的閾值,使用inRange()函數(shù)創(chuàng)建一個(gè)符合閾值范圍的mask。再用這個(gè)mask和原圖像進(jìn)行bitwise_and()操作,就可以得到我們想要的綠色背景。
Vec3b bgrPixel(16, 150, 60); //標(biāo)定綠色像素值
int threshHold = 50; //閾值設(shè)置為50
Mat3b bgr(bgrPixel);
Mat Image, mask, maskImage1, maskImage2;
Image = imread("C:/Users/LeLe/Desktop/opencv/color_segmentation/sample.jpg");
Scalar minBGR = Scalar(bgrPixel.val[0] - threshHold, bgrPixel.val[1] - threshHold, bgrPixel.val[2] - threshHold);
Scalar maxBGR = Scalar(bgrPixel.val[0] + threshHold, bgrPixel.val[1] + threshHold, bgrPixel.val[2] + threshHold);
inRange(Image, minBGR, maxBGR, mask); //基于設(shè)定的閾值創(chuàng)建一個(gè)mask
bitwise_and(Image, Image, maskImage1, mask); //將mask與原圖像進(jìn)行and操作,得到綠色背景
imshow("Input image", Image);
imshow("Mask image1", maskImage1);
結(jié)果如下圖所示,我們成功提取出了綠色背景。非背景區(qū)域的像素在經(jīng)過bitwise_and()操作后的值都變成了0,所以顯示為黑色。
background.PNG
我們再將上面的mask進(jìn)行取反操作,這樣就得到了一個(gè)非綠色背景區(qū)域的mask。同樣的再和原圖像進(jìn)行bitwise_and()操作,就提取出了方格圖。
bitwise_not(mask, mask2); //將mask取反,得到一個(gè)非綠色背景的mask
bitwise_and(Image, Image, maskImage2, mask2); //將mask與原圖像進(jìn)行and操作,得到方格圖
imshow("Mask image2", maskImage2);
square.PNG
這一節(jié)中我們使用到了下面幾個(gè)OpenCV函數(shù),它們都是閾值分割常用的函數(shù):
inRange()
bitwise_and()
bitwise_not()