基于小波变换的图像融合(附加视频融合)代码

这篇具有很好参考价值的文章主要介绍了基于小波变换的图像融合(附加视频融合)代码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于小波变换的图像融合(附加视频融合)代码

一、小波变换

小波分析是一个比较难的分支,用户采用小波变换,可以实现图像压缩,振动信号的分解与重构等,因此在实际工程上应用较广泛。小波分析与Fourier变换相比,小波变换是空间域和频率域的局部变换,因而能有效地从信号中提取信息。小波变换通过伸缩和平移等基本运算,实现对信号的多尺度分解与重构,从而很大程度上解决了Fourier变换带来的很多难题。
小波分析作一个新的数学分支,它是泛函分析、Fourier分析、数值分析的完美结晶;小波分析也是一种“时间—尺度”分析和多分辨分析的新技术,它在信号分析、语音合成、图像压缩与识别、大气与海洋波分析等方面的研究,都有广泛的应用。

二、图像融合

1、采用对比度拉伸,完成红外图像增强

# 裁剪线性RGB对比度拉伸:(去掉2%百分位以下的数,去掉98%百分位以上的数,上下百分位数一般相同,并设置输出上下限)
def truncated_linear_stretch(image, truncated_value=2, maxout=255, min_out=0):
    def gray_process(gray, maxout=maxout, minout=min_out):
        truncated_down = np.percentile(gray, truncated_value)
        truncated_up = np.percentile(gray, 100 - truncated_value)
        gray_new = ((maxout - minout) / (truncated_up - truncated_down)) * gray
        gray_new[gray_new < minout] = minout
        gray_new[gray_new > maxout] = maxout
        return np.uint8(gray_new)
    (b, g, r) = cv2.split(image)
    b = gray_process(b)
    g = gray_process(g)
    r = gray_process(r)
    result = cv2.merge((b, g, r))# 合并每一个通道
    return result

2、采用Surf特征点匹配,完成图像配准

# RGB图片配准函数,采用白天的可见光与红外灰度图,计算两者Surf共同特征点,之间的仿射矩阵。
def Images_matching(img_base, img_target):
    img_base=cv2.cvtColor(img_base, cv2.COLOR_BGR2GRAY)
    img_target=cv2.cvtColor(img_target, cv2.COLOR_BGR2GRAY)
    hessian = 400
    # 初始化surf算子
    surf = cv2.xfeatures2d.SURF_create(hessian)
    # surf = cv2.xfeatures2d_SURF.create(hessian)
    # surf = cv2.SIFT_create(hessian)
    # 使用surf算子计算特征点和特征点周围的特征向量
    kp1, des1 = surf.detectAndCompute(img_base, None)  # 1136    1136, 64
    kp2, des2 = surf.detectAndCompute(img_target, None)
    # 进行KNN特征匹配
    FLANN_INDEX_KDTREE = 0  # 建立FLANN匹配器的参数
    indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)  # 配置索引,密度树的数量为5
    searchParams = dict(checks=50)  # 指定递归次数
    flann = cv2.FlannBasedMatcher(indexParams, searchParams)  # 建立匹配器
    matches = flann.knnMatch(des1, des2, k=2)  # 得出匹配的关键点  list: 1136
    good = []
    # 提取优秀的特征点
    for m, n in matches:
        if m.distance < 0.7 * n.distance:  # 如果第一个邻近距离比第二个邻近距离的0.7倍小,则保留
            good.append(m)   # 134
    src_pts = np.array([kp1[m.queryIdx].pt for m in good])  # 查询图像的特征描述子索引  # 134, 2
    dst_pts = np.array([kp2[m.trainIdx].pt for m in good])  # 训练(模板)图像的特征描述子索引
    H = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC)  # 生成变换矩阵  H[0]: 3, 3  H[1]: 134, 1
    return H[0]

3、采用HSV通道小波变换,完成图像融合

