V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ScriptEcho
V2EX  ›  前端开发

基于 Transformers.js 的图片任意元素分割

  •  
  •   ScriptEcho ·
    ScriptEcho.ai · 218 天前 · 506 次点击
    这是一个创建于 218 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Alt

    本文由ScriptEcho平台提供技术支持

    项目地址:传送门

    图片任意元素分割

    应用场景介绍

    该代码实现了一个基于 Hugging Face Transformers.js 库的图片任意元素分割功能。用户可以上传或选择一张图片,然后通过点击和右键单击在图片上标记出想要分割的区域。该代码使用 CLIP 模型对图片进行编码,并生成一张分割掩码,其中分割的区域用绿色填充。用户可以进一步使用该掩码来切割出图片中的特定元素。

    代码基本功能介绍

    该代码的主要功能包括:

    • 图片上传和选择:用户可以上传一张图片或选择一个示例图片。
    • 图片编码:使用 CLIP 模型对图片进行编码,提取图片的嵌入。
    • 分割掩码生成:根据用户的点击和右键单击,生成一张分割掩码,其中分割的区域用绿色填充。
    • 分割区域切割:用户可以点击“剪切遮罩”按钮,将分割的区域切割出来并下载为 PNG 图片。

    功能实现步骤及关键代码分析说明

    1. 初始化

    onMounted(async () => {
        // Reference the elements we will use
        const statusLabel = document.getElementById('status');
        const fileUpload = document.getElementById('upload');
        const imageContainer = document.getElementById('container');
        const example = document.getElementById('example');
        const maskCanvas = document.getElementById('mask-output');
        const uploadButton = document.getElementById('upload-button');
        const resetButton = document.getElementById('reset-image');
        const clearButton = document.getElementById('clear-points');
        const cutButton = document.getElementById('cut-mask');
    
        // ...
    

    onMounted钩子中,我们首先引用了所有必要的元素。

    2. 创建 Web Worker

        // Create a web worker so that the main (UI) thread is not blocked during inference.
        const worker = new Worker('/src/pages/test/ai/transformersjs/sam-worker.js', {
            type: 'module',
        });
    

    我们创建一个 Web Worker 来处理图片编码和分割掩码生成,以避免阻塞主线程。

    3. 消息处理程序

        // Set up message handler
        worker.addEventListener('message', (e) => {
            const { type, data } = e.data;
            if (type === 'ready') {
                modelReady = true;
                statusLabel.textContent = '已完成';
    
            } else if (type === 'decode_result') {
                // ...
            } else if (type === 'segment_result') {
                // ...
            }
        });
    

    我们为 Web Worker 设置一个消息处理程序,用于处理从 Web Worker 接收到的消息。

    4. 图片编码

    function segment(data) {
        // ...
    
        // Instruct worker to segment the image
        worker.postMessage({ type: 'segment', data });
    }
    

    segment函数用于将图片发送到 Web Worker 进行编码。

    5. 分割掩码生成

    function decode() {
        // ...
    
        worker.postMessage({ type: 'decode', data: lastPoints });
    }
    

    decode函数用于将用户点击和右键单击的点发送到 Web Worker ,以生成分割掩码。

    6. 分割区域切割

        // Handle cut button click
        cutButton.addEventListener('click', () => {
            // ...
    
            // Create a new canvas to hold the cut-out
            const cutCanvas = new OffscreenCanvas(w, h);
            const cutContext = cutCanvas.getContext('2d');
            const cutPixelData = cutContext.getImageData(0, 0, w, h);
    
            // ...
    
            // Download image
            const link = document.createElement('a');
            link.download = 'image.png';
            link.href = URL.createObjectURL(await cutCanvas.convertToBlob());
            link.click();
            link.remove();
        });
    

    cutButton的点击事件处理程序用于切割出分割的区域并下载为 PNG 图片。

    总结与展望

    开发这段代码过程中的经验与收获

    • 学习了如何使用 Hugging Face Transformers.js 库进行图片编码和分割。
    • 了解了如何在 Vue.js 中使用 Web Worker 。
    • 掌握了如何处理用户交互事件和更新 UI 。

    未来该卡片功能的拓展与优化

    • 添加对多张图片分割的支持。

    • 探索使用其他分割模型,如 U-Net 。

    • 集成图像编辑功能,如裁剪和旋转。

    • 优化 Web Worker 的性能。

      更多组件:

    获取更多 Echos

    本文由ScriptEcho平台提供技术支持

    项目地址:传送门

    扫码加入 AI 生成前端微信讨论群: 扫码加入群聊

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2689 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 04:03 · PVG 12:03 · LAX 20:03 · JFK 23:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.