基于MATLAB的红外弱小目标检测系统带GUI界面

红外弱小目标检测在安防监控和军事侦察领域一直是个头疼的问题。目标信号弱、背景复杂不说,传统算法动不动就给你误报一堆噪点。最近用MATLAB搞了个带GUI的检测系统,核心代码不到500行,实测效果还行,今天随便聊聊实现思路。

先看预处理部分,高斯滤波必须安排上。为啥不用中值滤波?试过,边缘保留效果确实好,但处理完目标信噪比反而下降。下面这段是滤波核心代码:

function filtered = gauss_filter(img, sigma)
    [x,y] = meshgrid(-3*sigma:3*sigma);
    kernel = exp(-(x.^2 + y.^2)/(2*sigma^2));
    kernel = kernel / sum(kernel(:));
    filtered = imfilter(img, kernel, 'replicate');
end

sigma参数建议设在1.5-2.5之间,太小去噪不给力,太大目标容易糊。有个坑要注意:imfilter默认用相关运算,记得转kernel方向或者改用卷积模式。

检测算法用了改进的局部对比度法。传统LCM算法在复杂云层背景下容易翻车,这里加了个自适应阈值:

function [targets, enhanced] = lcm_detect(img)
    local_mean = imfilter(img, ones(9)/81, 'symmetric');
    contrast = img - local_mean;
    adaptive_thresh = 0.5*max(contrast(:)) + 0.5*mean(contrast(:));
    targets = contrast > adaptive_thresh;
    enhanced = mat2gray(contrast).*targets;
end

9x9的滑动窗口实测速度与效果平衡最佳。阈值公式里的0.5系数不是拍脑袋定的,调参时发现当目标尺寸小于5x5像素时,这个权重组合误检率最低。

GUI界面用GUIDE拖控件比较快(虽然现在都推荐App Designer)。重点说下图像显示部分的回调处理:

function btn_load_Callback(hObject, ~, handles)
    [file, path] = uigetfile('*.png;*.jpg');
    if ~isequal(file,0)
        raw_img = imread(fullfile(path,file));
        handles.raw_img = im2double(rgb2gray(raw_img));
        axes(handles.axes_raw);
        imshow(handles.raw_img);
        guidata(hObject, handles);
    end
end

这里必须用guidata更新句柄,不然其他回调函数读不到最新图像数据。遇到过按钮点了没反应的坑,后来发现是回调函数执行顺序问题,加个drawnow就解决了。

实际跑起来发现两个问题:一是大尺寸图像(2000x2000以上)处理慢,后来改用im2col优化矩阵运算;二是目标尺寸变化时阈值需要动态调整,在GUI里加了个滑动条控件联动阈值参数,实时刷新效果。

最后放个处理效果对比图(此处应有示意图)。云层边缘的虚警明显减少,5x5像素左右的小目标都能稳定检出。代码里还藏了个彩蛋:双击结果图会弹出三维强度分布,方便分析目标特征。

这系统目前还在迭代,下一步准备上深度学习做虚警过滤。不过传统方法打好基础很重要,毕竟实际工程中很多场景还是需要轻量级方案。代码已传GitHub,需要自取(假装有链接)。遇到问题欢迎评论区互怼,看到就回——除非我也没解决。

更多推荐