# YUV通道小波变换RGB融合,低频均值高频最大值
def Images_fusion(img_base,img_target):          # 可见光,配准后的红外光
    # 按照不同的融合方式,计算通道融合
    def fuseCoeff(cooef1, cooef2, method):
        if (method == 'mean'):
            cooef = (abs(cooef1) + abs(cooef2)) / 2  # abs 绝对值
            # cooef=0.5*cooef1+1.5*cooef2
        elif (method == 'min'):
            cooef = np.minimum(cooef1, cooef2)
        elif (method == 'max'):
            cooef = np.maximum(abs(cooef1), abs(cooef2))
        return cooef
    # HSV的小波融合过程
    LOW_METHOD = 'mean'
    HIGH_METHOD = 'max'
    YUVimg_base = cv2.cvtColor(img_base, cv2.COLOR_BGR2YUV)  # 可见光转换为HSV
    # cv2.imwrite("D:/VS/vsprj/cuda/cudawavetest/2.jpg", YUVimg_base)
    grayimg_target = cv2.cvtColor(img_target, cv2.COLOR_BGR2GRAY)  #红外灰度化
    # cv2.imwrite("D:/VS/vsprj/cuda/cudawavetest/1.jpg",grayimg_target)
    Yimg_base = YUVimg_base[:, :, 0]  # 1024,1024
    wavelet = 'haar'
    cooef_base = pywt.wavedec2(Yimg_base[:, :], wavelet, level=1)  # base灰度图的小波展开  512, 512    3
    start = time.time()
    cooef_target = pywt.wavedec2(grayimg_target[:, :], wavelet, level=1)  # target灰度图的小波展开   512, 512    3
    end = time.time()-start
    print("小波展开:{}".format(end))
    fusedCooef = []
    for i in range(len(cooef_base)):
        if (i == 0):
            fusedCooef.append(fuseCoeff(cooef_base[0], cooef_target[0], LOW_METHOD))  # 低频部分取均值
        else:
            # 高频部分取最大值
            c1 = fuseCoeff(cooef_base[i][0], cooef_target[i][0], HIGH_METHOD)
            c2 = fuseCoeff(cooef_base[i][1], cooef_target[i][1], HIGH_METHOD)
            c3 = fuseCoeff(cooef_base[i][2], cooef_target[i][2], HIGH_METHOD)
            fusedCooef.append((c1, c2, c3))  # 高频合并
    tempfusedImage = pywt.waverec2(fusedCooef, wavelet)  # 小波逆变换
    fusedImage = np.multiply(np.divide(tempfusedImage - np.min(tempfusedImage), (np.max(tempfusedImage) -\
                            np.min(tempfusedImage))), 255)  # 逆变换后归一至(0,255)
    start = time.time()
    fusedImage = fusedImage.astype(np.uint8)
    Yimg_new = fusedImage
    fusedYUV = cv2.merge([Yimg_new, YUVimg_base[:, :, 1], YUVimg_base[:, :, 2]])  # 用小波变换替换V通道
    end = time.time() - start
    print("图像重建:{}".format(end))
    fusedBGR = cv2.cvtColor(fusedYUV, cv2.COLOR_YUV2BGR)  # 融合后的HSV转为BGR
    return fusedBGR

4、总的代码

import cv2
import numpy as np
import pywt #引入小波模块
import time
from PIL import Image

# 裁剪线性RGB对比度拉伸:(去掉2%百分位以下的数,去掉98%百分位以上的数,上下百分位数一般相同,并设置输出上下限)
def truncated_linear_stretch(image, truncated_value=2, maxout=255, min_out=0):
    def gray_process(gray, maxout=maxout, minout=min_out):
        truncated_down = np.percentile(gray, truncated_value)
        truncated_up = np.percentile(gray, 100 - truncated_value)
        gray_new = ((maxout - minout) / (truncated_up - truncated_down)) * gray
        gray_new[gray_new < minout] = minout
        gray_new[gray_new > maxout] = maxout
        return np.uint8(gray_new)
    (b, g, r) = cv2.split(image)
    b = gray_process(b)
    g = gray_process(g)
    r = gray_process(r)
    result = cv2.merge((b, g, r))# 合并每一个通道
    return result

