基于 Transformers.js 的圖片景深3D圖生成

1788385023080235009.png

本文由ScriptEcho平臺提供技術支持

項目地址:傳送門

基于 Transformers.js 的圖片景深3D圖生成

應用場景

本代碼可以將一張普通的圖片轉換為具有景深效果的 3D 圖,可用于創(chuàng)建逼真的 3D 場景或增強圖片的視覺吸引力。

代碼基本功能

該代碼使用 Transformers.js 中的深度估計模型,分析圖片中物體的深度信息,并生成一張位移貼圖。然后將位移貼圖應用于 3D 模型,使其產生景深效果。用戶可以通過滑動條控制景深程度,呈現出更具立體感和真實感的圖像。

功能實現步驟及關鍵代碼分析

1. 導入依賴項

import { ref, onMounted } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from '/sfc/threejs/jsm/controls/OrbitControls.js';
import { pipeline, env, RawImage } from '@xenova/transformers';
  • 導入 Vue.js 依賴項、Three.js 庫、OrbitControls 控件和 Transformers.js 庫。

2. 初始化狀態(tài)和引用

onMounted(async () => {
    console.log(`Transformers.js version: ${env.version}`);

    // Since we will download the model from the Hugging Face Hub, we can skip the local model check
    env.allowLocalModels = false;

    // Proxy the WASM backend to prevent the UI from freezing
    env.backends.onnx.wasm.proxy = true;

    // Constants
    const EXAMPLE_URL = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/bread_small.png';
    const DEFAULT_SCALE = 0.75;

    // Reference the elements that we will need
    const status = document.getElementById('status');
    const fileUpload = document.getElementById('upload');
    const imageContainer = document.getElementById('container');
    const example = document.getElementById('example');
    console.log(`status: `, status)

    // Create a new depth-estimation pipeline
    status.textContent = '正在加載模型...';
    const depth_estimator = await pipeline('depth-estimation', 'Xenova/depth-anything-small-hf');
    status.textContent = '已完成';
  • 禁用本地模型檢查,因為我們將從 Hugging Face Hub 下載模型。
  • 設置 WASM 后端代理,以防止 UI 在模型加載時凍結。
  • 定義常量,例如示例 URL 和默認景深比例。
  • 引用 HTML 元素,例如狀態(tài)文本、文件上傳輸入框、圖片容器和示例鏈接。
  • 創(chuàng)建一個深度估計管道,該管道將用于分析圖片的深度信息。

3. 設置事件監(jiān)聽器

example.addEventListener('click', (e) => {
    e.preventDefault();
    predict(EXAMPLE_URL);
});

fileUpload.addEventListener('change', function (e) {
    const file = e.target.files[0];
    if (!file) {
        return;
    }

    const reader = new FileReader();

    // Set up a callback when the file is loaded
    reader.onload = e2 => predict(e2.target.result);

    reader.readAsDataURL(file);
});
  • 為示例鏈接添加一個點擊事件監(jiān)聽器,以便用戶可以加載示例圖片。
  • 為文件上傳輸入框添加一個更改事件監(jiān)聽器,以便用戶可以選擇要轉換的圖片。

4. 預測深度圖

async function predict(url) {
    imageContainer.innerHTML = '';
    const image = await RawImage.fromURL(url);

    // Set up scene and slider controls
    const { canvas, setDisplacementMap } = setupScene(url, image.width, image.height);

    imageContainer.append(canvas);

    status.textContent = '正在分析...';
    const { depth } = await depth_estimator(image);

    setDisplacementMap(depth.toCanvas());
    status.textContent = '';

    // Add slider control
    const slider = document.createElement('input');
    slider.type = 'range';
    slider.min = 0;
    slider.max = 1;
    slider.step = 0.01;
    slider.addEventListener('input', (e) => {
        onSliderChange(parseFloat(e.target.value));
    });
    slider.defaultValue = DEFAULT_SCALE;
    imageContainer.append(slider);
}
  • 清空圖片容器。
  • 從給定的 URL 加載圖片。
  • 設置場景和滑塊控件。
  • 使用深度估計管道預測圖片的深度圖。
  • 設置位移貼圖。
  • 添加一個滑塊控件,允許用戶控制景深程度。

5. 設置場景

function setupScene(url, w, h) {

    // Create new scene
    const canvas = document.createElement('canvas');
    const width = canvas.width = imageContainer.offsetWidth;
    const height = canvas.height = imageContainer.offsetHeight;

    const scene = new THREE.Scene();

    // Create camera and add it to the scene
    const camera = new THREE.PerspectiveCamera(30, width / height, 0.01, 10);
    camera.position.z = 2;
    scene.add(camera);

    const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
    renderer.setSize(width, height);
    renderer.setPixelRatio(window.devicePixelRatio);

    // Add ambient light
    const light = new THREE.AmbientLight(0xffffff, 2);
    scene.add(light);

    // Load depth texture
    const image = new THREE.TextureLoader().load(url);
    image.colorSpace = THREE.SRGBColorSpace;
    const material = new THREE.MeshStandardMaterial({
        map: image,
        side: THREE.DoubleSide,
    });
    material.displacementScale = DEFAULT_SCALE;

    const setDisplacementMap = (canvas) => {
        material.displacementMap = new THREE.CanvasTexture(canvas);
        material.needsUpdate = true;
    }

    const setDisplacementScale = (scale) => {
        material.displacementScale = scale;
        material.needsUpdate = true;
    }
    onSliderChange = setDisplacementScale;

    // Create plane and rescale it so that max(w, h) = 1
    const [pw, ph] = w > h ? [1, h / w] : [w / h, 1];
    const geometry = new THREE.PlaneGeometry(pw, ph, w, h);
    const plane = new THREE.Mesh(geometry, material);
    scene.add(plane);

    // Add orbit controls
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;

    renderer.setAnimationLoop(() => {
        renderer.render(scene, camera);
        controls.update();
    });

    window.addEventListener('resize', () => {
        const width = imageContainer.offsetWidth;
        const height = imageContainer.offsetHeight;

        camera.aspect = width / height;
        camera.updateProjectionMatrix();

        renderer.setSize(width, height);
    }, false);

    return {
        canvas: renderer.domElement,
        setDisplacementMap,
    };
}
  • 創(chuàng)建一個新的場景、相機和渲染器。
  • 添加環(huán)境光。
  • 加載圖片并將其設置為材質貼圖。
  • 創(chuàng)建一個平面并將其添加到場景中。
  • 添加軌道控件以允許用戶旋轉和縮放場景。
  • 設置動畫循環(huán)以持續(xù)渲染場景。
  • 設置窗口大小更改事件監(jiān)聽器。

總結與展望

這段代碼成功實現了圖片景深3D圖的生成功能,展示了 Transformers.js 和 Three.js 的強大功能。

開發(fā)經驗與收獲:

  • 學習了如何使用 Transformers.js 加載和使用深度估計模型。
  • 熟悉了 Three.js 中的場景、相機、渲染器和材質的概念。
  • 了解了如何使用 Three.js 創(chuàng)建交互式 3D 場景。

未來拓展與優(yōu)化:

  • 探索不同的深度估計模型,以獲得更高的準確性和更逼真的效果。

  • 添加其他功能,例如更改景深范圍或應用不同類型的位移貼圖。

  • 優(yōu)化代碼以提高性能和響應速度。

  • 集成到更廣泛的應用程序中,例如圖像編輯器或 3D 建模工具。

    更多組件:

    獲取更多Echos

    本文由ScriptEcho平臺提供技術支持

    項目地址:傳送門

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容