⌈ 传知代码 ⌋ 红外小目标检测

news2024/11/16 6:58:57

💛前情提要💛

本文是传知代码平台中的相关前沿知识与技术的分享~

接下来我们即将进入一个全新的空间,对技术有一个全新的视角~

本文所涉及所有资源均在传知代码平台可获取

以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦!!!

以下内容干货满满,跟上步伐吧~


📌导航小助手📌

  • 💡本章重点
  • 🍞一. 概述
  • 🍞二. 算法原理
  • 🍞三.演示效果
  • 🍞四. 核心逻辑
  • 🫓总结


💡本章重点

  • 红外小目标检测

🍞一. 概述

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

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

本文用python复现论文Infrared Small Target Detection Based on Facet Kernel and Random Walker中提出的红外小目标检测算法。

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

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

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


🍞二. 算法原理

检测流程中图像的变化

在这里插入图片描述

1.均值滤波与次序统计滤波

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

2.Facet Kernel滤波

图像经过Facet Kernel滤波后并通过一个自适应阈值来对图像进行初步分割。从而实现对红外图像中的小目标进行一个粗检。
其中Factet Kernel为 F,其值如下:

在这里插入图片描述
滤波后的图像设为 Mf ,其为图像 M与 F 卷积而成,即:

在这里插入图片描述
对应流程中的( c )。分割所使用的阈值为:

在这里插入图片描述
分割后的图像对应流程中的(d)。可以看到,这样的粗检无法避免云层中背景杂波的干扰。

3.RandomWalker算法分割

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

在这里插入图片描述
目标种类标为1,背景标为2。RndomWalker算法会根据未标记像素与标记像素的灰度相似程度来自动对未标记像素进行分割。利用RandomWlaker算法进行分割并得到邻域内所有像素属于目标类的概率值,大于等于0.5的设为目标类,小于0.5的设为背景类。

至此,检测本可以结束。但本文提出了两个特异性指标来进一步优化检测与分割结果。即:

在这里插入图片描述
公式的意思是如果邻域内中心像素不在分割的目标区域内部即将此指标设为0,否则就设为一个概率值。这个概率值是这样获得的,将邻域内非中心像素而被分割为目标像素的那些像素所属目标类的概率值取平均作为分子,被分为背景像素的那些像素所属目标类的概率值取平均作为分母。这个指标在目标区域明显会大于背景区域。,具体来说它用于区分以下情况:

在这里插入图片描述
(a1)是真正的目标区域,而(a2)是背景区域,但由于中心较亮,其也存在被分为目标区域的像素。此指标的值在(a1)会远大于(a2)从而区分这两种情况,找出真正的目标区域。在这里插入图片描述
这个公式的意思是,如果邻域中被分为背景区域的像素的灰度值的最大值大于等于被分为目标区域像素的平均灰度值,就将该指标设为0,否则就设为目标区域灰度值的平均值除以背景区域灰度的最大值。这个指标用于进一步去除单点高亮噪声被错误分为目标区域的情况。具体来说,单点高亮噪声所处的邻域中,这个值的计算应当为0.

作为我们所分割的目标区域的标签值,背景区域则设为0。得到与原图像尺寸相同的加权图即流程中的( e )。( c )与( e )相乘得到最终检测图(f)。


🍞三.演示效果

在这里插入图片描述


🍞四. 核心逻辑

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

🫓总结

综上,我们基本了解了“一项全新的技术啦” 🍭 ~~

恭喜你的内功又双叒叕得到了提高!!!

感谢你们的阅读😆

后续还会继续更新💓,欢迎持续关注📌哟~

💫如果有错误❌,欢迎指正呀💫

✨如果觉得收获满满,可以点点赞👍支持一下哟~✨

【传知科技 – 了解更多新知识】

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

keil5导入程序到stm32的开发板

如图&#xff0c; 1&#xff0c;安装mdk_514.exe 2&#xff0c;安装Keil.STM32F1xx_DFP.1.0.5.pack 3&#xff0c;注册方法&#xff08;仅限学生使用&#xff09;&#xff1a;http://www.openedv.com/thread-69384-1-1.html 点击keil程序的上面魔法棒&#xff0c; 在device中…

类中的function无法正确被matlab所识别,该怎么操作呢?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

【Linux】CentOS更换国内阿里云yum源(超详细)

目录 1. 前言2. 打开终端3. 确保虚拟机已经联网4. 备份现有yum配置文件5. 下载阿里云yum源6. 清理缓存7. 重新生成缓存8. 测试安装gcc 1. 前言 有些同学在安装完CentOS操作系统后&#xff0c;在系统内安装比如&#xff1a;gcc等软件的时候出现这种情况&#xff1a;&#xff08…

SpringBoot3如何整合Redis?

SpringBoot应该不用介绍&#xff01;它是Spring当前最火的一个框架&#xff0c;整合Spring Boot 3和Redis可以显著提升应用程序的性能&#xff0c;特别是在处理大量数据和需要快速访问的场景下。 在Spring Boot中&#xff0c;从1.x版本到2.x版本的Redis连接方式发生了变化&…

点脂成金携手北京新颜兴医疗美容医院,共启战略合作新篇章

2024年7月24日上午&#xff0c;点脂成金品牌方与北京新颜兴医疗美容医院在京举行了隆重的签约仪式&#xff0c;宣布达成战略合作关系&#xff0c;共同开启医疗美容领域的设备共享新篇章。 签约仪式在北京纯脂医疗美容门诊部有限公司举行&#xff0c;现场氛围热烈而庄重。点脂成…

