Unity3D IP Camera GUI Lag - PullRequest
       9

Unity3D IP Camera GUI Lag

0 голосов
/ 27 ноября 2018

Я пытаюсь получить канал IP-камеры от Unity и спроецировать его на графический интерфейс (PictureBox).Чтобы достичь канала IP-камеры, я использую ресурс с именем OpenCvforUnity .Вот мой код, который прикреплен к объекту:

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

namespace OpenCVForUnity { 
public class sourceControl : MonoBehaviour
{


    /// <summary>
    /// The videocapture.
    /// </summary>
VideoCapture capture;

/// <summary>
/// The rgb mat.
/// </summary>
Mat rgbMat;

/// <summary>
/// The texture.
/// </summary>
Texture2D texture;

/// <summary>
/// Indicates whether the video frame needs updating.
/// </summary>
bool shouldUpdateVideoFrame = false;

/// <summary>
/// The prev frame tick count.
/// </summary>
long prevFrameTickCount;

/// <summary>
/// The current frame tick count.
/// </summary>
long currentFrameTickCount;

/// <summary>
/// The FPS monitor.
/// </summary>

public string source = "http://iris.not.iac.es/axis-cgi/mjpg/video.cgi?resolution=320x240?x.mjpeg";


// Use this for initialization
void Start()
{


    capture = new VideoCapture();



    Initialize();
}

private void Initialize()
{
        capture.open(source);
        rgbMat = new Mat();

    if (!capture.isOpened())
    {
        Debug.LogError("capture.isOpened() is false. Please copy from “OpenCVForUnity/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
    }


    double ext = capture.get(Videoio.CAP_PROP_FOURCC);


    capture.grab();
    capture.retrieve(rgbMat, 0);
    int frameWidth = rgbMat.cols();
    int frameHeight = rgbMat.rows();
    texture = new Texture2D(frameWidth, frameHeight, TextureFormat.RGB24, false);

    capture.set(Videoio.CAP_PROP_POS_FRAMES, 0);

    gameObject.GetComponent<UnityEngine.UI.Image>().material.mainTexture = texture;

    StartCoroutine("WaitFrameTime");
}

void Update()
{
    if (shouldUpdateVideoFrame)
    {
        shouldUpdateVideoFrame = false;

        //Loop play
        if (capture.get(Videoio.CAP_PROP_POS_FRAMES) >= capture.get(Videoio.CAP_PROP_FRAME_COUNT))
            capture.set(Videoio.CAP_PROP_POS_FRAMES, 0);

        if (capture.grab())
        {

            capture.retrieve(rgbMat, 0);

            Imgproc.cvtColor(rgbMat, rgbMat, Imgproc.COLOR_BGR2RGB);



            Utils.fastMatToTexture2D(rgbMat, texture);
        }


    }
}

private IEnumerator WaitFrameTime()
{
    double videoFPS = (capture.get(Videoio.CAP_PROP_FPS) <= 0) ? 10.0 : capture.get(Videoio.CAP_PROP_FPS);
    int frameTime_msec = (int)Math.Round(1000.0 / videoFPS);

    while (true)
    {
        shouldUpdateVideoFrame = true;

        prevFrameTickCount = currentFrameTickCount;
        currentFrameTickCount = Core.getTickCount();

        yield return new WaitForSeconds(frameTime_msec / 1000f);
    }
}

/// <summary>
/// Raises the destroy event.
/// </summary>
void OnDestroy()
{
    StopCoroutine("WaitFrameTime");

    capture.release();

    if (rgbMat != null)
        rgbMat.Dispose();


}
}
}

(приведенный выше код взят из примера и немного изменен.) Я могу добраться до видеопотока, я могу отобразить его на объекте изображения, но проблема в том,похоже, что при каждом вызове обновления основной поток замораживается на доли секунды, поэтому вся программа отстает.

Итак, мой вопрос (ы):

Это правильный способ его реализации?

если нет;Как мне это реализовать или изменить текстуру, чтобы она не вызывала задержки.

Спасибо!

(Unity ver. 2018.2.16.f1

...