LoginSignup
3
3

More than 3 years have passed since last update.

【Unity】【 OpenCV for Unity】 RawImageに描画した動画を動画ファイルにして保存

Posted at

投稿し過ぎ感。。
だが、させてくれ。
今日一日(いやそれ以上?)、まーまーはまらなそうなとこではまったんだから:punch_tone1:

前回(https://qiita.com/wirsind55/items/35b411ae4d618ad09f47)、
OpenCV For UnityでVideoWrite出来んと嘆きを入れたところ、
@utibenkei さんの優しさによって見事に解決に至った翌日00:30である(どんだけはまるねん、とは言わない)。

ここまで出来ればやはりもうちょっと格好をつけたい(今は真っ黒な画面の動画が出来てるだけだから)。
やったことは、VideoPlayerでRenderTextureに描画し、それをUPDATE()から毎フレーム取り出し、
動画ファイルを作っていくということである!

まず、
UnityのRaw ImageにVideoPlayerを追加して、
動画をRawImageに描画する(細かいやり方は割愛。画面HCだけ貼っとく。
image.png

上記手順は大体はこちらを参考にした感じだったので知りたい方はご参考に
【Unity】VideoPlayerの使い方 – 動画再生をマスターしよう! https://xr-hub.com/archives/15798 )

で、
この素晴らしいスクリプトを任意のGameObjectにアタッチ。

Cap.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.VideoioModule;
using OpenCVForUnity.VideoModule;
using UnityEngine.UI;

public class Cap : MonoBehaviour
{
    private VideoWriter _videoWriter;
    private int cnt = 0;

    // Start is called before the first frame update
    void Start()
    {
        _videoWriter = new VideoWriter(@"C:\Users\hiro\openCvSample\output.avi", VideoWriter.fourcc('M', 'J', 'P', 'G'), 60.0, new Size(256, 256), true);
        //_videoWriter = new VideoWriter(@"C:\Users\hiro\openCvSample\output.mp4", VideoWriter.fourcc('m', 'p', '4', 'v'), 60.0, new Size(256, 256), true);
        Debug.Log(System.IO.Directory.GetCurrentDirectory());
    }

    // Update is called once per frame
    void Update()
    {
        if(cnt < 500)
        {
            CaptchaScreen();
            //cnt.ToString() + ".png");
        }else if(cnt == 500)
        {
            Debug.Log("Dispoooooose");
            _videoWriter.Dispose();
        }

        cnt++;
    }

    public void CaptchaScreen()
    {
        RawImage raw = GameObject.Find("RawImage").GetComponent<RawImage>();
        Texture2D tex2 = TextureToTexture2D(raw.texture);

        Mat srcMat = new Mat(new Size(256, 256), CvType.CV_8UC4);
        OpenCVForUnity.UnityUtils.Utils.texture2DToMat(tex2, srcMat);

        _videoWriter.write(srcMat);
    }

    private Texture2D TextureToTexture2D(Texture texture)
    {
        Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false);
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32);
        Graphics.Blit(texture, renderTexture);

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

        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(renderTexture);
        return texture2D;
    }
}

やってることは単純(少し調子に乗る)。

動画を描画しているRenderTexture
⇒Texture ⇒ Texuture2D ⇒ Mat へと変換させていき
最後はVideoWriter.write()にぶち込むという戦略でござる。

これで所定の位置に動画が出来たよ。

image.png

以上、どどん!

3
3
0

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
3
3