# RGB图片配准函数,采用白天的可见光与红外灰度图,计算两者Surf共同特征点,之间的仿射矩阵。
def Images_matching(img_base, img_target):
    img_base=cv2.cvtColor(img_base, cv2.COLOR_BGR2GRAY)
    img_target=cv2.cvtColor(img_target, cv2.COLOR_BGR2GRAY)
    hessian = 400
    # 初始化surf算子
    surf = cv2.xfeatures2d.SURF_create(hessian)
    # surf = cv2.xfeatures2d_SURF.create(hessian)
    # surf = cv2.SIFT_create(hessian)
    # 使用surf算子计算特征点和特征点周围的特征向量
    kp1, des1 = surf.detectAndCompute(img_base, None)  # 1136    1136, 64
    kp2, des2 = surf.detectAndCompute(img_target, None)
    # 进行KNN特征匹配
    FLANN_INDEX_KDTREE = 0  # 建立FLANN匹配器的参数
    indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)  # 配置索引,密度树的数量为5
    searchParams = dict(checks=50)  # 指定递归次数
    flann = cv2.FlannBasedMatcher(indexParams, searchParams)  # 建立匹配器
    matches = flann.knnMatch(des1, des2, k=2)  # 得出匹配的关键点  list: 1136
    good = []
    # 提取优秀的特征点
    for m, n in matches:
        if m.distance < 0.7 * n.distance:  # 如果第一个邻近距离比第二个邻近距离的0.7倍小,则保留
            good.append(m)   # 134
    src_pts = np.array([kp1[m.queryIdx].pt for m in good])  # 查询图像的特征描述子索引  # 134, 2
    dst_pts = np.array([kp2[m.trainIdx].pt for m in good])  # 训练(模板)图像的特征描述子索引
    H = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC)  # 生成变换矩阵  H[0]: 3, 3  H[1]: 134, 1
    return H[0]

# YUV通道小波变换RGB融合,低频均值高频最大值
def Images_fusion(img_base,img_target):          # 可见光,配准后的红外光
    # 按照不同的融合方式,计算通道融合
    def fuseCoeff(cooef1, cooef2, method):
        if (method == 'mean'):
            cooef = (abs(cooef1) + abs(cooef2)) / 2  # abs 绝对值
            # cooef=0.5*cooef1+1.5*cooef2
        elif (method == 'min'):
            cooef = np.minimum(cooef1, cooef2)
        elif (method == 'max'):
            cooef = np.maximum(abs(cooef1), abs(cooef2))
        return cooef
    # HSV的小波融合过程
    LOW_METHOD = 'mean'
    HIGH_METHOD = 'max'
    YUVimg_base = cv2.cvtColor(img_base, cv2.COLOR_BGR2YUV)  # 可见光转换为HSV
    # cv2.imwrite("D:/VS/vsprj/cuda/cudawavetest/2.jpg", YUVimg_base)
    grayimg_target = cv2.cvtColor(img_target, cv2.COLOR_BGR2GRAY)  #红外灰度化
    # cv2.imwrite("D:/VS/vsprj/cuda/cudawavetest/1.jpg",grayimg_target)
    Yimg_base = YUVimg_base[:, :, 0]  # 1024,1024
    wavelet = 'haar'
    cooef_base = pywt.wavedec2(Yimg_base[:, :], wavelet, level=1)  # base灰度图的小波展开  512, 512    3
    start = time.time()
    cooef_target = pywt.wavedec2(grayimg_target[:, :], wavelet, level=1)  # target灰度图的小波展开   512, 512    3
    end = time.time()-start
    print("小波展开:{}".format(end))
    fusedCooef = []
    for i in range(len(cooef_base)):
        if (i == 0):
            fusedCooef.append(fuseCoeff(cooef_base[0], cooef_target[0], LOW_METHOD))  # 低频部分取均值
        else:
            # 高频部分取最大值
            c1 = fuseCoeff(cooef_base[i][0], cooef_target[i][0], HIGH_METHOD)
            c2 = fuseCoeff(cooef_base[i][1], cooef_target[i][1], HIGH_METHOD)
            c3 = fuseCoeff(cooef_base[i][2], cooef_target[i][2], HIGH_METHOD)
            fusedCooef.append((c1, c2, c3))  # 高频合并
    tempfusedImage = pywt.waverec2(fusedCooef, wavelet)  # 小波逆变换
    fusedImage = np.multiply(np.divide(tempfusedImage - np.min(tempfusedImage), (np.max(tempfusedImage) -\
                            np.min(tempfusedImage))), 255)  # 逆变换后归一至(0,255)
    start = time.time()
    fusedImage = fusedImage.astype(np.uint8)
    Yimg_new = fusedImage
    fusedYUV = cv2.merge([Yimg_new, YUVimg_base[:, :, 1], YUVimg_base[:, :, 2]])  # 用小波变换替换V通道
    end = time.time() - start
    print("图像重建:{}".format(end))
    fusedBGR = cv2.cvtColor(fusedYUV, cv2.COLOR_YUV2BGR)  # 融合后的HSV转为BGR
    return fusedBGR
