一个改进的MATLAB CVA(Change Vector Analysis)变化检测程序

一个改进的MATLAB CVA(Change Vector Analysis)变化检测程序,增加了更多功能和灵活性:

matlab 复制代码
function change_detection_cva()
    % CVA变化检测主函数
    % 支持单波段/多波段遥感影像变化检测
    
    %% 参数设置
    params = struct();
    params.useAutoThreshold = true;       % 使用自动阈值(Otsu)
    params.manualThreshold = 0.25;         % 手动阈值(当useAutoThreshold=false时使用)
    params.morphologyEnabled = true;       % 启用形态学后处理
    params.structElementRadius = 3;        % 形态学结构元素半径
    params.saveResults = true;             % 保存结果
    params.showPlots = true;               % 显示结果图像
    params.bandSelection = [];             % 波段选择([]表示所有波段)
    
    %% 读取影像
    [img1, img2] = load_images();
    
    %% 预处理
    [img1, img2] = preprocess_images(img1, img2, params.bandSelection);
    
    %% CVA核心计算
    [magnitude, diff_img] = compute_cva(img1, img2);
    
    %% 阈值分割
    binary_change = threshold_segmentation(magnitude, params);
    
    %% 后处理
    if params.morphologyEnabled
        cleaned_change = morphological_processing(binary_change, params.structElementRadius);
    else
        cleaned_change = binary_change;
    end
    
    %% 结果显示与保存
    display_results(img1, img2, magnitude, cleaned_change, params);
    
    %% 可选:导出变化统计信息
    export_statistics(cleaned_change);
end

%% 辅助函数
function [img1, img2] = load_images()
    % 交互式选择影像文件
    [filename1, pathname1] = uigetfile({'*.tif;*.jpg;*.png;*.img','影像文件 (*.tif, *.jpg, *.png, *.img)'},...
        '选择时期1影像');
    [filename2, pathname2] = uigetfile({'*.tif;*.jpg;*.png;*.img','影像文件 (*.tif, *.jpg, *.png, *.img)'},...
        '选择时期2影像');
    
    if isequal(filename1,0) || isequal(filename2,0)
        error('未选择影像文件');
    end
    
    img1 = imread(fullfile(pathname1, filename1));
    img2 = imread(fullfile(pathname2, filename2));
    
    % 检查尺寸一致性
    if ~isequal(size(img1), size(img2))
        error('错误:两幅影像尺寸不一致 (%s: %dx%d, %s: %dx%d)',...
            filename1, size(img1,1), size(img1,2),...
            filename2, size(img2,1), size(img2,2));
    end
end

function [img1, img2] = preprocess_images(img1, img2, bandSelection)
    % 转换为双精度浮点型
    img1 = im2double(img1);
    img2 = im2double(img2);
    
    % 波段选择
    if ~isempty(bandSelection)
        if ndims(img1) == 3
            img1 = img1(:,:,bandSelection);
            img2 = img2(:,:,bandSelection);
        else
            warning('波段选择仅适用于多波段影像');
        end
    end
    
    % 直方图匹配(可选)
    % img2 = histeq(img2, img1);
end

function [magnitude, diff_img] = compute_cva(img1, img2)
    % 计算变化向量和幅度
    if ndims(img1) == 3
        % 多波段影像
        diff_img = zeros(size(img1));
        for b = 1:size(img1, 3)
            diff_img(:,:,b) = img2(:,:,b) - img1(:,:,b);
        end
        magnitude = sqrt(sum(diff_img.^2, 3));
    else
        % 单波段影像
        diff_img = img2 - img1;
        magnitude = abs(diff_img);
    end
    
    % 归一化幅度到0-1范围
    magnitude = (magnitude - min(magnitude(:))) / (max(magnitude(:)) - min(magnitude(:)));
end

function binary_change = threshold_segmentation(magnitude, params)
    % 变化区域分割
    if params.useAutoThreshold
        % Otsu自动阈值
        level = graythresh(magnitude);
        binary_change = imbinarize(magnitude, level);
    else
        % 手动阈值
        binary_change = magnitude > params.manualThreshold;
    end
end

function processed = morphological_processing(binary_img, radius)
    % 形态学后处理
    se = strel('disk', radius);
    processed = imopen(binary_img, se);    % 开运算去除小物体
    processed = imclose(processed, se);   % 闭运算填充小孔
    processed = bwareaopen(processed, 50); % 移除小面积区域
end

function display_results(img1, img2, magnitude, change_map, params)
    % 显示结果
    if params.showPlots
        figure('Name', 'CVA变化检测结果', 'NumberTitle', 'off');
        
        % 原始影像
        subplot(2,2,1), imshow(img1), title('时期1影像');
        subplot(2,2,2), imshow(img2), title('时期2影像');
        
        % 变化幅度
        subplot(2,2,3), imshow(magnitude, []), title('变化向量幅度');
        colorbar;
        
        % 变化检测结果
        subplot(2,2,4), imshow(change_map), title('变化检测结果');
        colormap(gray);
    end
    
    % 保存结果
    if params.saveResults
        [~, name1] = fileparts(uigetfile('last used'));
        timestamp = datestr(now, 'yyyymmdd_HHMMSS');
        output_dir = pwd;
        
        % 保存变化图
        imwrite(change_map, fullfile(output_dir, ['change_map_' timestamp '.png']));
        
        % 保存变化幅度图
        imwrite(mat2gray(magnitude), fullfile(output_dir, ['magnitude_' timestamp '.png']));
        
        disp(['结果已保存至: ' output_dir]);
    end
