通过 segment anything 实现图片自动遮罩 RE:ChatGPT Plus金牌销售之Chat2API图片生成+编辑

大家都知道,就在10天前,吾皇开放了“不是什么神奇的东西”之图片编辑的接口,能够定向编辑遮罩区域的内容(虽然被群佬们测出了一堆Bug

ChatGPT Plus金牌销售之Chat2API图片生成+编辑

实际使用的时候,如果希望编辑的区域并不规整(例如选择背景、天空等等),手涂遮罩就显得效率很低了,所以向各位坛佬介绍一种自动选区的办法。

segment anything 是meta开源的用于图像分割的模型,一经推出火爆了整个CV领域,而借助于 transformers.js 我们可以在浏览器端使用它。恰好有大佬开发了一款浏览器插件 magic copy 可以帮助我们很方便的在浏览器里完成图像分割的任务。

但是这个项目用于吾皇的接口上存在一些问题:

  1. 最终下载提供的是选区图片,而非完整的图片保留选区部分
  2. 选区是原始图片的截图,非黑色遮罩
  3. 背景是透明,非白色

我们可以通过fork项目并修改其中关键的代码来满足我们的需求:

修改以下文件 src/components/hooks/useImageEditor.ts 中的部分代码为:

  React.useEffect(() => {
    if (!bitmap || !traced) {
      return;
    }
    const offscreen = new OffscreenCanvas(bitmap.width, bitmap.height);
    const offscreenCtx = offscreen.getContext("2d", {
      willReadFrequently: true,
    });
    if (!offscreenCtx) return;
    for (const path of traced) {
      offscreenCtx.fill(new Path2D(path));
    }
    offscreenCtx.fillStyle = "rgba(0, 0, 0, 1)";
    offscreenCtx.globalCompositeOperation = "source-in";
    offscreenCtx.drawImage(bitmap, 0, 0);
    const trimmed = trim(
      offscreenCtx.getImageData(0, 0, bitmap.width, bitmap.height)
    );
    if (trimmed == null) {
      setRenderedImage(null);
    } else {
      const [tx, ty, tw, th] = trimmed;
      const copy = new OffscreenCanvas(bitmap.width, bitmap.height);
      const copyCtx = copy.getContext("2d");
      if (copyCtx === null) {
        throw new Error("Could not get context");
      }
      copyCtx.fillStyle = "white";
      copyCtx.fillRect(0, 0, bitmap.width, bitmap.height);
      var imageData = offscreenCtx.getImageData(tx, ty, tw, th);
      for (let i = 0; i < imageData.data.length; i += 4) {
        if (imageData.data[i + 3] !== 0) {
          imageData.data[i] = 0;
          imageData.data[i + 1] = 0;
          imageData.data[i + 2] = 0;
        } else {
          imageData.data[i] = 255;
          imageData.data[i + 1] = 255;
          imageData.data[i + 2] = 255;
          imageData.data[i + 3] = 255;
        }
      }
      copyCtx.putImageData(imageData, tx, ty);
      copy.convertToBlob({ type: "image/png" }).then(setRenderedImage);
    }
  }, [bitmap, traced]);

编译打包即可完成修改,仓库参考 GitHub - wojingke/magic-copy: Magic Copy is a Chrome extension that uses Meta's Segment Anything Model to extract a foreground object from an image and copy it to the clipboard.

当然,我已经编译好了 chrome 版本的供大家使用(在仓库release中找),解压缩后在扩展程序打开开发者模式,加载即可。

看下效果:

点击感兴趣的区域:

Preview 查看:

Download 下载:
image (8)

ONLY AT LINUX DO

10 个赞

支持一下

虽然我不懂,但看起来很厉害的样子

AI + AI = 金牌销售:medal_sports:

1 个赞

这个好啊,可以集成到项目里面,周末加入到项目来,就免得下载了

真的牛逼啊

这个 SAM 模型最近很火

大佬太强了