OpenCV的TIF红外可见光融合算法

一、简介

首先TIF是Two-Scale Image Fusion的缩写,论文《Two-Scale Image Fusion of Infrared and Visible Images Using Saliency Detection (TIF)》,作者在论文中提到TIF算法主要通过以下三个步骤实现融合:

  1. 图像分解,图像分解使用的是均值滤波器获取图像的基础(base)和细节(detail)层;

  2. 图像融合,对待基础和细节层分别使用不同的融合算法;

  3. 图像重建,从融合后的基础和细节层重建图像。
    在这里插入图片描述

二、详细介绍

2.1 图像分解

考虑到原始的同样大小(宽高)两幅图像ϕ1(x,y)\phi_{1}(x,y)ϕ1(x,y) , ϕ2(x,y)\phi_{2}(x,y)ϕ2(x,y),将这两幅图像分解为基础层(base)和细节(detail)层,作者在文中使用了均值滤波器来生成基础层和细节层(文中作者通过验证,使用的均值滤波窗口大小为35)。

ϕ1B(x,y)=ϕ1(x,y)∗μ(x,y)\phi_{1}^{B}(x, y)=\phi_{1}(x, y) * \mu(x, y)ϕ1B(x,y)=ϕ1(x,y)μ(x,y)

ϕ2B(x,y)=ϕ2(x,y)∗μ(x,y)\phi_{2}^{B}(x, y)=\phi_{2}(x, y) * \mu(x, y)ϕ2B(x,y)=ϕ2(x,y)μ(x,y)

在得到基础层之后,通过原始图像与基础层图像得到细节层图像。

ϕ1D(x,y)=ϕ1(x,y)−ϕ1B(x,y)\phi_{1}^{D}(x, y)=\phi_{1}(x, y) - \phi_{1}^{B}(x, y)ϕ1D(x,y)=ϕ1(x,y)ϕ1B(x,y)

ϕ2D(x,y)=ϕ2(x,y)∗ϕ2B(x,y)\phi_{2}^{D}(x, y)=\phi_{2}(x, y) * \phi_{2}^{B}(x, y)ϕ2D(x,y)=ϕ2(x,y)ϕ2B(x,y)

基于可视显著检测理论,作者在文中使用了一种很有效的可视显著检测方法,就是用均值滤波(作者通过验证,使用的中值窗口大小为3)得到的图像减去中值滤波得到的图像,并取绝对值。
在这里插入图片描述

ξ(x,y)=∣ϕu(x,y)−ϕη(x,y)∣\xi(x,y)=|\phi_u(x,y)-\phi_\eta(x,y)|ξ(x,y)=ϕu(x,y)ϕη(x,y)

如果是RGB图像的话,使用L2-norm或欧拉距离的方法:

ξ(x,y)=de(ϕu,ϕη)=(ϕuR−ϕηR)2+(ϕuG−ϕηG)2+(ϕuB−ϕηB)2\xi(x,y)=de(\phi_u,\phi_\eta)=\sqrt{(\phi_u^R-\phi_\eta^R)^2+(\phi_u^G-\phi_\eta^G)^2+(\phi_u^B-\phi_\eta^B)^2}ξ(x,y)=de(ϕu,ϕη)=(ϕuRϕηR)2+(ϕuGϕηG)2+(ϕuBϕηB)2
对于原始的输入图像ϕ1(x,y)\phi_{1}(x,y)ϕ1(x,y) , ϕ2(x,y)\phi_{2}(x,y)ϕ2(x,y),通过分别计算可以得到ξ1(x,y)\xi_{1}(x,y)ξ1(x,y) , ξ2(x,y)\xi_{2}(x,y)ξ2(x,y)通过这两个矩阵,得到detail层的融合系数矩阵。

ψ1(x,y)=ξ1(x,y)ξ1(x,y)+ξ2(x,y)\psi_1(x,y)=\frac{\xi_1(x,y)}{\xi_1(x,y)+\xi_2(x,y)}ψ1(x,y)=ξ1(x,y)+ξ2(x,y)ξ1(x,y)

ψ2(x,y)=ξ2(x,y)ξ1(x,y)+ξ2(x,y)\psi_2(x,y)=\frac{\xi_2(x,y)}{\xi_1(x,y)+\xi_2(x,y)}ψ2(x,y)=ξ1(x,y)+ξ2(x,y)ξ2(x,y)

2.2 图像融合

基础层的融合,使用平均的策略进行融合:
ϕB(x,y)=12(ϕ1B(x,y)+ϕ2B(x,y))\phi^B(x,y)=\frac{1}{2}(\phi_1^B(x,y)+\phi_2^B(x,y))ϕB(x,y)=21(ϕ1B(x,y)+ϕ2B(x,y))
细节层的融合,使用加权平均的策略进行融合,二加权矩阵就是之前求得的ψ1(x,y)\psi_1(x,y)ψ1(x,y),ψ2(x,y)\psi_2(x,y)ψ2(x,y)

