博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python-opencv自学,图像金字塔与图像融合
阅读量:3968 次
发布时间:2019-05-24

本文共 5635 字,大约阅读时间需要 18 分钟。

本篇文章讲解基于python-opencv图像金字塔API及浅析原理


文章目录

一. 图像金字塔

1. 图像金字塔是什么?为什么要叫它图像金字塔?

图像金字塔是对出现处理发展至今的一种手段。它是图像多尺度表达的一种,它的本质就是一张图片的集合,我们可以用列表存,可以用字典存,只要是可变的结构就可以存储。该集合中每一个元素就是一个原图的子图集。他之所以称之为金字塔,是因为,图像金字塔的构建是采用一次次梯度向下取样获得,最后组成的层次性的结果像一个金字塔一样,取名为图像金字塔。

在这里插入图片描述

2. 图像金字塔构建原理

图像金字塔的构建,得从两个金字塔来说

①. 高斯金字塔

高斯金字塔是最基本的图像金字塔。

其构建过程为对一张大图采用,将原图像的连续行和列去除利用一个总长为5的高斯核进行模糊的操作。
一般的过程为,先对图像进行高斯内核卷积,完成模糊操作,之后去除掉偶数行和列,这样原图就会变为以前的四分之一(因为行列都变为以前的二分之一),高斯核从官档来看应该是1*5若是有问题可以指出,这里我没有太关注,之后重复以上过程,直至达到终止条件或者报错。

②. 拉普拉斯金字塔

拉普拉斯金字塔,是基于高斯金字塔获取的图像金字塔。一般情况下先计算高斯金字塔。其计算公式如下

在这里插入图片描述
这里的L就是拉普拉斯金字塔。G就是高斯金字塔,i为下标,pyrup方法是对图片的扩大,这里注意它并不是图像降采样的逆方法,它的扩大过程为填充新的偶数行和列为0,并利用先前的卷积核进行卷积,近似的估计元素,它并不能获取原图,只能获取一个预测图。公式表明,每一层的拉普拉斯金字塔,就高斯金字塔该层图的减去下一层的放大图。求出高斯金字塔列表后,用代码也很容易构建。拉普拉斯金字图大多是如下:
在这里插入图片描述

像这样一个边界图,其实,拉普拉斯金字塔更多时用于图片压缩的。

二. 代码方面

1. 构建高斯金字塔

#利用图像金字塔对图像进行融合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())
  • 注意传入的图像一定要是正方图,如果不是正方图要记得用numpy的reshape或者cv2的resize将图转化为正方图。

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)

在这里插入图片描述

  • 在构建金字塔那里需要不断的迭代和保存
  • cv2.copy()方法可以获取一张copy后的图片,并且不对原图片产生影响。

2. 拉普拉斯金字塔

#利用图像金字塔对图像进行融合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())

结果如下图

在这里插入图片描述

  • 注意pyrUp的参数,dstsize一般这个尺寸大小是按照 Size(src.cols* 2, src.rows*2) 来计算的。
  • cv.subtract:之前讲过,对图像做减法。
  • 高斯金字塔构建完毕之后,最小的图像在最高层,但是在列表的最后,因此需要从最后一张图片开始遍历。始终记住公式和关系,代码就很容易构建。

三. 使用实例

1. 必要掌握的知识基础

讲到图像融合,这里需要说明两个方法,在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()

结果如下:

在这里插入图片描述

这里我们明显可以看到图像合并之间有一条接线,而利用金字塔进行合并便是牺牲一定信息的情况下,抹除掉这条界限。

2. 使用图像金字塔合并图像

#利用图像金字塔对图像进行融合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())

结果如下:

在这里插入图片描述

三. 对之前知识的补充

1. 读取视频文件,做加速或者缓速

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()
  • 一般情况下25~30为比较舒服的速度,如果将waitKey的参数调制1那么速度就会很快,如果太大就会造成延迟播放的情况。

这里主要是一个同学这块,想起之前没有细说。

转载地址:http://xkcki.baihongyu.com/

你可能感兴趣的文章
SQL - SQL Server 之处理JSON数据
查看>>
SQL - SQL Server 之WHILE循环的坑
查看>>
SQL - SQL Server 性能优化之SQL语句总结
查看>>
Docker - docker-compose常用命令
查看>>
SQL - SQL Server判断字符串中是否有中文
查看>>
SQL - SQL Server查询近7天的连续日期
查看>>
SQL - SQL Server中如何取年、月、日 -DATEPART函数
查看>>
SQL - SQL Server 一列或多列重复数据的查询,删除
查看>>
NET - .NET Core WebAPI + Vue + Axios 导出Excel / CSV
查看>>
NET - NET Core quartz.net 时间表达式----- Cron表达式详解
查看>>
NET - .NET Core 之 Abp Audit-Logging
查看>>
NET - .NET Core 之 Abp 整合 Quartz
查看>>
Spring - Nacos 配置实时更新原理分析
查看>>
依赖注入
查看>>
android 各式各样progress 进度条大全
查看>>
开发Google眼镜的app
查看>>
Android base-adapter-helper 源码分析与扩展
查看>>
Android 4.4从图库选择图片,获取图片路径并裁剪
查看>>
Android Fragment 你应该知道的一切
查看>>
使用AudioManager调节播放器音量的开发实例
查看>>