红外小目标检测

目录

  • 背景
  • 概述
  • 算法原理
      • 演示效果
      • 核心逻辑
    • 使用方式
      • 基础镜像
      • 配置环境
      • 直接运行
    • 参考文献


  • 文章声明,非广告,仅个人体验。

背景

  • 红外图像在许多领域中都有所应用。例如军事领域中,经常需要通过红外成像设备对远距离的目标进行侦察和监视,如复杂背景下的无人机、导弹之类的物体。此外,航空航天领域中也需要通过红外传感器检测地面或海上的船只、车辆等等。这些需要检测的物体在红外图像中通常都是以不超过7X7像素大小的小目标呈现。在实际应用时,我们一般不需要区分这些物体的形状或纹理,而只需区分图像中是否有这些物体(有时对其检测位置及大小也有一定要求)以及时采取相应的措施,这就是红外小目标检测的应用场景。 在真实的应用场景中,这样的单帧红外图像短时间内就可能产生相当大的数量,如果人为一张张查看会耗费相当大的人力,所以一个能够自动检测出红外小目标的算法就显得相当有意义。

  • 不同于自然图像,红外图像中的物体因为拍摄距离较远通常以小目标呈现,加之受各种因素的干扰,如环境因素(无人机可能受到雾或是云层的干扰)与设备自身因素(传感器不可避免地引入噪声)等,使得红外小目标淹没在各种复杂的背景中,检测具有相当的难度。本文复现的方法就是致力于实现高效的红外小目标检测。

  • 参考文献:https://www.aspiringcode.com/content?id=17194033422039&uid=e0d52bade2d0497f9cf268db47231b67

概述

本文用python复现论文Infrared Small Target Detection Based on Facet Kernel and Random Walker中提出的红外小目标检测算法。原文连接https://ieeexplore.ieee.org/abstract/document/8705367

该论文提出了一种针对红外图像中小目标检测的算法。在红外小目标检测方面优于其之前的所有传统方法并且为后续传统的红外小目标检测算法打下了良好的基础。

该方法作为非深度学习方法,基于滤波与图论的思想来对红外小目标进行检测。所以其对算力几乎没有任何要求,且性能也足够优秀。其提出的检测与分割的策略与指标为后续许多相关论文所借鉴。

从展示结果可以看出,该算法可以将红外图像中位于云层背景干扰下的微小目标精确地检测并分割出来,这是其他传统方法难以实现的。

算法原理

检测流程中图像的变化
在这里插入图片描述

  • 1.均值滤波与次序统计滤波2 × 2的均值滤波用于平滑图像来降低噪声等级,为后续RandomWalker算法的使用创造一个低噪声空间,此外次序统计滤波被使用来去除一部分图像中的单点高亮噪声。假设原图像为I,此步骤之后的图像被称为增强图像M对应流程中的(b)。

在这里插入图片描述
在这里插入图片描述
u为MF​ 的均值,σ为其标准差,本次实现中参考官方论文的默认值设为4。
分割后的图像对应流程中的(d)。可以看到,这样的粗检无法避免云层中背景杂波的干扰。

  • 3.RandomWalker算法分割
    对于(d)图中的候选目标像素,依次设置为一个11 ×× 11邻域的中心,在对应原图的这个11 ×× 11的邻域内,中心像素设为目标,周围一圈设为背景,如下图所示:

在这里插入图片描述
目标种类标为1,背景标为2。RndomWalker算法会根据未标记像素与标记像素的灰度相似程度来自动对未标记像素进行分割。利用RandomWlaker算法进行分割并得到邻域内所有像素属于目标类的概率值,大于等于0.5的设为目标类,小于0.5的设为背景类。
至此,检测本可以结束。但本文提出了两个特异性指标来进一步优化检测与分割结果。即:

在这里插入图片描述
公式的意思是如果邻域内中心像素不在分割的目标区域内部即将此指标设为0,否则就设为一个概率值。这个概率值是这样获得的,将邻域内非中心像素而被分割为目标像素的那些像素所属目标类的概率值取平均作为分子,被分为背景像素的那些像素所属目标类的概率值取平均作为分母。这个指标在目标区域明显会大于背景区域。,具体来说它用于区分以下情况:
在这里插入图片描述
(a1)是真正的目标区域,而(a2)是背景区域,但由于中心较亮,其也存在被分为目标区域的像素。此指标的值在(a1)会远大于(a2)从而区分这两种情况,找出真正的目标区域。
在这里插入图片描述
这个公式的意思是,如果邻域中被分为背景区域的像素的灰度值的最大值大于等于被分为目标区域像素的平均灰度值,就将该指标设为0,否则就设为目标区域灰度值的平均值除以背景区域灰度的最大值。这个指标用于进一步去除单点高亮噪声被错误分为目标区域的情况。具体来说,单点高亮噪声所处的邻域中,这个值的计算应当为0.最终将两个指标相乘,即
在这里插入图片描述