#
def main():
    matchimg_di = cv2.imread('images/oripics/basic_day_infrared.jpg')  # 1080, 1920, 3
    matchimg_dv = cv2.imread('images/oripics/basic_day_visual.jpg')
    # matchimg_di = cv2.imread('left_2020_11_30-15_15_31.jpg')  # 1080, 1920, 3
    # matchimg_dv = cv2.imread('right_2020_11_30-15_15_31.jpg')
    # 1080, 1920, 3
    orimg_nv=matchimg_dv
    orimg_ni=matchimg_di
    # orimg_nv = cv2.imread('images/oripics/night_visual_40m.jpg')
    # orimg_ni = cv2.imread('images/oripics/night_infrared_40m.jpg')
    # orimg_nv = cv2.imread('images/oripics/left_2020_11_30-20_06_54.jpg')
    # orimg_ni = cv2.imread('images/oripics/right_2020_11_30-20_06_54.jpg')
    # orimg_nv = cv2.imread('images/oripics/left_2020_11_30-20_08_09.jpg')
    # orimg_ni = cv2.imread('images/oripics/right_2020_11_30-20_08_09.jpg')
    orimg_nv = cv2.imread('images/oripics/left_video_2020_11_30-20_09_32_73.jpg')  # 1024, 1024, 3
    orimg_ni = cv2.imread('images/oripics/right_video_2020_11_30-20_09_32_73.jpg')  # 1024, 1024, 3

    #用白天图像进行配准
    # enhance_matchimg_di = truncated_linear_stretch(matchimg_di)# 配准模板红外图像RGB增强
    h, w = orimg_nv.shape[:2]   # 1024 1024
    H = Images_matching(matchimg_dv, matchimg_di)   # (3, 3)

    # enhance_orimg_ni=truncated_linear_stretch(orimg_ni) # 需融合红外图像RGB增强
    matched_ni = cv2.warpPerspective(orimg_ni, H, (w, h))
    cv2.imwrite("./1.jpg",matched_ni)# 红外图像按照仿射矩阵配准 1024, 1024, 3
    start = time.time()
    fusion = Images_fusion(orimg_nv, matched_ni)
    cv2.imwrite("./2.jpg",fusion)
    end = time.time()-start
    print(end)
    # enhance=truncated_linear_stretch(fusion)#融合图像RGB增强

    # cv2.imshow('0', cv2.resize(orimg_nv, (600, 400)))
    # cv2.imshow('1', cv2.resize(orimg_ni, (600, 400)))
    cv2.imshow('2', cv2.resize(fusion, (1200, 800)))
    cv2.waitKey(0)

    # name_fusionfile='YUV_04.jpg'
    # path_fusionfile='images/fusion/'+name_fusionfile
    # cv2.imwrite(path_fusionfile, fusion)
