opencv——图形金字塔、轮廓、模板

1、图像金字塔

定义:把图像按照分辨率大小组合成金字塔的形状,主要用于图像的多层级特征提取。

a、高斯金字塔

img=cv2.imread("AM.png")
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
print(img.shape)
第一种:向下采样方法(金字塔从下往上走)——缩小
步骤:1、将原图像与高斯核模板进行卷积操作(先相乘再加在一起)。
2、将所有的偶数行核列去除掉。

高斯核模板(1/16表示归一化)

up=cv2.pyrUp(img)
cv2.imshow("up",up)
cv2.waitKey()
cv2.destroyAllWindows()
print(up.shape)
第二种:向上采样方法(金字塔从上往下走)——放大
步骤:1、将图像在每个方向扩大为原来的两倍,新增的行和列以0填充。
2、使用先前同样的高斯核模板(乘以4)与放大后的图像卷积,获得近似值。
down=cv2.pyrDown(img)
cv2.imshow("down",down)
cv2.waitKey()
cv2.destroyAllWindows()
print(down.shape)

ps:如果对原图像先上采样再下采样,得到的结果比原图像会差一点,因为进行上采样是采用0进行填充放大的,再进行下采样会损失一些信息。

b、laplacian金字塔

down=cv2.pyrDown(img)
down_up=cv2.pyrUp(down)
l_1=img-down_up
cv2.imshow("l_1",l_1)
cv2.waitKey()
cv2.destroyAllWindows()

2、图像轮廓的检测

cv2.findContours(img,mode,method)

mode(轮廓检索模式): 1、RETR_EXTERNAL——只检索最外边的轮廓

2、RETR_LIST——检索所有的轮廓,并将其保存到一条链表上

3、RETR_CCOMP——检索所有的轮廓,并将其组织为两层,顶层是各部分的外部边界,第二层

是空洞的边界

4、RETR_TREE——检索所有的的轮廓,并重构嵌套轮廓的整个层次(最常用的模式)

method(轮廓逼近方法):1、CHAIN_APPROX_NONE——以FREEMAN链码的方式输出轮廓,所有

其他方法输出多边形(顶点的序列)

2、CHAIN_APPROX_SIMPLE——压缩水平的、垂直的和斜的的部分,函数

只保留它们的终点部分

ps:轮廓检测最好是二值化图像

img=cv2.imread("contour.png")
#转化为灰度图像
gray=cv2.cvtColor(img,cv2.BGR2GRAY)
#采用阈值处理转化为二值化图像
ret,thresh=cv2.Threshold(img,127,255,cv2.THRESH_BINARY)
cv2.imshow("thresh",thresh)
cv2.waitKey()
cv2.destroyAllWindows()
#轮廓检测(binary:二值化图像,contours:轮廓点信息,hierarchy:轮廓层级
binary,contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
#绘制轮廓
draw_img=img.copy
#-1是指绘制全部轮廓,其他数字按照从左下开始检测部分轮廓,2是指绘制的线条宽度
res=cv2.drawContours(draw_img,contours,-1,(0,0,255),2)
cv2.imshow("res",res)
cv2.waitKey()
cv2.destroyAllWindows()

3、轮廓计算

a 、轮廓特征(面积和周长)

cnt=contours[0]#第0个轮廓
cv2.contourArea(cnt)#计算轮廓面积
cv2.arcLength(cnt,True)#计算轮廓周长,True表示闭合

b、轮廓近似

以直代曲:设定一个阈值,如果两点间的曲线弯曲程度大于阈值则用直线代替,否则在中间再找一点,寻找两条直线代替。(类似于二分法)

epsilon=0.1*cv2.arcLength(cnt,True)
approx=cv2.approxPolyDP(cnt,epsilon,True)#近似函数,利用0.1倍周长作为阈值
draw_img=img.copy()
res=cv2.drawContours(draw_img,[approx],-1,(0,0,255),2)
cv2.imshow("res",res)
cv2.waitKey()
cv2.destroyAllWindows()

c、外接图形(边界矩形和外接圆)

#边界矩形
x,y,w,h=cv2.boundingRect(cnt)
img=cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
#轮廓面积与边界矩形比
area=cv2.contourArea(cnt)
x,y,w,h=cv2.boundingRect(cnt)
rect_area=w*h
extent=float(area)/rect_area
pri("轮廓面积与边界矩形比:",extent)
#外接圆
(x,y),radius=cv2.minEnclosingCircle(cnt)
center=(int(x),int(y))
radius=int(radius)
img=cv2.circle(img,center,radius,,(0,255,0),2)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

4、模板匹配

定义:模板匹配类似于卷积,模板在原图像上从原点开始滑动,计算模板与图形被模板覆盖区域的差别程度,将每次计算的结果都保存到一个矩阵里,作为结果输出

假设:模板:a*b 原图像:A*B 输出结果矩阵:(A-a+1)*(B-b+1)

差别程度计算方法:TM_SQDIFF:计算平方不同,值越小,越相关

TM_CCORR:计算相关性,值越大,越相关

TM_CCOEFF:计算相关系数,值越大,越相关

TM_SQDIFF_NORMED:计算归一化平方不同,越接近于0越相关

TM_CCORR_NORMED:计算归一化相关性,越接近于1越相关

TM_CCOEFF_NORMED:计算归一化相关系数,越接近于1越相关

a、匹配单个对象

import cv2
import matplotlib.pyplot as plt
img=cv2.imread("lena.jpg",0)
template=cv2.imread("face.jpg",0)
h,w=template.shape[:2]
img.shape
template.shape
methods=["cv2.TM_CCOEFF","cv2.TM_CCOEFF_NORMED","cv2.TM_CCORR","cv2.TM_CCORR_NORMED","cv2.TM_SQDIFF","cv2.TM_SQDIFF_NORMED"]
for meth in methods:
    img2=img.copy()
    method=eval(meth)#不能是字符串
    print(method)
    res=cv2.matchTemplate(img2,template,method)
    res.shape
    min_val,max_val,min_roc,max_roc=cv2.minMaxLoc(res)#最小值,最大值,最小值坐标位置,最大值坐标位置
    if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
       top_left=min_roc
    else :
       top_left=max_roc
    bottom_right=(top_left[0]+w,top_left[1]+h)
    cv2.rectangle(img2,top_left,bottom_right,255,2)
    plt,subplot(121)
    plt.imshow(res,cmap="gray")
    plt.xtick([])#隐藏坐标轴
    plt.ytick([])
    plt.subtitle(meth)
    plt.show()

b、匹配多个模板对象

threshold=0.8#设定一个阈值
loc=np.where(res>=threshold)
for pt in zip(*loc[::-1]):
    bottom_right=(pt+w,pt+h)
    cv2.rectangle(img2,pt,bottom_rigth,(0,0,255),2)
    cv2.imshow("img2",img2)
    cv2.waitKey()
    cv2.destroyAllWindows()
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一瞬にして失う

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

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

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

打赏作者

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

抵扣说明:

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

余额充值