Log in or register to post comments

Getting Camera Image after scene is reloaded

February 5, 2013 - 1:58am #1

I'm having an issue on Android devices getting image data after reloading the unity scene with the latest Unity Vuforia 2.0 extension.

When the scene is first loaded the RGB image data is correct however as soon as the app is put into the background and re-run, or if another scene is loaded and then the AR Camera scene is loaded again, the RGB data isn't correct.

I am getting the camera image using :

image = CameraDevice.Instance.GetCameraImage(Image.PIXEL_FORMAT.RGB888); 

This doesn't return null and according to isValid method is valid, pixel sizes are fine, and PixelFormat still returns RGB888. However, when I check the RGB pixel colours they are not correct after the scene is reloaded.

Getting Camera Image after scene is reloaded

April 8, 2014 - 5:29am #12

Getting Camera Image after scene is reloaded

November 7, 2013 - 4:37am #11

I was switching between front and back cameras but wouldn't get the new camera's pixel data. It would still give the previous camera's last frame. Adding this line before setting frame format again, fixed it.

CameraDevice.Instance.SetFrameFormat(m_PixelFormat, false);

 

Thanks AlessandroB and joshsavage. Saved me a few hours. :)

 

Getting Camera Image after scene is reloaded

February 6, 2013 - 11:03pm #10

Great!

Getting Camera Image after scene is reloaded

February 6, 2013 - 10:43pm #9

Thanks a lot for the work around!

I tested it and it works well for when the scene is reloaded but the "Start" method isn't called when the app comes back to the foreground after say the home button is pressed.

Here is the solution that worked for me:

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

      .....

}

Thanks again for your help!

Getting Camera Image after scene is reloaded

February 6, 2013 - 3:23am #8

Hey, quick update:

I managed to find a simple workaround for that, which consists of resetting the frame format in teh Start() method of the script:

void Start(){
	// Remove the pixel format (in case it was previously set); 
	// note that we are passing "false" here
	CameraDevice.Instance.SetFrameFormat(m_PixelFormat, false);
		
        lastPrintedTime = DateTime.Now;
     
        QCARBehaviour qcarBehaviour = (QCARBehaviour) FindObjectOfType(typeof(QCARBehaviour));
        if (qcarBehaviour)
        {
            qcarBehaviour.RegisterTrackerEventHandler(this);
        }
    }

I tested it and it seems to work nicely.

Meanwhile the issue is also being tracked for a stable fix in one of our future releases, but I recommend to use the workaround above for now.

 

Getting Camera Image after scene is reloaded

February 6, 2013 - 2:18am #7

Hi, I see what you say;

indeed, I can confirm that the pixel buffer appears to be "stuck" on the same values after switching level;

I am bringing this up to the Vuforia team's attention, I will update you on the progress (also checking for some workarounds).

 

Getting Camera Image after scene is reloaded

February 5, 2013 - 8:01pm #6

I'm still having the issue. After the home button is pressed or the scene is switched the pixel values do not update. They seem frozen on the last frame before the scene change. I slightly modified your script so you will be able to more easily see what I'm talking about (see below). When you first run the script you'll see the pixel RGB values changing, then after you press the home button and then go back into the app you'll see them not updating however the camera is still visible on the screen as normal.

Thanks for taking the time to investigate this issue.

public class CameraImageAccess : MonoBehaviour, ITrackerEventHandler {
	private Image.PIXEL_FORMAT m_PixelFormat = Image.PIXEL_FORMAT.RGB888;
    private bool m_RegisteredFormat = false;
    private bool m_LogInfo = true;
	
	private DateTime lastPrintedTime;
	
	void Start(){
		lastPrintedTime = DateTime.Now;
	
		QCARBehaviour qcarBehaviour = (QCARBehaviour) FindObjectOfType(typeof(QCARBehaviour));
        if (qcarBehaviour)
        {
            qcarBehaviour.RegisterTrackerEventHandler(this);
        }
    }
     