演示效果

在这里插入图片描述

核心逻辑

def visual_attention_rw(img,k):
    #FacetKernel滤波
    img = img.astype(np.float64) / 255.0


    # Step 2: Define the filter
    h = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]])

    # Step 3: Apply the rank filter
    img_1 = rank_filter(img, rank=7, footprint=h)

    # Step 4: Calculate the ratio
    con_idx = img / img_1

    # Step 5: Create a mask
    tmp = np.ones_like(img)
    tmp[con_idx > 1] = 0

    # Step 6: Combine the images
    img = img * tmp + img_1 * (1 - tmp)

    h = np.ones((2, 2)) / 4

    img_filtered= convolve(img, h, mode='nearest')

    img=img_filtered

    im = img.copy()

    L = np.array([
        [-4, -1, 0, -1, -4],
        [-1, 2, 3, 2, -1],
        [0, 3, 4, 3, 0],
        [-1, 2, 3, 2, -1],
        [-4, -1, 0, -1, -4]
    ])

    im_mirrored = mirror_matrix(im, 3)

    img_dog = convolve2d(im_mirrored, L, mode='valid')

    #探测
    Th = np.mean(img_dog) + k * np.sqrt(np.var(img_dog))

    # 创建与 img_dog 相同大小的全 1 数组
    img_idx = np.ones_like(img_dog)

    # 将 img_dog 中小于阈值 Th 的位置设为 0
    img_idx[img_dog < Th] = 0

    # 创建 out1 并将 img_dog 中小于阈值 Th 的部分设为 0
    out1 = img_dog.copy()
    out1[img_dog < Th] = 0

    # 对 out1 进行归一化,防止除以零
    out1 = out1 / (np.max(out1) + 1e-6)

    patch=11
    p=(patch+1)//2
    im_m=mirror_matrix(im,p)

    im_out = np.zeros_like(im_m)
    out2 = im_out.copy()
    out3 = im_out.copy()
    p_idx_r, p_idx_c = np.where(img_idx == 1)

    im_v = im[img_idx == 1]

    I = np.argsort(-im_v)

    p_idx_r = p_idx_r[I]
    p_idx_c = p_idx_c[I]

    FLAG = np.zeros_like(im_out)
    patch_half = (patch - 1) // 2
    for i in range(len(p_idx_r)):
        r_pos = int(p_idx_r[i] + (patch - 1) //2)
        c_pos = int(p_idx_c[i] + (patch - 1) // 2)
        if FLAG[r_pos, c_pos] == 1:
            continue

        # 提取图像块
        img = im_m[r_pos - patch_half: r_pos + patch_half + 1,c_pos - patch_half: c_pos + patch_half + 1]

        X, Y = img.shape

        # 计算 s1x 和 s1y
        s1x = int((patch + 1) / 2)-1
        s1y = int((patch + 1) / 2)-1

        # 复制 img 并设置边界
        img_2 = img.copy()
        img_2[:, 0] = 1
        img_2[:, -1] = 1
        img_2[0, :] = 1
        img_2[-1, :] = 1

        idx = np.flatnonzero(img_2 == 1)

        # 将 idx 转换为 double 类型(与 MATLAB 类型相似)
        idx = idx.astype(float)
        markers= np.zeros_like(img)
        markers[:, 0] = 2
        markers[:, -1] = 2
        markers[0, :] = 2
        markers[-1, :] = 2
        markers[s1x,s1y]=1
        mask=random_walker(img, markers,mode='bf',beta=200)
        proba = random_walker(img, markers,mode='bf', return_full_prob=True,beta=200)
        prob_t=proba[0,:,:]

        if np.sum(mask == 1) == 1:
            # 将 im_out 数组在位置 (r_pos, c_pos) 处的值设为 0
            im_out[r_pos, c_pos] = 0
            # 将 FLAG 数组在位置 (r_pos, c_pos) 处的值设为 1
            FLAG[r_pos, c_pos] = 1
            # 跳过当前循环的剩余部分,继续下一次循环
            continue

        mask[s1x, s1y] = 2

        # 计算 prob_t 数组中对应 mask 中等于 1 的位置的均值
        prob_res = np.mean(prob_t[mask == 1])

        # 计算 prob_t 数组中对应 mask 中不等于 1 的位置的均值
        # 并将 prob_res 除以这个均值
        prob_res = prob_res / np.mean(prob_t[mask != 1])

        # 将 mask 数组在位置 (s1x, s1y) 处的值重新设为 1
        mask[s1x, s1y] = 1

        inten_res=local(mask,img)

        idx_r, idx_c = np.where(mask == 1)
        patch_half = (patch - 1) // 2

        for j in range(len(idx_r)):
            r_idx = r_pos - patch_half + idx_r[j] - 1
            c_idx = c_pos - patch_half + idx_c[j] - 1

            if FLAG[r_idx, c_idx] == 1:
                continue

            im_out[r_idx, c_idx] = prob_res * inten_res ** 6
            out2[r_idx, c_idx] = prob_res
            out3[r_idx, c_idx] = inten_res ** 6
            FLAG[r_idx, c_idx] = 1

    out2 = out2[patch_half:-patch_half, patch_half:-patch_half]
    out3 = out3[patch_half:-patch_half, patch_half:-patch_half]

    out2 = out2 / (np.max(out2) + 1e-6)
    out3 = out3 / (np.max(out3) + 1e-6)

    im_out = im_out[patch_half:-patch_half, patch_half:-patch_half]
    im_out = im_out * img_dog
    im_out = im_out / (np.max(im_out) + 1e-6)

    out4 = im_out

    return out4

使用方式

基础镜像

python:3.9.19

配置环境

解压后进入InfraredTargetDetection项目路径下
运行以下命令:

pip install -r requirements.txt

直接运行

python main.py

即可看到视频中示例图片的小目标检测效果。

更换图片运行或调整参数运行
修改main.py文件里的默认图片路径
在这里插入图片描述
将"data/rice.png"更改为你自己的图片路径即可。
调整参数,只需要去调整k=4即可,k越大该算法对目标的判定越严格。

参考文献

  • 参考文献:https://www.aspiringcode.com/content?id=17194033422039&uid=e0d52bade2d0497f9cf268db47231b67

  • [1] Qin Y, Bruzzone L, Gao C, et al. Infrared small target detection based on facet kernel and random walker[J]. IEEE Transactions on Geoscience and Remote Sensing, 2019, 57(9): 7104-7118.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/923563.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

hive的存储格式

1&#xff09; 四种存储格式 hive的存储格式分为两大类&#xff1a;一类纯文本文件&#xff0c;一类是二进制文件存储。 Hive支持的存储数据的格式主要有&#xff1a;TEXTFILE、SEQUENCEFILE、ORC、PARQUET 第一类&#xff1a;纯文本文件存储 textfile: 纯文本文件存储格式…

ReentrantLock(可重入锁) Semaphore(信号量) CountDownLatch

目录 ReentrantLock(可重入锁) &Semaphore(信号量)&CountDownLatchReentrantLock(可重入锁)既然有了synchronized&#xff0c;为啥还要有ReentrantLock?Semaphore(信号量)如何确保线程安全呢&#xff1f;CountDownLatch ReentrantLock(可重入锁) &Semaphore(信号量…

51单片机从入门到精通:理论与实践指南入门篇(二)

续51单片机从入门到精通&#xff1a;理论与实践指南&#xff08;一&#xff09;https://blog.csdn.net/speaking_me/article/details/144067372 第一篇总体给大家在&#xff08;全局&#xff09;总体上讲解了一下51单片机&#xff0c;那么接下来几天结束详细讲解&#xff0c;从…

STM32C011开发(2)----nBOOT_SEL设置

STM32C011开发----2.nBOOT_SEL设置 概述硬件准备视频教学样品申请源码下载参考程序自举模式BOOT0设置配置 nBOOT_SEL生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32CubeProgrammer (STM32CubeProg) 是一款用于编程STM32产品的全功能多操作系统软件工…

基于 AI 的软件工程: 超级程序员

徐昊 《AI时代的软件工程》-极客时间课程学习总结 帮助你更好地利用 LLM 提高效率,还可以站在一个更全面的立场上,讨论如何将 LLM 引入团队或是组织。 核心观点: AI 辅助业务建模:通过将模型转化为 Mermaid 格式,将我们的模型表达为大语言模型能够理解的形式。通过添加注…

【消息序列】详解(7):剖析回环模式--设备测试的核心利器

目录 一、概述 1.1. 本地回环模式 1.2. 远程环回模式 二、本地回环模式&#xff08;Local Loopback mode&#xff09; 2.1. 步骤 1&#xff1a;主机进入本地环回模式 2.2. 本地回环测试 2.2.1. 步骤 2a&#xff1a;主机发送HCI数据包并接收环回数据 2.2.2. 步骤 2b&…

如何使用GCC手动编译stm32程序

如何不使用任何IDE&#xff08;集成开发环境&#xff09;编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中&#xff0c;使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境&#xff0c;…

计算机网络 第4章 网络层

计算机网络 &#xff08;第八版&#xff09;谢希仁 第 4 章 网络层4.2.2 IP地址**无分类编址CIDR**IP地址的特点 4.2.3 IP地址与MAC地址4.2.4 ARP 地址解析协议4.2.5 IP数据报的格式题目2&#xff1a;IP数据报分片与重组题目&#xff1a;计算IP数据报的首部校验和(不正确未改) …

【Git】常用命令汇总

目录 一.安装及配置 1.在 Windows 上安装 2.用户信息 3.差异分析工具 二.基础 1.创建仓库 2.提交与修改 三.分支管理 1.创建分支 2.合并分支 四.远程操作 1.管理 Git 仓库中的远程仓库 2.数据的获取与推送 五.标签 1.创建轻量标签和附注标签 2.查看标签和标签信…

jvm核心组件介绍

1. 类加载器&#xff08;ClassLoader&#xff09;&#xff1a; • 想象它是一个快递员&#xff0c;负责把Java类&#xff08;.class文件&#xff09;这个“包裹”从磁盘这个“发货地”送到JVM内部这个“目的地”。类加载器确保每个类只被加载一次&#xff0c;并维护一个类的层级…

【Docker】常用命令汇总

Docker 是1个开源的应用容器引擎&#xff0c;基于Go 语言并遵从 Apache2.0 协议开源。 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱机制&#xff0c;相…

ChatGPT如何辅助academic writing?

今天想和大家分享一篇来自《Nature》杂志的文章《Three ways ChatGPT helps me in my academic writing》&#xff0c;如果您的日常涉及到学术论文的写作&#xff08;writing&#xff09;、编辑&#xff08;editing&#xff09;或者审稿&#xff08; peer review&#xff09;&a…

对比C++,Rust在内存安全上做的努力

简介 近年来&#xff0c;越来越多的组织表示&#xff0c;如果新项目在技术选型时需要使用系统级开发语言&#xff0c;那么不要选择使用C/C这种内存不安全的系统语言&#xff0c;推荐使用内存安全的Rust作为替代。 谷歌也声称&#xff0c;Android 的安全漏洞&#xff0c;从 20…

【网络安全设备系列】12、态势感知

0x00 定义&#xff1a; 态势感知&#xff08;Situation Awareness&#xff0c;SA&#xff09;能够检测出超过20大类的云上安全风险&#xff0c;包括DDoS攻击、暴力破解、Web攻击、后门木马、僵尸主机、异常行为、漏洞攻击、命令与控制等。利用大数据分析技术&#xff0c;态势感…

UE5 slate BlankProgram独立程序系列

源码版Engine\Source\Programs\中copy BlankProgram文件夹&#xff0c;重命名为ASlateLearning&#xff0c;修改所有文件命名及内部名称。 ASlateLearning.Target.cs // Copyright Epic Games, Inc. All Rights Reserved.using UnrealBuildTool; using System.Collections.Ge…

铲屎官进,2024年宠物空气净化器十大排行,看看哪款吸毛最佳?

不知道最近换毛季&#xff0c;铲屎官们还承受的住吗&#xff1f;我家猫咪每天都在表演“天女散花”&#xff0c;家里没有一块干净的地方&#xff0c;空气中也都是堆积的浮毛&#xff0c;幸好有宠物空气净化器这种清理好物。宠物空气净化器针对宠物浮毛设计&#xff0c;可以有效…

VOLO实战:使用VOLO实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

AI加持,华为全屋智能品牌升级为“鸿蒙智家”

1.传统智能家居的困境&#xff1a;从便利到繁琐 近年来&#xff0c;智能家居因其便捷性和科技感受到消费者的青睐。然而&#xff0c;随着用户需求的多样化&#xff0c;传统智能家居的弊端逐渐显现&#xff1a; 设备连接复杂&#xff0c;品牌间兼容性不足&#xff0c;用户不得不…

.NET9 - Swagger平替Scalar详解(四)

书接上回&#xff0c;上一章介绍了Swagger代替品Scalar&#xff0c;在使用中遇到不少问题&#xff0c;今天单独分享一下之前Swagger中常用的功能如何在Scalar中使用。 下面我们将围绕文档版本说明、接口分类、接口描述、参数描述、枚举类型、文件上传、JWT认证等方面详细讲解。…

Qt界面篇:QMessageBox高级用法

1、演示效果 2、用法注意 2.1 设置图标 用于显示实际图标的pixmap取决于当前的GUI样式。也可以通过设置icon pixmap属性为图标设置自定义pixmap。 QMessageBox::Icon icon(