前言
這是我《OpenCV:從零到一》專欄的第十九篇博客,想看跟多請戳這。
本文概要
findContours發現輪廓
drawContours繪製輪廓
案例代碼
大概內容: 輪廓發現 。
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
Mat src, dst;
const char* output_win = "findcontours-demo";
int threshold_value = 100;
int threshold_max = 255;
RNG rng;
void Demo_Contours(int, void*);
int main(int argc, char** argv) {
src = imread("D:/86186/Documents/opencv/lena.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow("input-image", WINDOW_AUTOSIZE);
namedWindow(output_win, WINDOW_AUTOSIZE);
imshow("input-image", src);
cvtColor(src, src, COLOR_BGR2GRAY);
const char* trackbar_title = "Threshold Value:";
createTrackbar(trackbar_title, output_win, &threshold_value, threshold_max, Demo_Contours);
Demo_Contours(0, 0);
waitKey(0);
return 0;
}
void Demo_Contours(int, void*) {
Mat canny_output;
vector<vector<Point>> contours;
vector<Vec4i> hierachy;
Canny(src, canny_output, threshold_value, threshold_value * 2, 3, false);
findContours(canny_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
/*
InputOutputArray binImg, // 輸入圖像,非0的像素被看成1,0的像素值保持不變,8-bit
OutputArrayOfArrays contours,// 全部發現的輪廓對象
OutputArray, hierachy// 圖該的拓撲結構,可選,該輪廓發現算法正是基於圖像拓撲結構實現。
int mode, // 輪廓返回的模式 RetrievalModes
int method,// 發現方法 ContourApproximationModes
Point offset=Point()// 輪廓像素的位移,默認(0, 0)沒有位移
mode(RetrievalModes)
RETR_EXTERNAL:表示只檢測最外層輪廓,對所有輪廓設置hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有輪廓,並放置在list中,檢測的輪廓不建立等級關係
RETR_CCOMP:提取所有輪廓,並將輪廓組織成雙層結構(two-level hierarchy),頂層爲連通域的外圍邊界,次層位內層邊界
RETR_TREE:提取所有輪廓並重新建立網狀輪廓結構
RETR_FLOODFILL:官網沒有介紹,應該是洪水填充法
method(ContourApproximationModes)
CHAIN_APPROX_NONE:獲取每個輪廓的每個像素,相鄰的兩個點的像素位置差不超過1
CHAIN_APPROX_SIMPLE:壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點座標,如果一個矩形輪廓只需4個點來保存輪廓信息
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS使用Teh-Chinl鏈逼近算法中的一種
offset:輪廓點可選偏移量,有默認值Point()
*/
dst = Mat::zeros(src.size(), CV_8UC3);
RNG rng(12345);
for (size_t i = 0; i < contours.size(); i++) {
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(dst, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
/* findContours之後對發現的輪廓數據進行繪製顯示
InputOutputArray binImg, // 輸出圖像
OutputArrayOfArrays contours,// 全部發現的輪廓對象
Int contourIdx// 輪廓索引號
const Scalar & color,// 繪製時候顏色
int thickness,// 繪製線寬
int lineType ,// 線的類型LINE_8
InputArray hierarchy,//拓撲結構圖
int maxlevel,// 最大層數, 0只繪製當前的,1表示繪製繪製當前及其內嵌的輪廓
Point offset=Point()// 輪廓位移,可選
*/
}
imshow(output_win, dst);
}
運行效果:
解析及注意事項
步驟:
輸入圖像轉爲灰度圖像cvtColor
使用Canny進行邊緣提取,得到二值圖像
使用findContours尋找輪廓
使用drawContours繪製輪廓
翻譯筆記
approximation n.近似值;粗略估算;類似事物
contours n.輪廓;等高線;輪廓線;
retrieves v.取回;(獵狗將獵獲物)找回;拉回(鉤魚線);拯救
hierarchy n.層次體系