    public void OnTrackablesUpdated(){
		if (!m_RegisteredFormat)
        {
			Debug.Log("Setting pixel format to RGB888");
            CameraDevice.Instance.SetFrameFormat(m_PixelFormat, true);
            m_RegisteredFormat = true;
        }
        if (m_LogInfo)
        {
            CameraDevice cam = CameraDevice.Instance;
            Image image = cam.GetCameraImage(m_PixelFormat);
            if (image == null)
            {
                Debug.Log(m_PixelFormat + " image is not available yet");
            }
            else
            {
				// print pixel's RGB values every sec so not to overload output
                if(TimeSpan.FromTicks(DateTime.Now.Ticks - lastPrintedTime.Ticks).TotalMilliseconds > 1000){
					string s = "[";
	                byte[] pixels = image.Pixels;
	                // Read RGB values for first 10 pixels
	                for (int i = 0; i < 10; ++i) {
						s += " R" + pixels[i] + " G" + pixels[i+1] + " B" + pixels[i+2]; 
	                }
					s += " ]";
					Debug.Log(s);
					
					lastPrintedTime = DateTime.Now;
				}
            }
        }
	}
	
	public void OnInitialized() 
    {   
    }
}

 

 

 

 

Getting Camera Image after scene is reloaded

February 5, 2013 - 9:59am #5

Hi, so, here is what I have tried:

  • creating two scenes (i.e. two game levels)
  • creating a script called CameraImageAccess and attaching it to the ARCamera object (although it does not really matters where you put it)
  • creating a second script showing a simple Button to switch level back and forth (i.e. from level0 to level1 and back from level1 to level0)

The CameraImageAccess script logs some information about the image; please have a try with it and let me know how it goes (I did not observe the issue you report using that script).

Here is the CameraImageAccess script code:

using UnityEngine;
using System.Collections;

public class CameraImageAccess : MonoBehaviour, ITrackerEventHandler
{
    private Image.PIXEL_FORMAT m_PixelFormat = Image.PIXEL_FORMAT.RGB888;
    private bool m_RegisteredFormat = false;
    private bool m_LogInfo = true;
	
    void Start()
    {
        QCARBehaviour qcarBehaviour = (QCARBehaviour) FindObjectOfType(typeof(QCARBehaviour));
        if (qcarBehaviour)
        {
            qcarBehaviour.RegisterTrackerEventHandler(this);
        }
    }
	
    public void OnTrackablesUpdated()
    {
		if (!m_RegisteredFormat)
        {
            CameraDevice.Instance.SetFrameFormat(m_PixelFormat, true);
            m_RegisteredFormat = true;
        }
        if (m_LogInfo)
        {
            CameraDevice cam = CameraDevice.Instance;
            Image image = cam.GetCameraImage(m_PixelFormat);
            if (image == null)
            {
                Debug.Log(m_PixelFormat + " image is not available yet");
            }
            else
            {
                string s = m_PixelFormat + " image: \n";
                s += "  size: " + image.Width + " x " + image.Height + "\n";
                s += "  bufferSize: " + image.BufferWidth + " x " + image.BufferHeight + "\n";
                s += "  stride: " + image.Stride;
                Debug.Log(s);
				byte[] pixels = image.Pixels;
				Debug.Log ("First 10 pixels:");
				for (int i = 0; i < 10; ++i) {
					Debug.Log("pixel byte[" + i + "] = " + pixels[i]);
				}
                m_LogInfo = false;
            }
        }
    }
	
	public void OnInitialized() 
	{	
	}
}

And here is the LevelSwitcher script code:

 

using UnityEngine;
using System.Collections;

public class LevelSwitcher : MonoBehaviour {

	void Start () {	}
	
	void Update () { }
	
	void OnGUI() 
	{
		if (GUI.Button(new Rect(0,0,200,100), "Switch Level")) 
		{
			if (Application.loadedLevelName.Equals("scene0")) 
			{
				Application.LoadLevel("scene1");
			}
			else 
			{
				Application.LoadLevel("scene0");
			}
		}
		
		if (GUI.Button(new Rect(0,100,200,100), "Exit App")) 
		{
			Application.Quit();
		}
	}
}

 

HTH.
 

 

Getting Camera Image after scene is reloaded

February 5, 2013 - 4:54am #4

Thank you for your quick response.

It is called from the Update() function of my own script that is attached to a seperate game object. The game object is not inside the AR Camera.

 

Getting Camera Image after scene is reloaded

February 5, 2013 - 4:09am #3

Hi, to help reproduce your issue, could you tell where do you use that code ? is it called from the Update() function of your own script ? is the script attached to the ARCamera ?

(so that I can setup a project as similar as possible to yours...)

 

Getting Camera Image after scene is reloaded

February 5, 2013 - 2:11am #2

I just checked iOS and it seems to be an issue as well.

Log in or register to post comments