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

ϕ 1 B ( 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)

ϕ 2 B ( 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)

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

ϕ 1 D ( x , y ) = ϕ 1 ( x , y ) − ϕ 1 B ( 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)

ϕ 2 D ( x , y ) = ϕ 2 ( x , y ) ∗ ϕ 2 B ( 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 ) = d e ( ϕ u , ϕ η ) = ( ϕ u R − ϕ η R ) 2 + ( ϕ u G − ϕ η G ) 2 + ( ϕ u B − ϕ η 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 ) = 1 2 ( ϕ 1 B ( x , y ) + ϕ 2 B ( 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 ) ϕ 1 D ( x , y ) + ψ 2 ( x , y ) ϕ 2 D ( 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实现

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)
相关推荐
KeyPan1 分钟前
【机器学习:十四、TensorFlow与PyTorch的对比分析】
人工智能·pytorch·python·深度学习·机器学习·计算机视觉·分类
cdut_suye4 分钟前
基于Linux环境的进度条实现
linux·运维·服务器·数据库·人工智能·深度学习·中间件
一叶祇秋7 分钟前
Leetcode - 周赛430
算法·leetcode·职场和发展
青春~飞鸟8 分钟前
再次梳理ISP的大致流程
图像处理·人工智能·计算机视觉
最 上 川13 分钟前
西电-神经网络基础与应用-复习笔记
人工智能·笔记·神经网络
凡人的AI工具箱23 分钟前
每日学习30分轻松掌握CursorAI:Cursor基础设置与配置
python·学习·ai·aigc·ai编程·cursor
孟芳芳1 小时前
JAVA 冒泡排序算法
java·算法
快乐非自愿1 小时前
C++中的各种锁
java·c++·算法
dot to one1 小时前
C语言数据结构与算法(排序)详细版
c语言·数据结构·算法·排序算法
打不了嗝 ᥬ᭄1 小时前
DFS与BFS
算法·深度优先·图论·宽度优先