Working with Vuforia

From Emgu CV: OpenCV in .NET (C#, VB, C++ and more)
Jump to: navigation, search

The following code is based on the Vuforia Tutorial to access Camera Image, with modification to convert Vuforia Image object to Emgu CV Mat.

Please follow the Vuforia Tutorial and replace the "CameraAccess" class with the following code to convert camera images to Emgu CV.

using System;
using UnityEngine;
using System.Collections;
using System.Drawing;
using System.Runtime.InteropServices;
using Vuforia;
using Emgu.CV;
using Emgu.CV.CvEnum;

public class CameraImageAccessBehaviour : MonoBehaviour
{
   //either use RGB888 or RGBA8888, depends on your camera device.
   //private Image.PIXEL_FORMAT m_PixelFormat = Image.PIXEL_FORMAT.RGB888;
   private Image.PIXEL_FORMAT m_PixelFormat = Image.PIXEL_FORMAT.RGBA8888;

   private bool m_RegisteredFormat = false;

   void Start()
   {
      VuforiaBehaviour vuforiaBehaviour = (VuforiaBehaviour)FindObjectOfType(typeof(VuforiaBehaviour));
      if (vuforiaBehaviour)
      {
         vuforiaBehaviour.RegisterTrackablesUpdatedCallback(OnTrackablesUpdated);
      }
   }

   public void OnTrackablesUpdated()
   {
      if (!m_RegisteredFormat)
      {
         if (CameraDevice.Instance.SetFrameFormat(m_PixelFormat, true))
         {
            m_RegisteredFormat = true;
         }

      }

      CameraDevice cam = CameraDevice.Instance;
      Image image = cam.GetCameraImage(m_PixelFormat);

      if (image == null)
      {
         Debug.Log("Image is not available yet");
      }
      else
      {


         byte[] pixels = image.Pixels;
         GCHandle pixelHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
         try
         {
            if (m_PixelFormat == Image.PIXEL_FORMAT.RGBA8888)
            {
               using (
                  Mat m = new Mat(new Size(image.Width, image.Height), DepthType.Cv8U, 4,
                     pixelHandle.AddrOfPinnedObject(), image.Stride))
               using (Mat alphaChannel = new Mat())
               {
                  //process the image (RGBA format) here
                  ...
               }
            }
            else if (m_PixelFormat == Image.PIXEL_FORMAT.RGB888)
            {
               using (
                  Mat m = new Mat(new Size(image.Width, image.Height), DepthType.Cv8U, 3,
                     pixelHandle.AddrOfPinnedObject(), image.Stride))
               {
                  //process the image (RGB format) here
                  ...
               }
            }
            else
            {
               string s = String.Format("Image type {0} is not supported\n", m_PixelFormat);
               s += "  size: " + image.Width + "x" + image.Height + "\n";
               s += "  bufferSize: " + image.BufferWidth + "x" + image.BufferHeight + "\n";
               s += "  stride: " + image.Stride;
               Debug.Log(s);
            }
         }
         finally
         {
            pixelHandle.Free();
         }
      }
   }
}