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()

推荐链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: