美文网首页
从图像边缘到物体轮廓

从图像边缘到物体轮廓

作者: Byte猫 | 来源:发表于2019-05-25 11:45 被阅读0次

上一篇已经讲解了很多算子用来检测边缘,其中用得最多的是canny边缘检测。只有边缘还不够,有很多时候我们还需要获得图片上的某物体轮廓。
轮廓可以简单认为成连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。

发现轮廓

Opencv提供了一个函数findContours()用于发现轮廓,它有三个参数,第一个是输入图像,第二个是轮廓检索模式,第三个是轮廓近似方法。

轮廓的近似方法
轮廓是一个形状具有相同灰度值的边界,它会存储形状边界上所有的(x,y)坐标。实际上我们不需要所有的点,当需要直线时,找到两个端点即可。CHAIN_APPROX_SIMPLE可以实现。它会将轮廓上的冗余点去掉,压缩轮廓,从而节省内存开支。
下面用矩阵来演示,在轮廓列表中的每一个坐标上画一个蓝色圆圈。第一个显示使用CHAIN_APPROX_NONE的效果,一共734个点,第二个图是使用CHAIN_APPROX_SIMPLE的结果,只有4个点。

# coding = utf-8
import numpy as np
import cv2 as cv

img = cv.imread('1024.jpg')
imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)
image, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

findContours()的返回值有三个,第一个是图像,第二个是轮廓,第三个是(轮廓的)层析结构。最常用的是第二个返回值。
轮廓(第二个返回值)是一个Python列表,其中储存这图像中所有轮廓。每一个轮廓都是一个Numpy数组,包含对象边界点(x,y)的坐标。

绘制轮廓

Opencv提供了一个函数drawContours()用于绘制轮廓。

image, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]

img2 = np.copy(img)
cv.drawContours(img2, [cnt], 0, (0, 0, 255), 2)

轮廓特征

1、轮廓面积

area = cv.contourArea(cnt)

轮廓特征计算的结果并不等同于像素点的个数,而是根据几何方法算出来的,所以有小数。

2、轮廓周长

perimeter = cv.arcLength(cnt, True)

参数2表示轮廓是否封闭

3、外接矩形

形状的外接矩形有两种,如下图,绿色的叫外接矩形,表示不考虑旋转并且能包含整个轮廓的矩形。蓝色的叫最小外接矩,考虑了旋转。


x, y, w, h = cv.boundingRect(cnt)  # 外接矩形
cv.rectangle(img2, (x, y), (x + w, y + h), (0, 255, 0), 2)
rect = cv.minAreaRect(cnt)  # 最小外接矩形
box = np.int0(cv.boxPoints(rect))  # 矩形的四个角点取整
cv.drawContours(img2, [box], 0, (255, 0, 0), 2)

其中np.int0(x)是把x取整的操作,比如377.93就会变成377,也可以用x.astype(np.int)

4、最小外接圆

外接圆跟外接矩形一样,找到一个能包围物体的最小圆:

(x, y), radius = cv.minEnclosingCircle(cnt)
(x, y, radius) = np.int0((x, y, radius))  # 圆心和半径取整
cv.circle(img2, (x, y), radius, (0, 0, 255), 2)

5、外接椭圆

我们可以用得到的轮廓拟合出一个椭圆:

ellipse = cv.fitEllipse(cnt)
cv.ellipse(img2, ellipse, (255, 255, 0), 2)

6、判断点和轮廓关系

result = cv.pointPolygonTest(biggest, (w,h), False)

第一个参数是某一轮廓。第二个参数是像素点坐标。第三个参数如果为True则输出该像素点到轮廓最近距离;如果为False,则输出为正表示在轮廓内,0为轮廓上,负为轮廓外。

相关文章

  • 从图像边缘到物体轮廓

    上一篇已经讲解了很多算子用来检测边缘,其中用得最多的是canny边缘检测。只有边缘还不够,有很多时候我们还需要获得...

  • 轮廓发现

    轮廓发现   轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓发现结果。相...

  • 028-Opencv笔记-轮廓发现

    轮廓发现 轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法。所以边缘提取的阈值选定会影响最终轮廓发现结果API介...

  • opencv+python -- 轮廓发现

    轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓发现结果 Code 运行结...

  • 识别物体+路径生成

    流程 截取视频 图像处理识别物体二值化物体定位 经过erode/dilate后物体轮廓偏移了 生成路径路径中的坐标...

  • 图像处理常用边缘检测算子总结

    不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像。需要说明的是:边缘和物体间的边界并不等同,边缘...

  • Opencv第四课--轮廓检测

    轮廓检测 轮廓检测是检测图像中物体的轮廓。简单例子: 函数cv2.findContours()有三个参数。第一个是...

  • LabVIEW角点检测(基础篇—10)

    图像的特征是图像的原始特性或属性,它包含图像中的关键信息,是机器视觉算法工作的基础。 图像的灰度、边缘、轮廓、纹理...

  • opencv-图像处理api及效果展示

    滤波【线性;非线性】 - [含义:不能损坏图像的轮廓以边缘等重要信息;使图像清晰视觉效果好] 平滑滤波: 功能:一...

  • 边缘检测及扩展学习(OpenCV学习笔记之三)

    在图像处理中经常有一个需求就是要知道图像中物体的边缘,以此来做物体区分或作其他处理,有时还可实现某些滤镜效果例如我...

网友评论

      本文标题:从图像边缘到物体轮廓

      本文链接:https://www.haomeiwen.com/subject/depazqtx.html