ϕD(x,y)=ψ1(x,y)ϕ1D(x,y)+ψ2(x,y)ϕ2D(x,y)\phi^D(x,y)=\psi_1(x,y)\phi_1^D(x,y)+\psi_2(x,y)\phi_2^D(x,y)ϕD(x,y)=ψ1(x,y)ϕ1D(x,y)+ψ2(x,y)ϕ2D(x,y)

2.3 图像重建

在得到基础层和细节层之后,通过简单的加法多基础层和细节层进行融合:

γ(x,y)=ϕB(x,y)+ϕD(x,y)\gamma(x,y)=\phi^B(x,y)+\phi^D(x,y)γ(x,y)=ϕB(x,y)+ϕD(x,y)

三、python实现

import numpy as np
import cv2
import argparse

def TIF_GRAY(img_r, img_v):
    img_r_blur = cv2.blur(img_r, (35,35))
    img_v_blur = cv2.blur(img_v, (35,35))
    img_r_median = cv2.medianBlur(img_r, 3)
    img_v_median = cv2.medianBlur(img_v, 3)
    img_r_detail = img_r*1. - img_r_blur*1.
    img_v_detail = img_v*1. - img_v_blur*1.
    img_r_the = cv2.pow(cv2.absdiff(img_r_median,img_r_blur), 2)
    img_v_the = cv2.pow(cv2.absdiff(img_v_median ,img_v_blur),2)
    img_r_weight = cv2.divide(img_r_the*1.,img_r_the*1.+img_v_the*1.+0.000001)
    img_v_weight = 1- img_r_weight
    img_base_fused = (img_r_blur*1.  + img_v_blur*1.) / 2
    img_detail_fused = img_r_weight * img_r_detail + img_v_weight * img_v_detail
    img_fused_tmp = (img_base_fused  + img_detail_fused).astype(np.int32)
    #first method to change <0 to 0 and > 255 to 255
    img_fused_tmp[img_fused_tmp<0] = 0
    img_fused_tmp[img_fused_tmp>255]=255
    #second method to change value to[0,255] using minmax method
    #cv2.normalize(img_fused_tmp,img_fused_tmp,0,255,cv2.NORM_MINMAX)
    img_fused = cv2.convertScaleAbs(img_fused_tmp)
    return img_fused
    

def TIF_RGB(img_r, img_v):
    fused_img = np.ones_like(img_r)
    r_R = img_r[:,:,2]
    v_R = img_v[:,:,2]
    r_G = img_r[:,:,1]
    v_G = img_v[:,:,1]
    r_B = img_r[:,:,0]
    v_B = img_v[:,:,0]
    fused_R = TIF_GRAY(r_R, v_R)
    fused_G = TIF_GRAY(r_G, v_G)
    fused_B = TIF_GRAY(r_B, v_B)
    fused_img[:,:,2] = fused_R
    fused_img[:,:,1] = fused_G
    fused_img[:,:,0] = fused_B
    return fused_img



def TIF(_rpath, _vpath):
    img_r = cv2.imread(_rpath)
    img_v = cv2.imread(_vpath)
    if not isinstance(img_r, np.ndarray) :
        print('img_r is null')
        return
    if not isinstance(img_v, np.ndarray) :
        print('img_v is null')
        return
    if img_r.shape[0] != img_v.shape[0]  or img_r.shape[1] != img_v.shape[1]:
        print('size is not equal')
        return
    fused_img = None
    if len(img_r.shape)  < 3 or img_r.shape[2] ==1:
        if len(img_v.shape)  < 3 or img_v.shape[-1] ==1:
            fused_img = TIF_GRAY(img_r, img_v)
        else:
            img_v_gray = cv2.cvtColor(img_v, cv2.COLOR_BGR2GRAY)
            fused_img = TIF_GRAY(img_r, img_v)
    else:
        if len(img_v.shape)  < 3 or img_v.shape[-1] ==1:
            img_r_gray = cv2.cvtColor(img_r, cv2.COLOR_BGR2GRAY)
            fused_img = TIF_GRAY(img_r_gray, img_v)
        else:
            fused_img = TIF_RGB(img_r, img_v)
    cv2.imshow('fused image', fused_img)
    cv2.imwrite("fused_image_tif.jpg", fused_img)
    cv2.waitKey(0)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-r', type=str, default='ir.png' ,help='input IR image path', required=False)
    parser.add_argument('-v', type=str, default= 'vr.png',help='input Visible image path', required=False)
    args = parser.parse_args()
    TIF(args.r, args.v)

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深图智能

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

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

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

打赏作者

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

抵扣说明:

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

余额充值