12. 形态学--轮廓、多边形逼近与凸包

1. 轮廓

findContours(image, mode, method[, contours[, hierarchy[, offset]]])

  • mode查找轮廓的模式
    cv2.RETR_EXTERNAL = 0,表示指检测外围扩阔
    cv2.RETR_LIST = 1,检测的轮廓不建立等级关系,即检测所有的轮廓
    cv2.RETR_CCOMP = 2,每层最多两级,从小到大,从里到外
    cv2.RETR_TREE = 3,按照树型存储轮廓,从大到小,从右到左,较为常用
  • method 轮廓近似方法,也叫ApproximationMode
    cv2.CHAIN_APPROX_NONE 保存所有轮廓上的点
    cv2.CHAIN_APPROX_SIMPLE 只保存角点,存储信息少,比较常用
  • 反馈contours和hierarchy 即轮廓和层级
img = cv2.imread('./contors1.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
# 注意contours是一个list,里面的元素是ndarray,每个ndarray表示一个contour
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 注意,会直接在原图上进行操作,如果要原图保持不变,就需要copy一份
img_copy = img.copy()
cv2.drawContours(img_copy, contours, 1, (0,0,255), 2)

# 计算轮廓面积
area = cv2.contourArea(contours[1])

# 计算轮廓周长
cv2.arcLength(contours[1], closed=True)

# 返回结果是一个Rotated Rect 旋转的矩形,矩形的起始坐标(x, y), 矩形的长宽,矩形的旋转角度
# boundingRect(points) 最大外接矩阵
rect = cv2.minAreaRect(contours[1])

# cv的工具,将旋转矩阵的四个坐标点计算出来
# 注意:这个计算出来后的数据是float,而在绘图的时候,要求像素点位置,是int的
box = cv2.boxPoints(rect)
# 对boxPoints的结果进行处理
box = np.round(box).astype('int64')
cv2.drawContours(img, [box], 0, (255,0,0), 2)
cv2.imshow('img', img)

2. 多边形逼近与凸包

findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似,这就是轮廓的多边形逼近;
DP算法原理核心,不断找多边形最远的点加入形成新的多边形,直到最短距离小于指定的精度;
approxPolyDP(curve, epsilon, closed, approxCurve=None)

  • curve 要近似逼近的轮廓
  • epsilon 即DP算法使用的阈值
  • closed 轮廓是否闭合
# 获取单个轮廓
cnt = contours[0]
# 根据轮廓周长来逼近
epsilon = 0.05*cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
# 将res使用cv2.im_show()展示出来

# 边界矩形
x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x,y), (x+w, y+h), (0,255,0), 2)
# im_show()

# 最小外接圆
(x,y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
img = cv2.circle(img, center, radius, (0,255,0), 2)
# im_show()

posted @ 2022-06-26 20:51  理舞  阅读(320)  评论(0编辑  收藏  举报