Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Background subtraction C# implementation

Using a Unity asset for OpenCV which in turn is based on OpenCV for Java. Background subtraction IS supported however no code samples so I am trying to get something working based on OpenCV Java samples online. The folowing compiles correctly and we correctly see the webcamTexture, however stumped on getting the computed foreground mask(_fgMask) to either display or properly mask the original image.

The problem area is immediately after the processFrame() method call in my Update loop.

Not absolutely sure if I need to be creating a new Bitmap instance as well

Can any OpenCV and or C# experts possibly help?

using OpenCVForUnity;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using UnityEngine;

public class OpenCV_backgroundSubtraction : MonoBehaviour
{
private WebCamTexture webCamTexture;

private WebCamDevice webCamDevice;

private Color32[] colors;


private int width = 640;

private int height = 480;

private Mat rgbaMat;

private Mat grayMat;

private Mat _fgMask;

private Mat _rgbaMat;

private Texture2D texture;

private BackgroundSubtractorMOG2 _mBGSub;
private VideoCapture _camera;

private bool initDone = false;

// Use this for initialization
private void Start()
{
StartCoroutine(init());
}

private IEnumerator init()
{
if (webCamTexture != null)
{
_minSize = (float)width / 6.0f;
_maxSize = _minSize * 1.5f;

webCamTexture.Stop();
initDone = false;

rgbaMat.Dispose();
grayMat.Dispose();
}
_mBGSub = new BackgroundSubtractorMOG2(2, 16, true);

_camera = new VideoCapture();

if (webCamTexture == null)
{
webCamDevice = WebCamTexture.devices[0];
webCamTexture = new WebCamTexture(webCamDevice.name, width, height);
}

// Starts the camera
webCamTexture.Play();

while (true)
{
if (webCamTexture.didUpdateThisFrame)
{
colors = new Color32[webCamTexture.width * webCamTexture.height];

rgbaMat = new Mat(webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);
grayMat = new Mat(webCamTexture.height, webCamTexture.width, CvType.CV_8UC1);

texture = new Texture2D(webCamTexture.width, webCamTexture.height, TextureFormat.RGBA32, false);

gameObject.GetComponent<Renderer>().material.mainTexture = texture;
// Camera.main.orthographicSize = webCamTexture.height / 2;

Camera.main.orthographicSize = webCamTexture.height / 2;
initDone = true;

break;
}
else
{
yield return 0;
}
}
}

// Update is called once per frame
private void Update()
{
Bitmap bmp = null;
// if (!initDone)
// return;

//*/

if (webCamTexture.didUpdateThisFrame)
{
Utils.webCamTextureToMat(webCamTexture, rgbaMat, colors);
_fgMask = new Mat(webCamTexture.height, webCamTexture.width, CvType.CV_8UC1);
_rgbaMat = _fgMask.clone();
processFrame();

bmp = new System.Drawing.Bitmap(100, 100, PixelFormat.Format32bppArgb);

Utils.matToTexture2D(rgbaMat, texture, colors);
}

//*/
}

protected void processFrame()//
{
_camera.retrieve(_rgbaMat, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);

_mBGSub.apply(_rgbaMat, _fgMask, 0.1);
Imgproc.cvtColor(_fgMask, _rgbaMat, Imgproc.COLOR_GRAY2BGRA, 4);
}

private void OnDisable()
{
webCamTexture.Stop();
}

private void OnGUI()
{
}
}