OpenCV中轮廓特征的提取与筛选

1、轮廓发现(或提取)

findContours(
    InputOutputArray binImg, OutputArrayOfArrays contours,
    OutputArray hierachy, int mode, int method, Point offset=Point()
)
参数解释:
第一个参数 binImg:输入8bit图像,0值像素值不变,非0的像素看成1;(变为二值图像)
第二个参数 contours:输出找到的轮廓对象
第三个参数 hierachy: 图像的拓扑结构
第四个参数 mode:轮廓返回的模式(RETR_TREE等)
    CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;
    CV_RETR_LIST   检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系;
    CV_RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;
    CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
第五个参数 method:发现方法(CHAIN_APPROX_SIMPLE等)
    CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内;
    CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留;
    CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法;
第六个参数 offset://轮廓像素的位移(默认没有位移(0, 0)

2、轮廓绘制

drawContours(
    InputOutputArray binImg, OutputArrayOfArrays contours,
    Int contourIdx, const Scalar & color, int  thickness, int lineType ,
    InputArray hierarchy, int maxlevel, Point offset=Point()
)
参数解释:
第一个参数 binImg:输入图像
第二个参数 contours:找到的全部轮廓对象
第三个参数 contourIdx: 轮廓索引号
第四个参数 color:绘制颜色
第五个参数 thickness:绘制线宽
第六个参数 lineType:线的类型(默认8)
第七个参数 hierarchy:拓扑结构图
第八个参数 maxlevel:最大层数(0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓)
第九个参数 offset=Point():轮廓位移

3、代码实践

#include <opencv2/opencv.hpp>
#include<vector>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;


int main()
{
	Mat src_img, gray_img, dst_img;
	int threshold_value = 100;
	int threshold_max = 255;
	RNG rang;

	src_img = imread("D:\\03.jpg");
	if (src_img.empty()){
		return -1;
	}
	imshow("原图", src_img);
  
	cvtColor(src_img, gray_img, CV_BGR2GRAY);

	Mat canny_output;
	Canny(gray_img, canny_output, threshold_value, threshold_max, 3, false);
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(canny_output, contours, hierachy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));

	dst_img = Mat::zeros(src_img.size(), CV_8UC3);
	RNG rng(12345);
	for (auto i = 0; i < contours.size(); ++i)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));   //随机颜色
		drawContours(dst_img, contours, i, color, 1, 8, hierachy, 0, Point(0, 0));
	}
	imshow("轮廓图", dst_img);

	waitKey(0);
	return 0;
}

加入二值化操作和形态学操作后代码如下:

#include <opencv2/opencv.hpp>
#include<vector>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;


int main()
{
	Mat src_img, gray_img, dst_img;
	int threshold_value = 100;
	int threshold_max = 255;
	RNG rang;

	src_img = imread("D:\\03.jpg");
	if (src_img.empty()){
		return -1;
	}
	imshow("原图", src_img);
  
	cvtColor(src_img, gray_img, CV_BGR2GRAY);

#if 1
	  //可酌情加入
	threshold(gray_img, gray_img, 200, 255, THRESH_BINARY|CV_THRESH_TRIANGLE);
	imshow("二值化", gray_img);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	erode(gray_img, gray_img, kernel, Point(-1, -1), 1);

	dilate(gray_img, gray_img, kernel, Point(-1, -1), 1);
	dilate(gray_img, gray_img, kernel, Point(-1, -1), 1);
	imshow("膨胀", gray_img);
#endif	

	Mat canny_output;
	Canny(gray_img, canny_output, threshold_value, threshold_max, 3, false);
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(canny_output, contours, hierachy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));

	dst_img = Mat::zeros(src_img.size(), CV_8UC3);
	RNG rng(12345);
	for (auto i = 0; i < contours.size(); ++i)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));   //随机颜色
		drawContours(dst_img, contours, i, color, 1, 8, hierachy, 0, Point(0, 0));
	}
	imshow("轮廓图", dst_img);

	waitKey(0);
	return 0;
}

4、参考

https://blog.youkuaiyun.com/weixin_41695564/article/details/80085012

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值