使用輪廓檢測,我們可以檢測目標的邊界,并在圖像中定位它們。輪廓檢測有著很多應(yīng)用場景,例如圖像前景提取,圖像分割、檢測和識別等等。
1.什么是圖像的輪廓?
當我們連接圖像中某個目標邊界上的所有點時,就得到了一個輪廓。通常輪廓是指具有相同顏色和強度的邊界像素。
在之前我們有學(xué)過Canny邊緣檢測, 那么邊緣和輪廓的區(qū)別在哪里呢?通常來說,輪廓是一系列相連的點組成的曲線,描繪了物體的基本外形,相對于邊緣,輪廓是連續(xù)的,邊緣并不全部連續(xù)。


2.使用OpenCV進行輪廓檢測
使用OpenCV進行輪廓檢測非常簡單 。步驟如下:
1) 讀取圖像并將其轉(zhuǎn)換為灰度格式
讀取圖像并將圖像轉(zhuǎn)換為灰度格式。將圖像轉(zhuǎn)換為單通道灰度圖像是為了方便做閾值處理,這是輪廓檢測算法的第一步。
2) 應(yīng)用二進制閾值
在尋找輪廓時,首先總是對灰度圖像應(yīng)用二值閾值或 Canny 邊緣檢測。在這里,我們使用二值閾值。
這會將彩色圖像轉(zhuǎn)換為二值圖像,使輪廓檢測算法變得容易。邊緣檢測使圖像中對象的邊界完全變白,所有像素都具有相同的強度。該算法現(xiàn)在可以從這些白色像素中檢測對象的邊界。
此時,可能會出現(xiàn)一個問題。如果我們使用 R(紅色)、G(綠色)或 B(藍色)等單通道而不是灰度(閾值)圖像會怎樣?答案是在這種情況下,輪廓檢測算法將無法正常工作。Canny邊緣檢測算是利用像素強度(亮度)的值來檢測出邊界的。而通常灰度圖比單個 (RGB) 顏色通道圖像更好地提供亮度信息。
3) 找到輪廓
使用findContours()函數(shù)檢測圖像中的輪廓。
4) 在原始 圖像上繪制輪廓。
識別輪廓后,使用該drawContours()函數(shù)將輪廓疊加在原始 RGB 圖像上。
3.OpenCV代碼演示
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main() {
//讀取原始圖片
Mat image = imread("C:/Users/LeLe/Desktop/opencv/images/car.jpeg");
//轉(zhuǎn)換為灰度圖
Mat img_gray;
cvtColor(image, img_gray, COLOR_BGR2GRAY);
imshow("origin", image);
//通過閾值轉(zhuǎn)換為二值圖像
//注意這里對于不同的圖像,可以不斷調(diào)整閾值來得到更好的二值圖像。這里我設(shè)置的閾值是150。
Mat thresh;
threshold(img_gray, thresh, 150, 255, THRESH_BINARY);
//邊緣檢測
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
//將檢測到的邊緣畫在原始圖像上
Mat image_copy = image.clone();
drawContours(image_copy, contours, -1, Scalar(0, 255, 0), 2);
imshow("None approximation", image_copy);
waitKey(0);
}
結(jié)果顯示。左邊和右邊分別為原始圖像和原始圖像疊加輪廓的圖像。
