c# opencv 轮廓检测_OPENCV图像轮廓检测

前面在图像转换的时候学到canny算子,可以检测出图像的轮廓信息,但是,该算子检测到的轮廓信息还需要我们手动的用眼睛去识别,而实际工程应用中,我们需要得到轮廓的具体数学信息,这就涉及到今天的主题,图像轮廓检测.

一.图像轮廓检测

在opencv中,轮廓对应着一系列的点的集合,opencv提供了一个函数,用来获得这些点的集合

API:void finContours(输入图像,输出轮廓点集,输出向量,int 轮廓检索模式,int 轮廓近似方法,Point 轮廓点的可选偏移量)

注:1.输入图像,是单通道八位阈值化图像,也就是对应canny检测之后的图像,如果不是阈值化图像,算法会将图像中不为0的点当成1,0点当成0处理,我们可以通过canny threshold adaptiveThreshold来处理,

2.该函数在检测轮廓的时候会修改源图像的数据,所以最好不要拿源图像直接检测轮廓,最好是用拷贝

3.输出点集的形式为vector>contours,每个向量包含有多个向量,包含的向量一个就是一条轮廓,而包含的向量是由一个个点构成的.

4.输出向量包含了图像轮廓的拓扑信息,比如这个轮廓的前一个轮廓编号,后一个轮廓编号,父轮廓编号以及子轮廓编号,形式为vectorh,h[0]为后一个轮廓编号 h[1]后一个轮廓编号 h[2]父轮廓编号 h[3]内嵌轮廓编号

5.轮廓的检索模式包含有如下几种选择RETR_EXTERNAL只检测最外围的轮廓  RETR_LIST提取所有的轮廓,不建立上下等级关系,只有兄弟等级关系  RETR_CCOMP提取所有轮廓,建立为双层结构 RETR_TREE提取所有轮廓,建立网状结构

6.轮廓的近似方法有以下取值 CHAIN_APPROX_NONE获取轮廓的每一个像素,像素的最大间距不超过1 CHAIN_APPROX_SIMPLE压缩水平垂直对角线的元素,只保留该方向的终点坐标(也就是说一条中垂线a-b,中间的点被忽略了) CHAIN_APPROX_TC89_LI使用TEH_CHAIN逼近算法中的LI算法  CHAIN_APPROX_TC89_KCOS使用TEH_CHAIN逼近算法中的KCOS算法

7.可选偏移量,对ROI区域中获得的轮廓要在整个图像中分析的时候,该参数可以派上用场

二.图像轮廓绘制

该函数可以很方便的绘制出我们找到的轮廓点集和拓扑结构构成的轮廓图.

API:void drawContours(源图像,轮廓点集,int 绘制指示,scalar 轮廓颜色,int 轮廓粗细,int 轮廓线形,inputarray 轮廓的拓扑结构信息,int 轮廓的最大绘制等级,int 可选的轮廓偏移参数)

注:1.如果绘制指示为负值,则绘制所有轮廓,轮廓粗细默认值为1,为负值的化,绘制在轮廓的内部进行,使用filled,填充轮廓,线条类型默认为8,LINE_AA将绘制抗锯齿的线型,轮廓绘制等级,默认值是INT_MAX,指示最多可以绘制几层轮廓,=.

轮廓检测的基本步骤为1.图像转换为灰度图像,2.图像的滤波,降噪,3.图像的canny二值化或者其他二值化方式,4.寻找轮廓findContours

代码例子如下

//边À?缘¦Ì轮?廓¤a查¨¦找¨°//先¨¨进?行D边À?缘¦Ì滤?波¡§ 然¨?后¨®用®?canny算?法¤¡§得Ì?到Ì?二t值¦Ì化¡¥图ª?像?//滤?波¡§算?法¤¡§选?择?均¨´值¦Ì滤?波¡§ 可¨¦调Ì¡Â的Ì?是º?孔¡Á径?尺?寸ä?//canny算?法¤¡§可¨¦调Ì¡Â的Ì?上¦?下?限T和¨ªsobel算?子Á¨®孔¡Á径?3 5 7

Mat srcImage,blurImage,grayBlurImage,cannyImage,contourImage;

vector>g_vContours;

vectorg_vHierarchy;

RNG g_rng(12345);const int g_BlurMax = 100;intg_BlurValue;void onBlurTrackBar(int pos,void*userData);const int g_sobelSizeMax = 2;//sobel孔¡Á径?

