【去除红外图像竖条纹噪声】

介绍

红外热像仪在采集图像时由于ADC、放大电路、读出电路的影响,会产生非均匀的竖条纹噪声,大部分人的做法是对红外机芯做标定,也就是两点校正和单点校正。
但是也存在校正后还会出现竖条纹噪声的情况,可能是由于硬件性能的影响,或者是温漂的影响,再或者是被摄物体温度范围超出标定范围,积分时间不匹配等等原因。
出现竖条纹噪声会影响使用者的观感,一般会采用单点校正来使画面变得均匀,但毕竟单点校正只对像元变化的偏置做改变,而没有对斜率还是之前的,所以再换环境后依旧会出现竖条纹。当然也可以使用基于场景的非均匀校正,已经有好多人介绍过了。
我看到Effective Strip Noise Removal for Low-Textured Infrared Images Based on 1-D Guided Filtering这篇文章,就尝试用python实现了一下

在这里插入图片描述

python实现一维引导滤波去除竖条纹

对8bit的红外图像进行竖条纹噪声去除

#定义函数
import numpy as np
import cv2
import matplotlib.pyplot as plt
def Normalize_img(img):
    min_n = np.min(img)
    max_n = np.max(img)
    Normalize_image = ((img-min_n)/(max_n-min_n))
    return Normalize_image
def guideFilter(I, p, winSize, eps):
    mean_I = cv2.blur(I, winSize)      # I的均值平滑
    mean_p = cv2.blur(p, winSize)      # p的均值平滑
    mean_II = cv2.blur(I * I, winSize) # I*I的均值平滑
    mean_Ip = cv2.blur(I * p, winSize) # I*p的均值平滑
    var_I = mean_II - mean_I * mean_I  # 方差
    cov_Ip = mean_Ip - mean_I * mean_p # 协方差
    a = cov_Ip / (var_I + eps)         # 相关因子a
    b = mean_p - a * mean_I            # 相关因子b
    mean_a = cv2.blur(a, winSize)      # 对a进行均值平滑
    mean_b = cv2.blur(b, winSize)      # 对b进行均值平滑as
    q = mean_a * I + mean_b
    return q

进行行列的一维引导滤波

image = cv2.imread(r'test.bmp', cv2.COLOR_BGR2GRAY)
image= image[:, :, 0]
plt.figure(figsize=(5, 5))
plt.imshow(image,cmap="gray")
#-----------------------------------------------------------#
row_guideFilter_img=np.zeros((len(image),len(image[0])))
col_guideFilter_img=np.zeros(((len(image),len(image[0]))))
#-------------------行-----------------------------------#
I = image/255.0        #将图像归一化    
p =I
eps =20
winSize = (9,1)
row_guideFilter_img = guideFilter(I, p, winSize, eps)
row_guideFilter_img =  p-row_guideFilter_img
plt.figure(figsize=(5, 5))
plt.imshow(row_guideFilter_img,cmap="gray")
#------------------列------------------------------------#
eps =20
winSize = (1,15)
guideFilter_img_lie = guideFilter(p ,row_guideFilter_img, winSize, eps)
col_guideFilter_img=p-guideFilter_img_lie
guideFilter_img_lie = Normalize_img(guideFilter_img_lie)
plt.figure(figsize=(5, 5))
plt.imshow(guideFilter_img_lie,cmap="gray")
#---------------还原为8bit------------------------------#
col_guideFilter_img  = Normalize_img(col_guideFilter_img)  * 255
col_guideFilter_img [col_guideFilter_img  > 255] = 255
col_guideFilter_img  = np.round(col_guideFilter_img )
final_img  = col_guideFilter_img.astype(np.uint8)

plt.figure(figsize=(5, 5))
plt.imshow(final_img,cmap="gray")

结果

原图:
原图
行滤波:
行
列滤波提取竖条纹噪声:
列
去除竖条纹:
结果

保留竖边信息

可以看到处理完的图片完全没有了竖条纹,但同时也竖边细节也没有了,所以作者用sobel提取了图像中竖边细节信息,在一维引导滤波的时候将判断为细节的竖条纹保留下来了。我也尝试了一下,有一点效果,但不知道是不是理解的不对,结果没那么明显。可能还要再调调参数?

//提取竖条纹细节,参数固定了,要改自己改
def shuDetail(img):
    img_blur = cv2.GaussianBlur(img, (11, 55), 0)
    # x梯度
    xgrad = cv2.Sobel(img_blur, cv2.CV_16SC1, 1, 0)
    # y梯度
    ygrad = cv2.Sobel(img_blur, cv2.CV_16SC1, 0, 1)
    edge1 = cv2.Canny(xgrad, ygrad, 9,50)
    return edge1

sobel提取的竖边信息:
sobel

加一段这个,也可能不对,仅供参考吧

img_shu = shuDetail(image)
guideFilter_img_shu = guideFilter(I, img_shu, winSize, eps)
guideFilter_img_shu =  I-guideFilter_img_shu
guideFilter_img_shu = Normalize_img(guideFilter_img_shu)
plt.figure(figsize=(5, 5))
plt.imshow(guideFilter_img_hang+guideFilter_img_shu,cmap="gray")
row_guideFilter_img = guideFilter_img_hang+guideFilter_img_shu

没加sobel提取细节:
在这里插入图片描述
有竖边细节:
在这里插入图片描述

其他图片尝试

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

讨论

感觉有效果,但被滤掉的竖边细节确实不好恢复,滤波完的图像亮度对比度都会变低,可以再用直方图均衡一下,也可以用细节增强再增强一下边缘。
这个方法在8bit红外图像的处理中还可以,我也尝试了16bit图像,直接处理的话调整参数后,再动态范围压缩和细节增强,在竖条纹噪声不强时是有些用的。但还是转为8bit再用可能更明显一点

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值