计算机视觉11-轮廓绘制、特征、近似;模板匹配

目录

1.轮廓绘制

2.轮廓特征

3.轮廓近似

3.1近似

3.2外接矩形

3.3外接圆

4.模板匹配

4.1单个对象匹配

4.2多个对象匹配


 前提准备:调用相应的库,包括cv2,matplotlib,numpy

1.轮廓绘制

 读入的原图为:ppt自己手动画的,很难百度出满意的图。后面涉及到轮廓的一些信息读取,建议在这一步采用一些恶比较简单的图形。

img=cv2.imread('F:D.PNG')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)

↑读入图片-灰度处理-二值化处理

contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

↑ 读取到的两个参数的意思分别是:轮廓点的信息-list结构;层级信息

draw_img=img.copy()

↑原图复制一份,待会画轮廓将在复制出来的图片上画。如果不复制,直接会将轮廓画在原图上,这样的话如果后面还需要用到原图,而原图却被改变(附加了自己画的轮廓) 

res=cv2.drawContours(draw_img,contours,-1,(0,0,255),1)

↑ cv2.drawContours()里面四个参数分别是:在哪副图轮廓;轮廓信息;所有的轮廓显示哪一个(-1代表图片中所有元素的轮廓);轮廓的颜色;轮廓的粗细

用cv2.imshow()函数显示运行效果:

cv2.drawContours()函数第三个参数为-1时,所有轮廓都画出来了

当cv2.drawContours()第三个参数为0,1,2,3时的效果图:

 

 

2.轮廓特征

cnt=contours[3]
area=cv2.contourArea(cnt)
length=cv2.arcLength(cnt,True)#true代表封闭
print(area)
print(length)

↑congtour[3]表示:取的是cv2.drawContours()函数第三个参数取3的图形的轮廓的信息,这里具体是哪个图形的轮廓不能主观臆断,需要代码运行一下看到底是哪一个。这幅图参数为3时对应的是圆的轮廓。

cnt=contours[]这一步是必须的,每次都要申明自己在哪个轮廓上操作。

cv2.contourArea(cnt)是轮廓的面积,cv2.arcLength(cnt,True)是轮廓的周长,运行结果如下:

 

3.轮廓近似

读入的图片为:

↑为了显示取近似时参数的作用,尽量选取这种凹凸有致的图形,上图是用PPT绘制。 

3.1近似

img=cv2.imread('F:ddd.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

↑以上为准备工作,过程和轮廓绘制完全一致,即读入图片、灰度处理、二值化处理、 cv2.findContours()函数提取轮廓信息

draw_img=img.copy()
cnt=contours[-1]

↑ 原图复制,此后的工作都是在draw_img这幅图上而不是img这幅图;cnt为-1即图像的全部元素的轮廓,这幅图就一个元素。

#参照值:决定是否将一段曲线近为直线
epsilon=0.1*cv2.arcLength(cnt,True)
#近似轮廓
approx=cv2.approxPolyDP(cnt,epsilon,True)
#将近似出来的轮廓画在复制出来的图片上
res=cv2.drawContours(draw_img,[approx],-1,(0,0,255),1)

当式中的自变量分别取0.001,0.01,0.1,0.15时,近似出来的轮廓效果如下:

 

3.2外接矩形

依然是3.1节轮廓近似的图片

cnt=contours[-1]
#确定矩形边界
x,y,w,h=cv2.boundingRect(cnt)
draw_img=img.copy()
#在复制的图中画出矩形边界,左上角开始画
res=cv2.rectangle(draw_img,(x,y),(x+w,y+h),(0,0,255),2)

运行结果:

 

3.3外接圆

#确定圆心及半径
(x,y),radius=cv2.minEnclosingCircle(cnt)
center=(int(x),int(y))
radius=int(radius)
draw_img=img.copy()
#复制的图层上画外接圆
img=cv2.circle(draw_img,center,radius,(0,255,0),2)

效果如下:

 Orz,图片有点小,画的圆出界了。

4.模板匹配

4.1单个对象匹配

读入库,读入原图并灰度处理,读入匹配模板-灰度图格式。模板大小无所谓,只要是在原图上截下来的就成。原图和模板为:

 

h,w=face.shape
print(h,w)

↑确定模板的高和宽,为后面确定好对象之后画矩形框框起来

res=cv2.matchTemplate(img,face,cv2.TM_SQDIFF_NORMED)
min_val,max_val,min_loc,max_loc=cv2.minMaxLoc(res)

↑ cv2.matchTemplate()是一个匹配函数,匹配的是输入的img.jpg图片和face.jpg模板,匹配的方式是cv2.TM_SQDIFF_NORMED,即方差并归一化。

↑每次匹配时都是一个一个像素点移动,因此有超级多匹配信息,用cv2.minMaxLoc(res)函数将匹配结果中value值最小和最大的那个信息提取出来。具体可以提取出来最大最小匹配结果值和此时的位置。对于平方差处理方式来说,匹配结果越小,说明两者差异越小。
 

top_left=min_loc
Tm=cv2.rectangle(img, (top_left[0],top_left[1]), (top_left[0] + w,top_left[1] + h), (0, 0, 255), 1)

↑此时应该取得点应该是min_loc,这个点在匹配的位置的左上角,再根据模板的大小在原图上画出矩形,以此作为匹配结果。

几种常见的匹配方式处理结果如下图所示:

4.2多个对象匹配

img=cv2.imread('F:T.jpg')
img1=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
template=cv2.imread('F:T1.jpg',0)
h,w=template.shape

↑读入库(代码中未呈现),读入图片并灰度处理,读入模板并灰度处理,读出模板的高和宽

 读入的原图和模板为:

res=cv2.matchTemplate(img1,template,cv2.TM_CCOEFF_NORMED)

↑匹配函数

threshold=0.8
img2=img.copy()
loc=np.where(res>=threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(img2,pt,(pt[0]+w,pt[1]+h),(0,0,255),1)

↑cv2.TM_CCOEFF_NORMED匹配方式,匹配值越大越接近。当大于阈值时,就认为匹配的对象是合格的,和模板是一致的,将之用和模板一样大的矩形框框起来。

匹配结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值