2022-04-29 11:45阅读: 1525评论: 6推荐: 0

【Unity】OpenCV Plus Unity 获取Unity中摄像机并调用opencv使其灰度化实例

前言

OpenCV Plus Unity 有关的教程实在很难找到,Opencv的有很多,但是在Unity上应用的相关教程很少,比如付费的OpenCV For Unity ,就已经很少了,目前经济有限,只能选择更加小众的OpenCV Plus Unity 国内甚至搜不到相关的概念,更别提学习教程了。真的就是纯靠自己一点点摸索尝试出来的。很不容易,不过成功之后也是成就感满满。其OpenCV的写法和C++版本的差不太多,也有些许不同之处,可以参考OpenCV for Unity 的语法格式写,并在写的过程看函数的参数说明。

1、导入OpenCV Plus Unity包

2、创建摄像机纹理

创建摄像机纹理并将其拖放到需要读取的摄像机上边

3、创建脚本

创建一个脚本:Get_cam_new,并将其附加到需处理的摄像机上边

4、代码分析

(1)引入包
using OpenCvSharp;
(2)所需变量
    //このScriptはMainCameraにアタッチしてください
    public RenderTexture renderTexture;             //mainCameraにつけるRendertexture(アタッチしてね)
    Texture2D kakunin, dstTexture;                  
    Camera mainCamera;
    GameObject hand;
(3)获取摄像机及所调用函数
    private void Update()
    {
        mainCamera = GetComponent<Camera>();
        kakunin = CreateTexture2D(renderTexture);
        Tex2D_to_Mat_show(kakunin);
    }
(4)将摄像机图像转 Texture2D 的函数定义
Texture2D CreateTexture2D(RenderTexture rt)
    {
        //Texture2Dを作成
        Texture2D texture2D = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, false);

        //subCameraにRenderTextureを入れる
        mainCamera.targetTexture = rt;

        //手動でカメラをレンダリングします
        mainCamera.Render();

        RenderTexture.active = rt;
        texture2D.ReadPixels(new UnityEngine.Rect(0, 0, rt.width, rt.height), 0, 0);
        texture2D.Apply();

        ////元に戻す別のカメラを用意してそれをRenderTexter用にすれば下のコードはいらないです。
        //mainCamera.targetTexture = null;
        //RenderTexture.active = null;
        return texture2D;
    }
(5)将 Texture2D 转 Mat 并经过 OpenCV 灰度处理输出到RawImage
    void Tex2D_to_Mat_show(Texture2D tex)
    {
        //Texture2D -> Mat
        Mat srcMat = OpenCvSharp.Unity.TextureToMat(tex);
        
        Mat grayMat = new Mat();
        Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.RGBA2GRAY);

        // Mat → Texture2D
        if (this.dstTexture == null)
        {
            this.dstTexture = new Texture2D(grayMat.Width, grayMat.Height, TextureFormat.RGBA32, false);
        }

        OpenCvSharp.Unity.MatToTexture(grayMat, this.dstTexture);

        // 表示
        GameObject.FindObjectOfType<RawImage>().texture = this.dstTexture;
    }

5、回到Unity,将渲染器纹理附加脚本上

6、创建一个cube,加上旋转脚本使其自转

旋转代码 Rotate:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
///
/// </summary>
public class Rotate : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }
    public float speed = 90f;
    // Update is called once per frame
    void Update()
    {
        this.transform.Rotate(Vector3.up * Time.deltaTime * speed);
    }
}

7、添加RawImage

   

8、运行测试

被灰度化后的图像上的Cube在不断旋转,成功

9、Get_cam_new源代码

using UnityEngine;
using UnityEngine.UI;
using OpenCvSharp;

public class Get_cam_new : MonoBehaviour
{

    //このScriptはMainCameraにアタッチしてください
    public RenderTexture renderTexture;             //mainCameraにつけるRendertexture(アタッチしてね)
    Texture2D kakunin, dstTexture;                  
    Camera mainCamera;
    GameObject hand;

    void Start()
    {
        //mainCamera = GetComponent<Camera>();
        //kakunin = CreateTexture2D(renderTexture);
        //Tex2D_to_Mat_show(kakunin);
    }
    private void Update()
    {
        mainCamera = GetComponent<Camera>();
        kakunin = CreateTexture2D(renderTexture);
        Tex2D_to_Mat_show(kakunin);
    }

    /// <summary>
    /// ここでTextur2Dに変換しているよ
    /// </summary>
    /// <param name="rt"></param>
    /// <returns></returns>
    Texture2D CreateTexture2D(RenderTexture rt)
    {
        //Texture2Dを作成
        Texture2D texture2D = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, false);

        //subCameraにRenderTextureを入れる
        mainCamera.targetTexture = rt;

        //手動でカメラをレンダリングします
        mainCamera.Render();

        RenderTexture.active = rt;
        texture2D.ReadPixels(new UnityEngine.Rect(0, 0, rt.width, rt.height), 0, 0);
        texture2D.Apply();

        ////元に戻す別のカメラを用意してそれをRenderTexter用にすれば下のコードはいらないです。
        //mainCamera.targetTexture = null;
        //RenderTexture.active = null;
        return texture2D;
    }

    void Tex2D_to_Mat_show(Texture2D tex)
    {
        //Texture2D -> Mat
        Mat srcMat = OpenCvSharp.Unity.TextureToMat(tex);
        
        Mat grayMat = new Mat();
        Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.RGBA2GRAY);

        // Mat → Texture2D
        if (this.dstTexture == null)
        {
            this.dstTexture = new Texture2D(grayMat.Width, grayMat.Height, TextureFormat.RGBA32, false);
        }

        OpenCvSharp.Unity.MatToTexture(grayMat, this.dstTexture);

        // 表示
        GameObject.FindObjectOfType<RawImage>().texture = this.dstTexture;
    }
}

以上

本文作者:HanaKoo

本文链接:https://www.cnblogs.com/HanaKoo/p/16206089.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   HanaKoo  阅读(1525)  评论(6编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
@format
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 Tiny Light(TV动画《地缚少年花子君》ED)(翻自 鬼頭明里) 柚卟
Tiny Light(TV动画《地缚少年花子君》ED)(翻自 鬼頭明里) - 柚卟
00:00 / 00:00
An audio error has occurred.

作词 : Saku

作曲 : Saku

優しさに触れて残る温度

消えないまま 愛しいと言えたら

心は軽くなるかな

閉ざした扉の向こうで

微かな声が聴こえてる

踏み出すことさえも出来ないから

孤独に寄り添ってる

まだこの胸の中 生きづいたまま

小さな灯し火のような想いを

風に吹かれぬように

雨に濡れないように

ずっと抱きしめてた

ただ 真っ直ぐなまま願う強さも

泣き出しそうになる脆い自分も

君が居なきゃ知らなかったんだよ

偶然の中で運命を見つけた

瞳閉じる度 記憶の海 漂っては

深い夢のあと

面影を探してたんだ

変わらないモノクロの日々に

君が色を添えてくから

滲んだ過去さえもいつの間にか

意味を持ち始めてる

まだこの胸の中隠したままの

痛いほど愛おしい こんな思いを

いつか消えてしまうその前に

届けたい人は 君だけなんだ

どんな涙も どんな笑顔も

全ては君のためにあるから

まだこの胸の中 生きづいたまま

小さな灯し火のような想いを

風に吹かれぬように

雨に濡れないように

ずっと抱きしめてた

ただ 真っ直ぐなまま願う強さも

泣き出しそうになる脆い自分も

君が居なきゃ知らなかったんだよ

偶然の中で運命を見つけた

君がいるだけで世界は変わった