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

如何在JavaScript中解码COCO RLE二进制掩码并转为图像?

在JavaScript中解码COCO RLE掩码并渲染到Canvas的方案

有几个现成的JavaScript工具库可以处理COCO RLE掩码的解码,也可以手动实现解码逻辑,以下是具体方案:

一、可用的第三方库

  • @cocodataset/coco-utils:COCO数据集官方提供的工具库,原生支持RLE格式的解码,功能稳定可靠。
  • maskjs:轻量级图像掩码处理库,专门针对COCO RLE等常见掩码格式做了优化。

使用@cocodataset/coco-utils的示例

  1. 先安装库:
npm install @cocodataset/coco-utils
  1. 解码并渲染到Canvas的代码:
import { maskUtils } from '@cocodataset/coco-utils';

// YOLOv8生成的预测数据
const examplePrediction = {
  "image_id": "102_jpg",
  "category_id": 0,
  "bbox": [153.106, 281.433, 302.518, 130.737],
  "score": 0.8483,
  "segmentation": {
    "size": [640, 640],
    "counts": "<你的RLE编码字符串>" // 替换为实际的RLE内容
  }
};

// 解码RLE为二进制掩码数组
const mask = maskUtils.decode(examplePrediction.segmentation);

// 将掩码渲染到指定Canvas
function renderMaskToCanvas(mask, canvasId) {
  const canvas = document.getElementById(canvasId);
  const ctx = canvas.getContext('2d');
  const [height, width] = examplePrediction.segmentation.size;
  
  canvas.width = width;
  canvas.height = height;
  
  const imageData = ctx.createImageData(width, height);
  const data = imageData.data;
  
  // 遍历掩码,设置像素:白色前景,透明背景
  for (let i = 0; i < height; i++) {
    for (let j = 0; j < width; j++) {
      const idx = i * width + j;
      const pixelOffset = idx * 4;
      if (mask[idx]) {
        data[pixelOffset] = 255;     // 红色通道
        data[pixelOffset + 1] = 255; // 绿色通道
        data[pixelOffset + 2] = 255; // 蓝色通道
        data[pixelOffset + 3] = 255; // 透明度
      } else {
        data[pixelOffset + 3] = 0;
      }
    }
  }
  
  ctx.putImageData(imageData, 0, 0);
}

// 执行渲染(假设页面上有id为maskCanvas的Canvas元素)
renderMaskToCanvas(mask, 'maskCanvas');

二、手动实现RLE解码(不依赖第三方库)

如果不想引入额外依赖,可以手动实现COCO RLE的解码逻辑。COCO RLE的规则是:交替记录连续的背景像素数和前景像素数,从背景开始,counts字符串是经过Base64编码的可变长度整数序列。

// 解码COCO RLE掩码
function decodeCocoRLE(rle) {
  const { size, counts } = rle;
  const [height, width] = size;
  const totalPixels = height * width;
  const mask = new Uint8Array(totalPixels);
  
  // 解码counts字符串为整数数组
  const countsArr = decodeRLECounts(counts);
  let currentPixel = 0;
  let isBackground = true;
  
  for (const count of countsArr) {
    const endPixel = currentPixel + count;
    if (!isBackground) {
      // 填充前景区域(值为1)
      mask.fill(1, currentPixel, endPixel);
    }
    currentPixel = endPixel;
    isBackground = !isBackground;
  }
  
  return mask;
}

// 解码RLE的counts字段(处理Base64和可变长度编码)
function decodeRLECounts(countsStr) {
  const buffer = Uint8Array.from(atob(countsStr), c => c.charCodeAt(0));
  const counts = [];
  let i = 0;
  
  while (i < buffer.length) {
    let value = 0;
    let shift = 0;
    let byte;
    
    do {
      byte = buffer[i++];
      value |= (byte & 0x7F) << shift;
      shift += 7;
    } while (byte & 0x80);
    
    counts.push(value);
  }
  
  return counts;
}

// 使用示例
const mask = decodeCocoRLE(examplePrediction.segmentation);
// 调用之前的renderMaskToCanvas函数渲染到Canvas
renderMaskToCanvas(mask, 'maskCanvas');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:03:30