轮廓

轮廓是连接具有相同颜色或强度的所有连续点(沿边界)的曲线。轮廓是用于形状分析以及对象检测和识别的有用工具。

  • 为了准确,要使用二值化图像。需要进行阈值化处理或者Canny边界检测。
  • 查找轮廓的函数会修改原始图像。如果之后想继续使用原始图像,应该将原始图像存储到其他变量中。从Opencv3.2开始,findContours()不再修改源图像。
  • 在OpenCV中,找到轮廓就像从黑色背景中找到白色物体。因此,要找到的对象是白色背景应该是黑色。

cv.findContours()函数中有三个参数,第一个是源图像,第二个是轮廓检索模式,第三个是轮廓逼近方法。输出等高线和层次结构。轮廓是图像中所有轮廓的python列表。每个单独的轮廓是一个(x,y)坐标的Numpy数组的边界点的对象。

cv.drawContours()函数,可以绘制轮廓。只要有边界点,它也可以用来绘制任何形状。它的第一个参数是源图像,第二个参数是应该作为python列表传递的轮廓,第三个参数是轮廓的索引(在绘制单个轮廓时有用,要绘制所有轮廓,请传递-1),其余参数是颜色、厚度等。

import cv2 as cv

img=cv.imread('./images/lena.jpeg')
imggray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,thresh=cv.threshold(imggray,127,255,0)
contours,hierarchy=cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
# 在图像中绘制所有轮廓
img1=cv.drawContours(img,contours,-1,(0,255,0),3)
# 绘制单个轮廓,如第四个轮廓
img2=cv.drawContours(img,contours,3,(0,255,0),3)
# 但是在大多数情况下,以下方法会很有用
cnt=contours[4]
cv.drawContours(img,[cnt],0,(0,255,0),3)
cv.imshow('img',img)
cv.imshow('gray',imggray)
cv.imshow('img1',img1)
cv.imshow('img2',img2)
cv.waitKey(0)
cv.destroyAllWindows()

结果:

 轮廓的近似方法

之前提到的轮廓是一个形状具有相同灰度值的边界,它会存储形状边界上所有(x,y)坐标。实际上不需要所有的点,当需要直线时,找到两个端点即可。cv.CHAIN_APPROX_SIMPLE可以实现。它会将轮廓上的冗余点去掉,压缩轮廓,从而节省内存开支。

下面用矩阵来演示,在轮廓列表中的每一个坐标上画一个蓝色圆圈。第一个显示使用cv.CHAIN_APPROX_NONE的效果,一共734个点,第二个图是使用cv.CHAIN_APPROX_SIMPLE的结果,只有4个点。

 

 posted on 2024-05-04 11:09  会飞的金鱼  阅读(18)  评论(0)    收藏  举报