【OpenCV:從零到一】19:輪廓發現

前言
這是我《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.層次體系

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章