使用 WebSocket 实现实时聊天

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

基于opencv的人脸识别(实战)

前言 经过这几天的学习&#xff0c;我已经跃跃欲试了&#xff0c;相信大家也是&#xff0c;所以我决定自己做一个人脸识别程序。我会把自己的思路和想法都在这篇博客内讲清楚&#xff0c;大家可以当个参考&#xff0c;&#x1f31f;仅供学习使用&#x1f31f;。 &#x1f31f…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day5 全网最快最全

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会…

树莓派_Opencv学习笔记23:模版样本匹配

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: ​ Opencv 版本是4.5.1&#xff1a; ​ Python 版本3.7.3&#xff1a; 今日学习Opencv样本…

香烟商品销售网站

1 香烟商品销售网站概述 1.1 课题简介 1.2 设计目的 1.3 系统开发所采用的技术 1.4 系统功能模块 2 数据库设计 2.1 建立的数据库名称 2.2 所使用的表 3 香烟商品销售网站设计与实现 1. 注册登录&#xff1a; 2. 分页查询&#xff1a; 3. 分页条件&#xff08;精确、…

速卖通卖家如何利用自养号测评,让店铺曝光量飙升?

在速卖通这个竞争激烈的跨境电商平台上&#xff0c;店铺曝光率是决定销售成败的关键因素之一。为了在众多商家中脱颖而出&#xff0c;增加速卖通店铺曝光显得尤为重要。速卖通怎么增加店铺曝光&#xff1f; 速卖通怎么增加店铺曝光? 1、优化产品列表 速卖通的产品列表是买家…

数据库实验:连接查询

一、实验目的&#xff1a; 1、掌握使用两种写法完成连接查询&#xff1a;叉积连接语法和内连接语法。 2、掌握使用外连接语法完成查询。 3、掌握使用派生表完成下列查询。 二、实验内容&#xff1a; 1. 使用连接实现查询&#xff0c;查询订单号为‘000005’的订单订购的玩具…

windows 安装docker桌面版

下载 下载两个&#xff1a; git桌面版 docker desktop 启动docker 执行安装文件&#xff0c;启动 更新wsl2 假如报错&#xff0c;会提示失败原因。 win10会提示跳转到&#xff1a; https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4—download-the-l…

CANoe编程实例--TCP/IP通信

1、简介 本实例将使用目前常用的开发工具C#来开发服务器端&#xff0c;以CANoe端作为客户端。服务器端和客户端&#xff0c;通过TCP/IP连接&#xff0c;实现数据交换。 首先在服务器端建立一个监听Socket&#xff0c;自动创建一个监听线程&#xff0c;随时监听是否有客户端的连…

使用 Visual Studio 2022 自带的 cl.exe 编译 tensorRT自带测试样例 sampleOnnxMNIST

1. 新建任意文件夹&#xff0c;将 D:\install\tensorRT\TensorRT-8.6.1.6\samples\sampleOnnxMNIST 下面的 sampleOnnxMNIST.cpp 文件复制进来&#xff0c;同时 D:\install\tensorRT\TensorRT-8.6.1.6\samples\sampleOnnxMNIST 下面的 sample_onnx_mnist.vcxproj 中的内容&…

WEBKIT 通过JavaScript 调用本地,硬件未来之窗OS硬件APP

以酒店为例我们需要调用shen份证读取&#xff0c;采集人脸&#xff0c;门锁写房卡&#xff0c;如何通过浏览器调用 1.通过本地http服务 2.通过webkit模式 这里说政务单位模式的集成 由于篇幅问题&#xff0c;怎么集成webkit就不说了 一、webkkit加载交互本地代码 browser.…

【Kettle实现神通(数据库)MPP增量、全量数据ETL,同步任务Linux运行(通用)】

1、背景介绍 具体Kettle操作步骤不做过多介绍&#xff0c;主要技术方案说明&#xff0c;Kettle8.2版本放在底部链接提取&#xff0c;本次采用Kettle实现源端&#xff1a;神通数据通用库、目标端&#xff1a;神通MPP增量数据同步&#xff0c;并在服务器端运行Job。 2、windows…

Materials Today|用于婴儿监护的柔性电子设备 (柔性健康监测/柔性传感/可穿戴电子/电子皮肤/柔性电子)

西安交通大学方云生&#xff08;Yunsheng Fang&#xff09;、徐峰&#xff08;Feng Xu&#xff09;和西安交通大学第一附属医院林婷&#xff08;Ting Lin&#xff09;团队&#xff0c;在期刊《Materials Today》上发布了一篇题为“Soft electronics for advanced infant monito…

关于@JsonSerialize序列化与@JsonDeserialize反序列化注解的使用(密码加密与解密举例)

注&#xff1a;另一种方式参考 关于TableField中TypeHandler属性&#xff0c;自定义的类型处理器的使用&#xff08;密码加密与解密举例&#xff09;http://t.csdnimg.cn/NZy4G 1.简介 1.1 序列化与反序列化 学习注解之前&#xff0c;我们可以先了解一下什么是序列化与反序列…

JAVA里的配置文件(Properties)详解

package Properties;import java.util.Map; import java.util.Properties; import java.util.Set;public class demo1 {public static void main(String[] args) {/*Properties作为Map集合的操作*///1.创建集合的对象Properties pnew Properties();//2.添加数据//细节&#xff…