LoginSignup
2
1

More than 3 years have passed since last update.

【OpenCV for Unity】texture2DToMatは絶対に必要なので忘れないように

Last updated at Posted at 2019-05-08

OpenCV for Unityを使い始めました。基本的な画像処理で間違ったためメモします。

画像によって、うまくいかない現象が起きる

基本的な画像処理”チャネル入れ替え”の処理を作ったのですが、うまくいく画像といかない画像の2パターンがでてきました。

■うまくいった画像
スクリーンショット 2019-05-08 18.43.40.png

■うまくいかない画像
スクリーンショット 2019-05-08 19.16.07.png

画像の設定で何か問題があるのかなぁ…と思い、設定を全て揃えたのですが、うまくいかず…
スクリーンショット_2019-05-08_18_52_22.png

原因:texture2DToMatがないから

うまくいかないコードがこちらです。

RGB2BGR.cs
    void Start()
    {
        Texture2D srcTex = Resources.Load("imori") as Texture2D;

        Mat srcMat = new Mat(srcTex.height, srcTex.width, CvType.CV_8UC4);
        Mat dstMat = new Mat(srcTex.height, srcTex.width, CvType.CV_8UC4);

        Imgproc.cvtColor(srcMat, dstMat, Imgproc.COLOR_RGBA2BGRA);
        Texture2D dstTex = new Texture2D(dstMat.cols(), dstMat.rows(), TextureFormat.RGBA32, false);
        Utils.matToTexture2D(dstMat, dstTex, false);

        Sprite texture_sprite = Sprite.Create(dstTex, new UnityEngine.Rect(0, 0, dstTex.width, dstTex.height), new Vector2(-0.25f, 0.5f));
        GetComponent<SpriteRenderer>().sprite = texture_sprite;
    }

原因は致命的で、texture2DToMatがなかったためです。new Mat()だけでは初期化しかしていないので、うまくいかないのも当然であります。

修正したコードはこちらになります!

RGB2BGR.cs
    void Start()
    {
        Texture2D srcTex = Resources.Load("imori") as Texture2D;

        //ここではmatの入れ物を用意するだけ
        Mat dstMat = new Mat(srcTex.height, srcTex.width, CvType.CV_8UC4);

        //テクスチャ→Mat
        Utils.texture2DToMat(srcTex, dstMat);

        //チャネル入替
        Imgproc.cvtColor(dstMat, dstMat, Imgproc.COLOR_RGBA2BGRA);

        //Mat→テクスチャ
        Texture2D dstTex = new Texture2D(dstMat.cols(), dstMat.rows(), TextureFormat.RGBA32, false);
        Utils.matToTexture2D(dstMat, dstTex);

        //テクスチャ→sprite→表示
        Sprite texture_sprite = Sprite.Create(dstTex, new UnityEngine.Rect(0, 0, dstTex.width, dstTex.height), new Vector2(-0.25f, 0.5f));
        GetComponent<SpriteRenderer>().sprite = texture_sprite;
    }

ちゃんとチャネル変換されていることがわかります。
スクリーンショット 2019-05-08 19.28.15.png

大きな違いはUtils.texture2DToMatがあるかどうかです。うまくいっている処理は、texture2DToMatがあります。

あくまでも仮説にはなりますが、Utils.texture2DToMatなしでもうまくいったのは、Mat srcMat = new Mat(srcTex.height, srcTex.width, CvType.CV_8UC4)で元々のテクスチャをMat変換+TextureやMatの型が合致したからかもしれません。

もしOpenCV for UnityでMat変換するときは、必ずUtils.texture2DToMatを用いた方が良さそうです。
(原因が仮説段階のため、断定はしていません。もし詳細がわかる方いらっしゃりましたら、コメントいただけると嬉しいです!)

追記:2019/5/9
原因はtexture2DToMatがなかったためです。new Mat(~,~,~)でも処理が動いたのは、openCV以外の原因(キャッシュが残るなど)、他が原因になります。

コメントしてくださった@utibenkeiさん、本当にありがとうございました!!!

参考リンク

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1