Background subtraction C# implementation [closed]
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()
{
}
}
what exactly is the problem ? i see no error msg or such ?
I think you're expecting something you shouldn't from these lines:
First one just saves the foreground mask in _fgMask. The second one does NOT apply any kind of masking over original image, you're just converting a 8UC1 mat (_fgMask) into a 8UC4 mat (_rgbaMat) ((and when displaying the new converted 4-channels mat, I think it is going to show as black&white anyway))
Another thing, I don't really know why this line before processing the frame:
_rgbaMat = _fgMask.clone();