end

function export_statistics(change_map)
    % 导出变化统计信息
    total_pixels = numel(change_map);
    changed_pixels = sum(change_map(:));
    change_percent = (changed_pixels / total_pixels) * 100;
    
    fprintf('\n===== 变化统计 =====\n');
    fprintf('总像素数: %d\n', total_pixels);
    fprintf('变化像素数: %d (%.2f%%)\n', changed_pixels, change_percent);
    fprintf('未变化像素数: %d (%.2f%%)\n', total_pixels - changed_pixels, 100 - change_percent);
    
    % 可选:保存统计信息到文件
    stats_file = fopen('change_stats.txt', 'w');
    fprintf(stats_file, '变化检测统计报告\n');
    fprintf(stats_file, '生成时间: %s\n\n', datestr(now));
    fprintf(stats_file, '总像素数: %d\n', total_pixels);
    fprintf(stats_file, '变化像素数: %d (%.2f%%)\n', changed_pixels, change_percent);
    fclose(stats_file);
end

程序特点与功能:

  1. 模块化设计
    • 分离了影像加载、预处理、CVA计算、阈值分割和后处理模块
    • 每个功能都有独立的函数实现
  2. 增强的预处理
    • 支持波段选择(可指定特定波段参与计算)
    • 自动尺寸检查和错误处理
    • 可选的直方图匹配(注释部分)
  3. 灵活的阈值处理
    • 支持Otsu自动阈值和手动阈值两种模式
    • 阈值参数可通过结构体配置
  4. 高级后处理
    • 形态学开闭运算去除噪声
    • 面积过滤移除小区域(<50像素)
    • 可调节的结构元素大小
  5. 全面的结果输出
    • 可视化显示原始影像、变化幅度和检测结果
    • 自动保存结果图像(PNG格式)
    • 生成变化统计报告(文本文件)
    • 控制台输出变化百分比
  6. 用户友好特性
    • 交互式文件选择对话框
    • 详细的错误处理和信息提示
    • 时间戳命名防止覆盖

使用示例:

matlab 复制代码
% 基本使用
change_detection_cva();

% 自定义参数(通过修改params结构体)
function custom_cva()
    params = struct();
    params.useAutoThreshold = false;     % 使用手动阈值
    params.manualThreshold = 0.3;         % 设置阈值
    params.morphologyEnabled = true;      % 启用形态学处理
    params.structElementRadius = 2;        % 较小的结构元素
    params.saveResults = true;             % 保存结果
    params.showPlots = true;               % 显示图像
    params.bandSelection = [3,2,1];        % 选择RGB波段(假设原图为多波段)
    
    % 调用修改后的处理函数(需要稍作调整)
    % ...
end

参考代码 cva变化检测程序 www.youwenfan.com/contentcss/55106.html

建议:

  1. 影像预处理

    • 确保影像经过精确配准
    • 进行辐射定标和大气校正
    • 对于高分辨率影像,考虑使用PCA降维
  2. 参数优化

    matlab 复制代码
    % 尝试不同阈值策略
    thresholds = 0.1:0.05:0.5;
    for t = thresholds
        params.manualThreshold = t;
        % 运行检测并记录结果
    end
    
    % 尝试不同结构元素
    radii = 1:5;
    for r = radii
        params.structElementRadius = r;
        % 运行检测
    end
  3. 结果验证

    • 使用混淆矩阵评估检测精度
    • 结合实地调查数据进行验证
    • 尝试不同波段组合(如NDVI、NDWI等指数)
  4. 性能优化

    • 对于大型影像,使用块处理
    • 利用并行计算(parfor
    • 使用GPU加速(需要Parallel Computing Toolbox)
相关推荐
2301_815482932 小时前
C++与WebAssembly集成
开发语言·c++·算法
机器学习之心HML2 小时前
考虑气象因素的贝叶斯优化短期电力负荷预测研究,MATLAB代码
开发语言·matlab
像污秽一样2 小时前
算法设计与分析-习题4.3
数据结构·算法·排序算法
ComputerInBook2 小时前
几何学基本概念——超平面(hyperplane)
算法·机器学习·平面·几何学
沈阳信息学奥赛培训2 小时前
C++ 指针* 和 指针的引用 *& (不是指针和引用,是指针的引用)
数据结构·c++·算法
老鱼说AI2 小时前
《深入理解计算机系统》(CSAPP)2.2:整数数据类型与底层机器级表示
开发语言·汇编·算法·c#
yuhaiqiang2 小时前
为什么这道初中数学题击溃了所有 AI
前端·后端·面试
djk88882 小时前
支持手机屏幕的layui后台html模板
前端·html·layui
紫_龙2 小时前
最新版vue3+TypeScript开发入门到实战教程之watch详解
前端·javascript·typescript