使用 Unity Sentis 和 Compute Shader,2d106det.onnx 进行高效人脸网格标记

前言

前篇:使用 Unity Sentis 和 Compute Shader,det_10g.onnx 进行高效人脸五官定位-CSDN博客

在计算机视觉领域,人脸网格标记是一项重要的任务,用于识别人脸关键点和特征。本文将介绍如何使用 Unity Sentis 和 Compute Shader,结合 2d106det.onnx 模型,实现高效的人脸网格标记。我将提供完整的代码示例。

模型分析

输入值:

模型的输入是1x3x192x192的一张图片;

输出值:

输出值为(1,212)的张量,存储的是106个特征点的位置,可以将它变形为(106,2)方便计算;

代码示例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Sentis;

public class Landmark2D : MonoBehaviour
{
    public ModelAsset modelAsset;
    public Model model; 
    private IWorker worker;
    private GPUComputeBackend gpu;
    
    //处理图片
    public Texture2D t2d;
    public Material landMarkMat;


    private RenderTexture fc1RT;
    public ComputeShader outputCS;
    

    private void Start()
    {

        fc1RT = new RenderTexture(106, 1, 0,RenderTextureFormat.RGFloat);
        model = ModelLoader.Load(modelAsset);  
      
        gpu = new GPUComputeBackend();
        
        var model2 = Functional.Compile(input =>
        {
            var outputs = model.Forward(input);
            var pred = outputs[0].Reshape(new []{106,2});
            pred = pred[.., 0..2] + 1;
            pred = pred[.., 0..2] * (192 / 2);
            return pred;

        }, InputDef.FromModel(model)[0]
        );
        worker = WorkerFactory.CreateWorker(BackendType.GPUCompute, model2);
        Get(t2d);
    }

   
    public RenderTexture rt1;
    public RenderTexture markTexture;
    public void Get(Texture2D source )
    {
        rt1 = RenderTexture.GetTemporary(192,192,0);
        landMarkMat.SetTexture("_MainTex",source);
        Graphics.Blit(source,rt1,landMarkMat,0);   
        
        using (var input = TextureConverter.ToTensor(rt1, 192, 192, 3))
        {
            TensorFloat _255 = new TensorFloat(new TensorShape(1), new float[] {255});
            TensorFloat newInput = TensorFloat.AllocNoData(new TensorShape(1, 3, 192,192)); 
            gpu.Mul(input,_255,newInput);
            worker.Execute(newInput);
        }
   
        
        using var fc1 = worker.PeekOutput("output_0") as TensorFloat;  
        fc1.Reshape(new TensorShape(1,106,1,2));
         
        using  TensorFloat tagetT = TensorFloat.AllocNoData(new TensorShape(1, 2, 1,106)); 
        gpu.Transpose(fc1,tagetT,new int[] {0, 3, 1, 2});
        
        fc1RT = TextureConverter.ToTexture(tagetT, 106, 1, 2);  
        
        
        markTexture = new RenderTexture(192, 192, 0);
        markTexture.enableRandomWrite = true;  // 允许随机写入
        markTexture.Create();  // 创建纹理
        
        outputCS.SetTexture(0,"fcTex",fc1RT);
        outputCS.SetTexture(0,"outTex",markTexture);
        outputCS.Dispatch (0, (106 + 15)/16, 1, 1); 
        
 
        landMarkMat.SetTexture("_MarkTex",markTexture);
        
        /*fc1.CompleteOperationsAndDownload();
        for (int i = 0; i < 212; i++)
        {
            print(fc1[i]);
        }*/
    
    }

    private void OnDestroy()
    {
        worker.Dispose();
        gpu.Dispose();
        RenderTexture.ReleaseTemporary(rt1);
    }
}

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的Unity Compute Shader示例,用于将输入纹理的红色通道值乘以一个常数系数,并将结果输出到目标纹理的绿色通道中: ``` // 声明输入和输出纹理 Texture2D inputTex; RenderTexture outputTex; // 声明Compute Shader ComputeShader computeShader; int kernelID; void Start() { // 获取输入纹理 inputTex = Resources.Load<Texture2D>("InputTexture"); // 创建输出Render Texture outputTex = new RenderTexture(inputTex.width, inputTex.height, 0, RenderTextureFormat.ARGB32); outputTex.enableRandomWrite = true; outputTex.Create(); // 获取Compute Shader computeShader = Resources.Load<ComputeShader>("ComputeShader"); kernelID = computeShader.FindKernel("CSMain"); // 设置纹理参数 computeShader.SetTexture(kernelID, "InputTex", inputTex); computeShader.SetTexture(kernelID, "OutputTex", outputTex); // 设置常数系数参数 float coefficient = 2.0f; computeShader.SetFloat("Coefficient", coefficient); // 计算输出 computeShader.Dispatch(kernelID, inputTex.width / 8, inputTex.height / 8, 1); // 显示输出 GetComponent<Renderer>().material.mainTexture = outputTex; } void OnDestroy() { // 释放Render Texture outputTex.Release(); } ``` 在这个示例中,我们首先声明了输入和输出纹理,以及Compute Shader和内核ID。然后,我们在Start函数中加载输入纹理,创建输出Render Texture,并获取Compute Shader。接下来,我们设置Compute Shader的纹理和常数系数参数,并计算输出。最后,我们将输出纹理设置为场景中的对象材质的主纹理,并在结束时释放输出Render Texture。 要使用Compute Shader,您需要将其保存为.compute文件,并将其放在Unity项目的Assets文件夹中。您还需要将您的Compute Shader添加到资源中,以便您可以在代码中加载它。请注意,Compute Shader只能用于支持Compute Shader 5.0或更高版本的显卡上运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值