《Java图像处理:基于OpenCV与JVM》 ——1.12 使用轮廓进行边缘检测
1.12 使用轮廓进行边缘检测
问题定义
在Canny操作的结果中,希望找到一组可绘制的轮廓,并把它们绘制在矩阵中。
解决方法
OpenCV中有两个函数常与Canny函数一同使用:findContours和drawContours。
findContours读入一个矩阵,并在这个矩阵中查找边缘,或者说定义形状的边界。因为原图像可能包含许多颜色和亮度的噪声,你通常需要一个经过预处理的图片,即一个由Canny处理过的黑白矩阵。
drawContours读入findContours的结果,也就是一组轮廓对象,并允许你用具体的特征来绘制这些轮廓,例如绘制线条的粗细和颜色。
工作原理
如同在解决方法中提到的,OpenCV的findContours函数输入一个预处理过的图片,包含以下参数:
1.预处理过的矩阵
2.用于接收轮廓对象的空队列(MatOfPoint)
3.一个分层矩阵,你目前可以忽略它,并把它设置为空矩阵
4.轮廓追踪模式,例如是否建立轮廓之间的关系或返回所有内容
5.存储轮廓的近似类型,例如是绘制所有的点还是只绘制一些关键点
第一步,我们把预处理图片和追踪轮廓一起放在自定义的find_contours函数中。
该函数返回一组检测到的轮廓,每个轮廓包含一组像素点,用OpenCV的话说,就是一个MatOfPoint对象。
接下来,我们定义一个draw_contours函数,读入源矩阵来找出第一步中得到的每个轮廓的大小,输入还包括我们希望用来绘制边缘的线条粗度。
在OpenCV中绘制轮廓,通常需要一个for循环,并把要绘制的轮廓索引给drawContours函数。
太棒啦,该攻略最核心的部分已经完成,现在你可以运行它了。可以和之前一样使用猫咪的照片来作为基准输入图像。
draw-contours的结果如图1-2所示。
图1-29 猫咪轮廓,粗度=7
接下来换一种粗度来绘制轮廓,例如,当粗度是3时,结果会有些许不同,如图1-30所示,线条更细一些。
图1-30 猫咪轮廓,粗度=3
从现在开始,我们可以使用结果矩阵作为掩膜进行背景复制。
下面的代码取自1-11节。该函数读入一个掩膜,并且用这个掩膜进行复制。
图1-31显示了掩膜复制的结果,其中轮廓绘制时的粗度为3。
图1-31 蓝色背景上的白***咪
值得注意的是,第3章将介绍更酷的使用掩膜和背景的方法,用于生成艺术图片,这一节攻略暂时告一段落。
- 点赞
- 收藏
- 关注作者
评论(0)