You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB递归4向Flood_Fill算法填充异常问题求助

MATLAB 4向递归Flood Fill算法问题修复方案

问题描述

我有一项作业任务,需要用MATLAB实现4向递归Flood_Fill算法,填充两个重叠圆的区域,通过鼠标选取填充起点并编写了对应函数,但运行时遇到三个问题:

  • 角落像素无法被填充
  • 递归返回后程序会“遗忘”已绘制的像素,进而陷入无限循环
  • 即使添加x_prev、y_prev参数记录上一位置,返回时仍会出现像素变回旧颜色的情况

8向算法效果较好,但需要将圆边框设为至少2像素才能避免重叠,尝试过扩大搜索区域等方法都没解决。我对MATLAB不太熟悉,求解决这个递归填充的问题。

以下是我编写的两段函数代码:

第一段代码

function [] = Flood_Fill(M,x,y,new_color,old_color,border_color)

if(x < 0 || y < 0 || x >= 60 || y >= 60 || M(x,y) ~= old_color) % M is a 60x60 array
    return
else
    M(x,y) = new_color;
    pause(0.16);
    image(M');

Flood_Fill(M,x+1,y,new_color,old_color,border_color);
Flood_Fill(M,x-1,y,new_color,old_color,border_color);
Flood_Fill(M,x,y+1,new_color,old_color,border_color);
Flood_Fill(M,x,y-1,new_color,old_color,border_color);

end
disp("looped");
end 

第二段代码

function M = Zadacha_4_Fill_Recursion(M,x,y,new_color,old_color,border_color,x_prev,y_prev)

if(x < 0 || y < 0 || x >= 60 || y >= 60 || M(x,y) ~= old_color )
    fprintf("return cond: x = %d, y = %d\n", x,y);
    if(M(x,y) ~= border_color)
        fprintf("erase_not: x = %d, y = %d | x_prev = %d, y_prev = %d\n", x,y,x_prev,y_prev);
        M(x_prev,y_prev) = new_color;
        x_prev = x;
        y_prev = y;
    end
    pause(1.2);
    image(M');
    return 
else
    M(x,y) = new_color;
    x_prev = x;
    y_prev = y;
    pause(0.3);
    image(M');
    fprintf("normal: x = %d, y = %d | x_prev = %d, y_prev = %d\n", x,y,x_prev,y_prev);
    

Zadacha_4_Fill_Recursion(M,x+1,y,new_color,old_color,border_color,x_prev,y_prev);
Zadacha_4_Fill_Recursion(M,x-1,y,new_color,old_color,border_color,x_prev,y_prev);
Zadacha_4_Fill_Recursion(M,x,y+1,new_color,old_color,border_color,x_prev,y_prev);
Zadacha_4_Fill_Recursion(M,x,y-1,new_color,old_color,border_color,x_prev,y_prev);


end
%disp("looped");

end 

问题根源与修复方案

1. 核心问题:MATLAB参数传递机制

MATLAB函数默认是值传递,不是引用传递。你第一段代码里的M没有作为返回值输出,递归调用中修改的M不会同步到上层调用的数组——这就是递归返回后像素变回旧颜色、程序重复处理同一像素导致无限循环的根本原因。

2. 边界判断错误

MATLAB数组索引从1开始,不是0!你代码里的x < 0 || y < 0会把合法的(1,1)附近像素误判为越界,导致角落像素无法填充,正确的边界判断应该是x < 1 || y < 1 || x > 60 || y > 60。

3. x_prev/y_prev参数冗余

这个参数完全没必要,只要保证每次递归调用时传递并接收更新后的M,就能避免重复处理同一像素。


修复后的4向递归Flood Fill代码

function M = Flood_Fill(M, x, y, new_color, old_color)
    % 修正边界判断:适配MATLAB从1开始的索引规则
    if x < 1 || y < 1 || x > size(M,1) || y > size(M,2)
        return;
    end
    % 仅当前像素为旧颜色时才填充,自动跳过边框(边框颜色≠旧颜色)
    if M(x,y) ~= old_color
        return;
    end
    
    % 修改当前像素颜色
    M(x,y) = new_color;
    pause(0.16);
    image(M');
    drawnow; % 强制刷新图像,避免显示滞后
    
    % 递归处理四个方向,接收返回值更新当前M
    M = Flood_Fill(M, x+1, y, new_color, old_color);
    M = Flood_Fill(M, x-1, y, new_color, old_color);
    M = Flood_Fill(M, x, y+1, new_color, old_color);
    M = Flood_Fill(M, x, y-1, new_color, old_color);
end

使用说明

  1. 调用时传入初始M数组、鼠标选取的起点(x,y)、新颜色、旧颜色(即填充区域的初始颜色)即可,无需单独传递边框颜色(边框颜色与旧颜色不同时会被自动跳过)。
  2. 如果你的M不是固定60x60,size(M,1)和size(M,2)会自动适配数组尺寸,通用性更强。

这样修改后,三个问题都能解决:边界判断修正后角落像素可正常填充,值传递问题通过返回更新后的数组解决,不会再出现像素“遗忘”和无限循环的情况。

内容的提问来源于stack exchange,提问作者Alex_Stankov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:20:42