if __name__ == '__main__':
    main()    

5、融合效果 上图

红外:
基于小波变换的图像融合(附加视频融合)代码
可见光:
基于小波变换的图像融合(附加视频融合)代码

融合后,效果一般,但是将就看吧,熟悉一下融合过程。基于小波变换的图像融合(附加视频融合)代码

三、视频融合

一个可见光摄像头,一个红外摄像头,就可以实现实时夜间车外图像融合啦

video_path_infrared = "../videos/ir/video_2020_11_30-20_05_30.avi"
    video_path_visible = "../videos/vi/video_2020_11_30-20_05_30.avi"
    video_save_path = "../videos/out.avi"
    video_fps = 25

    # matchimg_di = cv2.imread('images/oripics/basic_day_infrared.jpg')  # 1080, 1920, 3
    # matchimg_dv = cv2.imread('images/oripics/basic_day_visual.jpg')
    matchimg_di = cv2.imread('left_2020_11_30-15_15_31.jpg')  # 1080, 1920, 3
    matchimg_dv = cv2.imread('right_2020_11_30-15_15_31.jpg')
    H = Images_matching(matchimg_dv, matchimg_di)

    capture_in = cv2.VideoCapture(video_path_infrared)
    capture_vi = cv2.VideoCapture(video_path_visible)
    if video_save_path != "":
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        size = (int(capture_vi.get(cv2.CAP_PROP_FRAME_WIDTH)), int(capture_vi.get(cv2.CAP_PROP_FRAME_HEIGHT)))
        out = cv2.VideoWriter(video_save_path, fourcc, video_fps, size)

    fps = 0.0
    while (True):
        t1 = time.time()
        # 读取某一帧
        ref1, frame1 = capture_in.read()
        ref2, frame2 = capture_vi.read()
        # 格式转变,BGRtoRGB
        frame1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2RGB)
        frame2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
        # 转变成Image
        # frame1 = Image.fromarray(np.uint8(frame1))
        # frame2 = Image.fromarray(np.uint8(frame2))
        h, w = frame1.shape[:2]
        matched_ni = cv2.warpPerspective(frame2, H, (w, h))
        cv2.imwrite("./1.jpg", matched_ni)
        # 进行检测
        fusion = Images_fusion(frame1, matched_ni)
        fusion = np.array(fusion)
        end = time.time() - t1
        # RGBtoBGR满足opencv显示格式
        frame = cv2.cvtColor(fusion, cv2.COLOR_RGB2BGR)

        fps = (fps + (1. / end )) / 2
        print("fps= %.2f" % (fps))
        frame = cv2.putText(frame, "fps= %.2f" % (fps), (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

        cv2.imshow("video", frame)
        c = cv2.waitKey(1) & 0xff
        if video_save_path != "":
            out.write(frame)

        if c == 27:
            capture.release()
            break
    capture.release()
    out.release()
    cv2.destroyAllWindows()

一定选对配准图片,不然会出现鬼影

四、总结

这个方法试出来视频融合的时候如何加速,大家如果有什么好方法,多教教我!文章来源地址https://www.toymoban.com/news/detail-420525.html

到了这里,关于基于小波变换的图像融合(附加视频融合)代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于小波变换的同步压缩变换原理和Matlab代码

    作为处理非平稳信号的有力工具,时频分析在时域和频域联合表征信号,是时间和频率的二元函数。传统的时频分析工具主要分为线性方法和二次方法。线性方法受到海森堡测不准原理的制约,二次方法存在交叉项的干扰。 为了提升时频聚集性,逼近理想的时频表示,时频重

    2024年02月16日
    浏览(42)
  • 图像处理01 小波变换

    连续小波分解,通过改变分析窗口大小,在时域上移动窗口和基信号相乘,最后在全时域上整合。通过离散化连续小波分解可以得到 伪离散小波分解, 这种离散化带有大量冗余信息且计算成本较高。 小波变换的公式如下: ​ ​​ ​​ ​ ​ 更直观的可以用下面的图片来表

    2024年02月05日
    浏览(38)
  • (数字图像处理MATLAB+Python)第四章图像正交变换-第四、五节:Radon变换和小波变换

    Radon变换 :是一种用于将图像从空间域转换到投影域的数学工具,其基本思想是将图像中每个点的灰度值投影到一组直线上,然后将这些投影合并在一起形成投影域。Radon变换可以用于多种图像处理任务,包括图像重建、特征提取、图像分割等 Radon变换原理 :给定一个函数

    2023年04月20日
    浏览(50)
  • 【youcans 的图像处理学习课】21. Haar 小波变换

    专栏地址:『youcans 的图像处理学习课』 文章目录:『youcans 的图像处理学习课 - 总目录』 1.1 小波变换基本概念 信号变换是为了分析时间和频率之间的相互关系。 傅里叶变换(FFT)将信号表示为无限三角函数的叠加,从而将信号从时域转换到频域,可以分析信号的频谱,但

    2024年02月05日
    浏览(36)
  • 从傅里叶变换到小波变换详细解释(含代码)

    傅里叶变换能够将一个信号从时域转换为频域,在转换后的频谱中,频谱的峰值越大越尖,表示对应频率的信号就强度就越大。 傅里叶变换能够处理不随时间变化的平稳信号,即它能告诉我们信号包含哪些频段,但是不能告诉我们这个频段是在信号的哪个时间段出现的。而生

    2024年01月21日
    浏览(47)
  • 基于小波变换的信号分离

    使用小波变换将信号进行分离。验证小波变换在信号处理中的有效性。 小波变换是一种非常重要的信号处理方法,可以将信号分解成不同频率的小波成分,从而进行信号的分析和处理。小波变换是一种具有局部性质的信号分析方法,它将信号分解成一组基函数,这些基函数是

    2024年02月11日
    浏览(39)
  • 【M波段2D双树(希尔伯特)小波多分量图像去噪】基于定向M波段双树(希尔伯特)小波对多分量/彩色图像进行降噪研究(Matlab代码实现)

     💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 本文实

    2024年02月13日
    浏览(45)
  • 医学影像图像去噪:滤波器方法、频域方法、小波变换、非局部均值去噪、深度学习与稀疏表示和字典学习

            医学影像图像去噪是指使用各种算法从医学成像数据中去除噪声,以提高图像质量和对疾病的诊断准确性。MRI(磁共振成像)和CT(计算机断层扫描)是两种常见的医学成像技术,它们都会受到不同类型噪声的影响。         在医学影像中,噪声可能来源于多

    2024年04月26日
    浏览(41)
  • 135基于matlab的经验小波变换(EWT)的自适应信号处理方法

    基于matlab的经验小波变换(EWT)的自适应信号处理方法.其核心思想是通过对信号的Fourier谱进行自适应划分,建立合适的小波滤波器组来提取信号不同的成分,EWT1D和EWT2D方法。程序已调通,可直接运行。 135matlab信号处理EWT (xiaohongshu.com)

    2024年01月17日
    浏览(43)
  • 从傅里叶变换,到短时傅里叶变换,再到小波分析(CWT),看这一篇就够了(附MATLAB傻瓜式实现代码)

    本专栏中讲了很多时频域分析的知识,不过似乎还没有讲过时频域分析是怎样引出的。 所以本篇将回归本源,讲一讲从傅里叶变换→短时傅里叶变换→小波分析的过程。 为了让大家更直观得理解算法原理和推导过程,这篇文章将主要使用图片案例。 频谱分析可以告诉我们一

    2024年01月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包