利用OpenCVForUnity插件在Unity中录制一小段摄像机视频

有时希望录一小段unity某个摄像机的画面作为演示demo,虽然OpenCV是图像处理库,但是录一小段视频还是可以实现的,具体过程如下,只需给摄像机贴上一个脚本。

大概有几个需要注意的地方:

1、Texture2D的创建是宽*高,但Mat是高*宽

2、Texture2D是RGB色彩,而需要被VedioWriter使用的是BGR的Mat对象,需要用  Imgproc.cvtColor这个方法转换

3、使用OnPostRender()进行每帧的采集,这个函数是在每帧渲染完成后调用的

4、VedioWriter最好创为fourcc('M', 'J', 'P', 'G'),并且保存为avi格式

5、录制完后一定要release掉VedioWriter,否则视频可能打不开

6、下面给出代码需要自己添加按钮并绑定其中的OnClick()方法

using UnityEngine;
using OpenCVForUnity;
using UnityEngine.UI;
public class lushipin : MonoBehaviour
{
    const int maxframecount = 1000;    //最大录制帧数,按实际情况修改
    
    int framecount;                    //当前帧 

    Texture2D ScreenTexture;           //截图的texture2D
    
    Mat FrameRgbMat;                   //截图的Mat
    
    VideoWriter Writer;                //OpenCV的VedioWriter

    bool IsRecording;                  //是否在录制的flag

    void Start()
    {
        Writer = new VideoWriter(@"D:\opencvimage\2.avi", VideoWriter.fourcc('M', 'J', 'P', 'G'), 30, new OpenCVForUnity.Size(Screen.width, Screen.height));
        if (!Writer.isOpened())
        {
            Debug.LogError("writer.isOpened() false");
            Writer.release();
            return;
        }
        FrameRgbMat = new Mat(Screen.height, Screen.width, CvType.CV_8UC3);
        ScreenTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
        framecount = 0;
        IsRecording = false;
    }
    public void OnClick()           //注意public 与按钮绑定的方法,用于开始或停止录制
    {
        if (IsRecording == false)
        {
            IsRecording = true;
            Debug.Log("开始录制");
        }
        else
        {
            IsRecording = false;
            Debug.Log("录制结束");
            if (Writer != null)
                Writer.release();
        }
    }
    void OnPostRender()              //每渲染完一帧后
    {
        if (IsRecording)
        {
            if (framecount >= maxframecount ||FrameRgbMat.width() != Screen.width || FrameRgbMat.height() != Screen.height)     //达到最大帧数
            {
                IsRecording = false;
                Debug.Log("录制结束");
                if(Writer!=null)
                Writer.release();
                return;
            }
            framecount++;
            ScreenTexture.ReadPixels(new UnityEngine.Rect(0, 0, Screen.width, Screen.height), 0, 0);
            ScreenTexture.Apply();
            Utils.texture2DToMat(ScreenTexture, FrameRgbMat);
            Imgproc.cvtColor(FrameRgbMat, FrameRgbMat, Imgproc.COLOR_RGB2BGR);
            Writer.write(FrameRgbMat);
            Debug.Log("已录制:" + framecount.ToString()+"帧");
        }
    }
    void OnApplicationQuit()
    {
        Debug.Log("退出");
    }
}

附:绑定按钮触发方法

发布了5 篇原创文章 · 获赞 11 · 访问量 1934

猜你喜欢

转载自blog.csdn.net/jiaoqiao123/article/details/86590097