You need to enable JavaScript to run this app. JavaScript实现2D像素数组全同色矩形坐标查找方案
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现2D像素数组全同色矩形坐标查找方案

二维数组多色矩形识别实现

原代码核心问题

  • 所有像素判断逻辑硬编码了目标值为1,完全无法识别其他颜色值的矩形
  • 标记已识别区域时直接将像素值改为2,会覆盖数组内原本的2号颜色像素,干扰后续识别流程
  • 识别结果未关联对应颜色值,无法匹配多色矩形的分组输出要求

核心改造逻辑

  • 扫描左上角起点时,不再固定查找值为1的像素,而是定位第一个非0(即已填充)的像素,记录该像素的颜色值作为当前矩形的匹配标准
  • 矩形右边界校验、列方向下边界推导全部使用记录的目标颜色值,不再依赖硬编码固定值
  • 标记已识别区域时,将对应位置的像素值改为0(空白值),彻底避免和实际1-10的颜色值冲突
  • 每个识别出的矩形对象新增color字段,记录对应的颜色属性,方便按要求分组输出

可直接运行的完整代码

// 注意:原数组会在识别过程中被临时修改为0标记已识别区域,如需保留原数组可先做深拷贝
const grid = [
    [1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 4, 4], //y=0
    [1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 4, 4], //y=1
    [1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0], //y=2
    [1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0], //y=3
    [1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 2, 2], //y=4
    [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2], //y=5
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2], //y=6
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //y=7
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //y=8
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //y=9
    [0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2], //y=10
    [0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], //y=11
    [0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], //y=12
    [0, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], //y=13
    [0, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], //y=14
    [0, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]  //y=15
];

const WIDTH = grid[0].length;
const HEIGHT = grid.length;

// 计算所有已填充像素的总面积
let totalFilledArea = 0;
for (let y = 0; y < HEIGHT; y++) {
    for (let x = 0; x < WIDTH; x++) {
        totalFilledArea += grid[y][x] > 0 ? 1 : 0;
    }
}

const detectedRects = [];
let processedArea = 0;

// 循环识别直到所有已填充像素都被标记处理
while (processedArea < totalFilledArea) {
    const currentRect = findNextValidRect();
    detectedRects.push(currentRect);
    markRectAsProcessed(currentRect);
    processedArea += (currentRect.x2 - currentRect.x1 + 1) * (currentRect.y2 - currentRect.y1 + 1);
}

// 按颜色分组输出,和期望格式对齐
const rectsByColor = detectedRects.reduce((acc, rect) => {
    const c = rect.color;
    if (!acc[c]) acc[c] = [];
    acc[c].push(rect);
    return acc;
}, {});
console.log('识别结果:', rectsByColor);

function findNextValidRect() {
    let startFound = false;
    const rect = { x1: 0, x2: WIDTH - 1, y1: 0, y2: HEIGHT - 1, color: 0 };
    
    // 查找矩形左上角起点
    for (let x = 0; x < WIDTH; x++) {
        for (let y = 0; y < HEIGHT; y++) {
            if (grid[y][x] > 0) {
                rect.x1 = x;
                rect.y1 = y;
                rect.color = grid[y][x]; // 记录当前矩形的目标颜色
                startFound = true;
                break;
            }
        }
        if (startFound) break;
    }

    // 推导矩形右边界和下边界
    for (let x = rect.x1; x <= rect.x2; x++) {
        // 同一行当前位置颜色不匹配,截断右边界
        if (grid[rect.y1][x] !== rect.color) {
            rect.x2 = x - 1;
            break;
        }
        // 逐列向下校验颜色,遇到不匹配则截断下边界
        for (let y = rect.y1; y <= rect.y2; y++) {
            if (grid[y][x] !== rect.color) {
                rect.y2 = y - 1;
                break;
            }
        }
    }
    return rect;
}

// 标记已识别区域为0(空白),避免重复识别
function markRectAsProcessed({ x1, y1, x2, y2 }) {
    for (let x = x1; x <= x2; x++) {
        for (let y = y1; y <= y2; y++) {
            grid[y][x] = 0;
        }
    }
}

运行结果说明

代码运行后输出的按颜色分组的矩形列表,完全匹配给出的坐标样例:

  • 颜色1对应的5个矩形坐标和样例中的绿色矩形完全一致(修正了样例中第五个矩形y1:15的笔误,实际为y2:15)
  • 颜色2对应的4个矩形坐标和样例中的红色矩形完全一致
  • 颜色3、4对应的单矩形坐标也和样例匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 09:36:08