本文共 5635 字,大约阅读时间需要 18 分钟。
本篇文章讲解基于python-opencv图像金字塔API及浅析原理
图像金字塔是对出现处理发展至今的一种手段。它是图像多尺度表达的一种,它的本质就是一张图片的集合,我们可以用列表存,可以用字典存,只要是可变的结构就可以存储。该集合中每一个元素就是一个原图的子图集。他之所以称之为金字塔,是因为,图像金字塔的构建是采用一次次梯度向下取样获得,最后组成的层次性的结果像一个金字塔一样,取名为图像金字塔。
图像金字塔的构建,得从两个金字塔来说
高斯金字塔是最基本的图像金字塔。
其构建过程为对一张大图采用,将原图像的连续行和列去除利用一个总长为5的高斯核进行模糊的操作。 一般的过程为,先对图像进行高斯内核卷积,完成模糊操作,之后去除掉偶数行和列,这样原图就会变为以前的四分之一(因为行列都变为以前的二分之一),高斯核从官档来看应该是1*5若是有问题可以指出,这里我没有太关注,之后重复以上过程,直至达到终止条件或者报错。拉普拉斯金字塔,是基于高斯金字塔获取的图像金字塔。一般情况下先计算高斯金字塔。其计算公式如下
这里的L就是拉普拉斯金字塔。G就是高斯金字塔,i为下标,pyrup方法是对图片的扩大,这里注意它并不是图像降采样的逆方法,它的扩大过程为填充新的偶数行和列为0,并利用先前的卷积核进行卷积,近似的估计元素,它并不能获取原图,只能获取一个预测图。公式表明,每一层的拉普拉斯金字塔,就高斯金字塔该层图的减去下一层的放大图。求出高斯金字塔列表后,用代码也很容易构建。拉普拉斯金字图大多是如下:像这样一个边界图,其实,拉普拉斯金字塔更多时用于图片压缩的。
#利用图像金字塔对图像进行融合import cv2 as cvimport numpy as npdef load_image(): src_1=cv.imread('same_1.jpg') src_1=cv.resize(src_1,(2048,2048)) #src_2=cv.imread('same_2.jpg') #src_2=cv.resize(src_2,(512,512)) return src_1#,src_2#做高斯金字塔def pyramid(image): src=image.copy() level=5 pyramid_reduce=[] for i in range(level): dst=cv.pyrDown(src) cv.imshow('input'+str(i),dst) pyramid_reduce.append(dst) src=dst.copy() cv.waitKey(0) cv.destroyAllWindows() return pyramid_reducepyramid(load_image())
np.reshape():
import numpy as npa=np.random.rand(1,9)a=np.reshape(a,(3,3))print(a)
cv2.resize():转化图片的尺寸
import cv2 as cva=cv.imread('noise.jpg')print(a.shape)a=cv.resize(a,(256,256))print(a.shape)
#利用图像金字塔对图像进行融合import cv2 as cvimport numpy as npdef load_image(): src_1=cv.imread('con_1.jpg') src_1=cv.resize(src_1,(1024,1024)) #src_2=cv.imread('same_2.jpg') #src_2=cv.resize(src_2,(512,512)) return src_1#,src_2#做高斯金字塔def pyramid(image): src=image.copy() level=4 pyramid_reduce=[] for i in range(level): dst=cv.pyrDown(src) pyramid_reduce.append(dst) src=dst.copy() return pyramid_reducedef lapalian(image): #设置拉普拉斯金字塔返回值列表 lap=[] #获取高斯金字塔 gaussian=pyramid(image) #获取长度 用于遍历 level=len(gaussian) #从最低层开始 for i in range(level-1,-1,-1): #升维后 利用公式计算拉普拉斯 利用pyrup #为0直接计算原图 if i == 0: extend=cv.pyrUp(gaussian[i],dstsize=image.shape[:2]) lpls=cv.subtract(image,extend) lap.append(lpls) cv.imshow('lap'+str(i),lpls) else: extend=cv.pyrUp(gaussian[i],dstsize=gaussian[i-1].shape[:2]) lpls=cv.subtract(gaussian[i-1],extend) lap.append(lpls) cv.imshow('lap'+str(i),lpls) #返回列表 cv.waitKey(0) cv.destroyAllWindows() return laplapalian(load_image())
结果如下图
讲到图像融合,这里需要说明两个方法,在numpy中比较重要。
np.vstack():矩阵在竖直方向进行堆叠
np.hstack():在横向方向进行平铺
import numpy as npimport cv2 as cvarray_1=np.array([[1,2,3],[4,5,6],[7,8,9]])array_2=np.array([[10,11,12],[13,14,15],[16,17,18]])print(array_1)print(array_2)array_3=np.vstack((array_1,array_2))print(array_3)array_4=np.hstack((array_1,array_2))print(array_4)
结果如下:
不难想到可以利用这俩个方法对图像进行操作,将图像以某种方式合并。
import numpy as npimport cv2 as cvimg_1=cv.imread('con_1.jpg')img_1=cv.resize(img_1,(540,540))img_2=cv.imread('con_2.jpg')img_2=cv.resize(img_2,(540,540))img_3=np.vstack((img_1[:img_1.shape[0]//2,:,:],img_2[:img_2.shape[0]//2,:,:]))img_4=np.hstack((img_1[:,:img_1.shape[1]//2,:],img_2[:,:img_2.shape[1]//2,:]))cv.imshow('fuse_1',img_3)cv.imshow('fuse_2',img_4)cv.waitKey(0)cv.destroyAllWindows()
结果如下:
这里我们明显可以看到图像合并之间有一条接线,而利用金字塔进行合并便是牺牲一定信息的情况下,抹除掉这条界限。
#利用图像金字塔对图像进行融合import cv2 as cvimport numpy as npdef load_image(): src_1=cv.imread('same_1.jpg') src_1=cv.resize(src_1,(512,512)) src_2=cv.imread('same_2.jpg') src_2=cv.resize(src_2,(512,512)) return src_1,src_2#做高斯金字塔def pyramid(image): src=image.copy() level=6 pyramid_reduce=[] for i in range(level): dst=cv.pyrDown(src) pyramid_reduce.append(dst) src=dst.copy() return pyramid_reducedef lapalian(image): #设置拉普拉斯金字塔返回值列表 lap=[] #获取高斯金字塔 gaussian=pyramid(image) #获取长度 用于遍历 level=len(gaussian) #从最低层开始 for i in range(level-1,-1,-1): #升维后 利用公式计算拉普拉斯 利用pyrup #为0直接计算原图 if i == 0: extend=cv.pyrUp(gaussian[i],dstsize=image.shape[:2]) lpls=cv.subtract(image,extend) lap.append(lpls) else: extend=cv.pyrUp(gaussian[i],dstsize=gaussian[i-1].shape[:2]) lpls=cv.subtract(gaussian[i-1],extend) lap.append(lpls) #返回列表 return lapdef fuse_app(image_1,image_2): #构建拉普拉斯金字塔 lap_1=lapalian(image_1) lap_2=lapalian(image_2) #存储合并图片的列表 l_s=[] for l_1,l_2 in zip(lap_1,lap_2): row,col=l_1.shape[:2] l_add=np.hstack((l_1[:,:col//2],l_2[:,:col//2])) l_s.append(l_add) l_t=l_s[0] for i in range(1,6): l_t=cv.pyrUp(l_t) l_t=cv.add(l_t,l_s[i]) cv.imshow('fuse',l_t) cv.waitKey(0) cv.destroyAllWindows()fuse_app(*load_image())
结果如下:
import numpy as npimport cv2 as cvcapture=cv.VideoCapture('test.mp4')while True : #利用read方法获取帧数以及布尔值 ret,frame=capture.read() cv.imshow('input',frame) c=cv.waitKey(30) #27为esc的asc if c==27: breakcv.destroyAllWindows()
这里主要是一个同学这块,想起之前没有细说。
转载地址:http://xkcki.baihongyu.com/