intg_sobelValue;const int g_lowThresholdMax = 80;//边À?缘¦Ì检¨¬测a低̨ª阈D值¦Ì

intg_lowThresholdValue;intg_upThresholdValue;void onTrackBarSobelSize(int pos,void*userData);void onTrackBarLowThresholdSize(int pos,void*userData);int main(int argc,char*argv[])

{

srcImage= imread("F:\\opencv\\OpenCVImage\\findContours.jpg");

g_BlurValue= 4;

g_sobelValue= 1;

g_lowThresholdValue= 80;

g_upThresholdValue= 240;

namedWindow("canny Image");

namedWindow("contours Image");

createTrackbar("blur size value", "canny Image", &g_BlurValue, g_BlurMax,onBlurTrackBar,0);

createTrackbar("sobel size", "canny Image", &g_sobelValue, g_sobelSizeMax,onTrackBarSobelSize,0);

createTrackbar("low threshold", "canny Image", &g_lowThresholdValue, g_lowThresholdMax,onTrackBarLowThresholdSize,0);

onBlurTrackBar(g_BlurValue,0);

imshow("src image", srcImage);

moveWindow("src image", 0, 0);

moveWindow("canny Image", srcImage.cols, 0);

moveWindow("contour image", srcImage.cols*2, 0);

waitKey(0);return 0;

}//修T改?了¢?滤?波¡§参?数ºy

void onBlurTrackBar(int pos,void*userData)

{int blurSize = g_BlurValue*2+1;

blur(srcImage, blurImage, Size(blurSize,blurSize));int sobelValue = g_sobelValue*2 +3;if (g_lowThresholdValue == 0) {

g_lowThresholdValue= 1;

}int lowThresholdValue =g_lowThresholdValue;int upThresholdValue = lowThresholdValue*3;

cvtColor(blurImage, grayBlurImage, CV_RGB2GRAY);//计?算?canny

Canny(grayBlurImage, cannyImage, lowThresholdValue, upThresholdValue,sobelValue);

contourImage=Mat::zeros(cannyImage.rows, cannyImage.cols, CV_8UC3);

findContours(cannyImage, g_vContours, g_vHierarchy, RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));for(int i = 0;i

{

Scalar color= Scalar(g_rng.uniform(0, 255),g_rng.uniform(0, 255),g_rng.uniform(0, 255));

drawContours(contourImage, g_vContours, i, color,2,8,g_vHierarchy,0,Point(0,0));

}

imshow("contour image", contourImage);

imshow("canny Image",cannyImage);

}//修T改?了¢?sobel孔¡Á径?参?数ºy

void onTrackBarSobelSize(int pos,void*userData)

{int blurSize = g_BlurValue*2+1;

blur(srcImage, blurImage, Size(blurSize,blurSize));int sobelValue = g_sobelValue*2 +3;if (g_lowThresholdValue == 0) {

g_lowThresholdValue= 1;

}int lowThresholdValue =g_lowThresholdValue;int upThresholdValue = lowThresholdValue*3;

cvtColor(blurImage, grayBlurImage, CV_RGB2GRAY);//计?算?canny

Canny(grayBlurImage, cannyImage, lowThresholdValue, upThresholdValue,sobelValue);

contourImage=Mat::zeros(cannyImage.rows, cannyImage.cols, CV_8UC3);

findContours(cannyImage, g_vContours, g_vHierarchy, RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));for(int i = 0;i

{

Scalar color= Scalar(g_rng.uniform(0, 255),g_rng.uniform(0, 255),g_rng.uniform(0, 255));

drawContours(contourImage, g_vContours, i, color,2,8,g_vHierarchy,0,Point(0,0));

}

imshow("contour image", contourImage);

imshow("canny Image",cannyImage);

}//修T改?了¢?阈D值¦Ì参?数ºy

void onTrackBarLowThresholdSize(int pos,void*userData)

{int blurSize = g_BlurValue*2+1;

blur(srcImage, blurImage, Size(blurSize,blurSize));int sobelValue = g_sobelValue*2 +3;if (g_lowThresholdValue == 0) {

g_lowThresholdValue= 1;

}int lowThresholdValue =g_lowThresholdValue;int upThresholdValue = lowThresholdValue*3;

cvtColor(blurImage, grayBlurImage, CV_RGB2GRAY);//计?算?canny

C

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值