openCV专栏(九):图像轮廓:凸包

OPENCV基础操作

提示:本专栏所用版本仅供参考,其他版本也可

版本
pythonPython 3.9.3
opencv4.5.5
matplotlib3.4.3
numpy1.19.5
QQ学习群点击加群:928357277

提问环节

1:什么是凸包

答:凸包是一种对逼近多边形简化的多边形,是物体最外层的“凸”多边形

2:凸包有什么特征

答:它的每一处都应该是凸起的,在凸包内,任意连续的三个点的内角小于180度

3:如何获取凸包

答:openCV提供了函数convexHull() 来获取

获取凸包

hull = cv2.convexHull(points[,clockwise[,returnPoints]])
返回值为凸包角点hull
参数为:轮廓points,顺逆时针标志clockwise,返回轮廓特性标志(返回x/y轴坐标,或凸包角点)

获取并绘制凸包多边形

import matplotlib.pyplot as plt #导入模块
import cv2
import numpy as np

img = cv2.imread('1.jpg')

imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#构造矩形边框

print(c[2].shape)
# 得到凸包的角点
hull = cv2.convexHull(c[2])
#绘制凸包
cv2.polylines(imgGray,[hull],True,(255,255,255),2)
#显示图片
cv2.imshow('imgGray',imgGray)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:红色箭头为后期添加
在这里插入图片描述

凸缺陷

凸包与轮廓之间的部分,称为为凸缺陷
convexityDefects = cv2.convexityDefects(contour,convexhull)
返回值;convexityDefects为缺陷点集,是一个数组,每一行包含[起点,终点,轮廓上距离凸包最远的点,最远点到凸包的近似距离]
参数为:轮廓contour、凸包convexhull

缺陷点集展示

import cv2

img = cv2.imread('1.jpg')

imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

# 得到凸包
hull = cv2.convexHull(c[10],returnPoints=False)
defects = cv2.convexityDefects(c[10],hull)
#构造缺陷包

for i in range(defects.shape[0]):
    s,e,f,d = defects[i,0]
    start = tuple(c[10][s][0])
    end = tuple(c[10][e][0])
    far = tuple(c[10][f][0])
    cv2.line(imgGray,start,end,[255,255,255],2)#绘制直线
    cv2.circle(imgGray,far,5,[0,0,0],-1)#绘制圆形

#显示图片
cv2.imshow('imgGray',imgGray)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

几何学测试

检测轮廓是否是凸形的

retval = cv2.isContourConvex(contour)
返回值为轮廓凸形转态
参数为轮廓

(全代码后面有演示)

retval = cv2.isContourConvex(hull)#判断是否是凸形

点到轮廓的垂线(最短)距离及位置判定

retval = cv2.pointPolygonTest(contour,pt,measureDist)
返回值为距离或者点对线的位置
参数为:轮廓Contour、待判定的点pt,距离判定方式measureDist(当为True时,表示计算距离,当为False时,表示得到位置)
全代码后面有演示)

retval = cv2.cv2.pointPolygonTest(hull,(300,150),True)#判断点(300,150)到轮廓的距离

判断逼近多边形是否为凸包并判断点A和轮廓的关系

import cv2

img = cv2.imread('1.jpg')

imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
r,imgGray = cv2.threshold(imgGray,180,255,cv2.THRESH_BINARY_INV)
c,h = cv2.findContours(imgGray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

#绘制逼近多边形
imgGrayL = imgGray.copy()
epslion = 0.01*cv2.arcLength(c[10],True)
approx = cv2.approxPolyDP(c[10],epslion,True)
retL = cv2.isContourConvex(approx)
imgGrayL = cv2.cvtColor(imgGrayL,cv2.COLOR_GRAY2BGR)
imgGrayL = cv2.drawContours(imgGrayL,[approx],0,(255,255,0),2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(imgGrayL,'%s%d'%("it is : ",retL),(100,100),font,1,(255,0,255),2)#将结果写入屏幕中
# 判断点和轮廓的关系
hull = cv2.convexHull(c[10])
imgGray = cv2.cvtColor(imgGray,cv2.COLOR_GRAY2BGR)#转换为BGR色彩空间
cv2.polylines(imgGray,[hull],True,(0,255,0),2)
rev = cv2.pointPolygonTest(hull,(300,150),True)
cv2.putText(imgGray,'A',(300,150),font,1,(0,255,0),3)#将结果写入屏幕中

#显示图片
cv2.imshow('imgGray',imgGray)
cv2.imshow('imgGrayL',imgGrayL)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述
如果你也喜欢编程,点击群号加入我们的QQ大家庭 928357277吧!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亿只萌新

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值