3
votes

We have implemented the QR detection functionality using ZXing.dll in Unity 5.3.4f1 with Vuforia Unity SDK 5.5.9. We have a QR detection script on GameObject which remains active throughout the app and using below mentioned (QRScanner.cs) code ( as mentioned on Unity Zxing QR code scanner integration ).

We are also using Vuforia for image detection (50 image targets) in the same scene where QR detection is expected. The Vuforia plugin is getting enabled / disabled multiple times as per our requirement. Both the image and QR detection is working perfectly for us on Android and iOS devices until the app is in focus. Whenever VuforiaBehaviour gets disabled and enabled, QR detection stops working after that. QRScanner script always receives null data after the app is resumed or AR camera is reloaded. We have tried keeping our QR detection script on AR camera prefab and also tried

qcarBehaviour.RegisterTrackablesUpdatedCallback(OnTrackablesUpdated); qcarBehaviour.RegisterQCARStartedCallback(OnTrackablesUpdated);

callbacks every time AR camera starts but with no success. The QR detection stops working completely after pausing Vuforia plugin for any reason.

Does anybody have any idea how to fix this issue?

QRScanner.cs

  using UnityEngine;
  using System;
  using System.Collections;
  using Vuforia;
  using System.Threading;
  using ZXing;
  using ZXing.QrCode;
  using ZXing.Common;

  /*        /////////////////   QR detection does not work in editor    ////////////////    */

  [AddComponentMenu("System/QRScanner")]
  public class QRScanner : MonoBehaviour
  { 
    private bool cameraInitialized;
    private BarcodeReader barCodeReader;
    public AppManager camScript;

    void Start()
    { 
        barCodeReader = new BarcodeReader();
        StartCoroutine(InitializeCamera());
    }

    private IEnumerator InitializeCamera()
    {
        // Waiting a little seem to avoid the Vuforia's crashes.
        yield return new WaitForSeconds(3f);

        var isFrameFormatSet = CameraDevice.Instance.SetFrameFormat(Image.PIXEL_FORMAT.RGB888, true);
        Debug.Log(String.Format("FormatSet : {0}", isFrameFormatSet));

        // Force autofocus.
  //        var isAutoFocus = CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
  //        if (!isAutoFocus)
  //        {
  //            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
  //        }
  //        Debug.Log(String.Format("AutoFocus : {0}", isAutoFocus));
        cameraInitialized = true;
    }

    private void Update()
    {
        if (cameraInitialized)
        {
            try
            {
                var cameraFeed = CameraDevice.Instance.GetCameraImage(Image.PIXEL_FORMAT.RGB888);
                if (cameraFeed == null)
                {
                    return;
                }
                var data = barCodeReader.Decode(cameraFeed.Pixels, cameraFeed.BufferWidth, cameraFeed.BufferHeight, RGBLuminanceSource.BitmapFormat.RGB24);
                if (data != null)
                {
                    // QRCode detected.
                    Debug.Log(data.Text);
                    Application.OpenURL (data.Text); // our function to call and pass url as text
                    data = null;        // clear data
                }
                else
                {
                    Debug.Log("No QR code detected !");
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
        }
    }
  }
1

1 Answers

0
votes

i have this problem to but i fix that with place code on ARcam

using UnityEngine;
using System.Collections;
using Vuforia;

public class CameraSettings : MonoBehaviour
{
    #region PRIVATE_MEMBERS
    private bool mVuforiaStarted = false;
    private bool mAutofocusEnabled = true;
    private bool mFlashTorchEnabled = false;
    private CameraDevice.CameraDirection mActiveDirection = CameraDevice.CameraDirection.CAMERA_DEFAULT;
    #endregion //PRIVATE_MEMBERS


    #region MONOBEHAVIOUR_METHODS
    void Start ()  {
        Debug.Log("CameraSettings Start");
        VuforiaAbstractBehaviour vuforia = FindObjectOfType<VuforiaAbstractBehaviour>();
        VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
        VuforiaARController.Instance.RegisterOnPauseCallback(OnPaused);
        VuforiaARController.Instance.RegisterTrackablesUpdatedCallback (OnTrack);
        //VuforiaARController.Instance.RegisterVideoBgEventHandler(BgEventHandler);
    }
    #endregion // MONOBEHAVIOUR_METHODS


    #region PUBLIC_METHODS
    public bool IsFlashTorchEnabled()
    {
        return mFlashTorchEnabled;
    }

    public void SwitchFlashTorch(bool ON)
    {
        if (CameraDevice.Instance.SetFlashTorchMode(ON))
        {
            Debug.Log("Successfully turned flash " + ON);
            mFlashTorchEnabled = ON;
        }
        else
        {
            Debug.Log("Failed to set the flash torch " + ON);
            mFlashTorchEnabled = false;
        }
    }

    public bool IsAutofocusEnabled()
    {
        return mAutofocusEnabled;
    }

    public void SwitchAutofocus(bool ON)
    {
        if (ON)
        {
            if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO))
            {
                Debug.Log("Successfully enabled continuous autofocus.");
                mAutofocusEnabled = true;
            }
            else
            {
                // Fallback to normal focus mode
                Debug.Log("Failed to enable continuous autofocus, switching to normal focus mode");
                mAutofocusEnabled = false;
                CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
            }
        }
        else
        {
            Debug.Log("Disabling continuous autofocus (enabling normal focus mode).");
            mAutofocusEnabled = false;
            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
        }
    }

    public void TriggerAutofocusEvent()
    {
        // Trigger an autofocus event
        CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_TRIGGERAUTO);

        // Then restore original focus mode
        StartCoroutine(RestoreOriginalFocusMode());
    }

    public void SelectCamera(CameraDevice.CameraDirection camDir)
    {
        if (RestartCamera (camDir)) 
        {
            mActiveDirection = camDir;

            // Upon camera restart, flash is turned off
            mFlashTorchEnabled = false;
        }
    }

    public bool IsFrontCameraActive()
    {
        return (mActiveDirection == CameraDevice.CameraDirection.CAMERA_FRONT);
    }
    #endregion // PUBLIC_METHODS


    #region PRIVATE_METHODS
    private void OnTrack() {
        //Debug.Log("CameraSettings OnTrack");
    }
    private void BgEventHandler() {
        //Debug.Log("CameraSettings BgEventHandler");
    } 
    private void OnVuforiaStarted() {
        //Debug.Log("CameraSettings OnVuforiaStarted");
        mVuforiaStarted = true;
        // Try enabling continuous autofocus
        SwitchAutofocus(true);
        //RestartCamera (CameraDevice.CameraDirection.CAMERA_DEFAULT);
    }

    private void OnPaused(bool paused) {
        bool appResumed = !paused;
        //Debug.Log("CameraSettings OnPaused");
        if (appResumed && mVuforiaStarted)
        {
            // Restore original focus mode when app is resumed
            if (mAutofocusEnabled)
                CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
            else
                CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);

            // Set the torch flag to false on resume (cause the flash torch is switched off by the OS automatically)
            mFlashTorchEnabled = false;
        }
    }

    private IEnumerator RestoreOriginalFocusMode()
    {
        // Wait 1.5 seconds
        yield return new WaitForSeconds(1.5f);

        // Restore original focus mode
        if (mAutofocusEnabled)
            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        else
            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
    }

    private bool RestartCamera(CameraDevice.CameraDirection direction)
    {
        ObjectTracker tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        if (tracker != null)
            tracker.Stop();

        CameraDevice.Instance.Stop();
        CameraDevice.Instance.Deinit();

        if (!CameraDevice.Instance.Init(direction))
        {
            Debug.Log("Failed to init camera for direction: " + direction.ToString());
            return false;
        }
        if (!CameraDevice.Instance.Start())
        {
            Debug.Log("Failed to start camera for direction: " + direction.ToString());
            return false;
        }

        if (tracker != null)
        {
            if (!tracker.Start())
            {
                Debug.Log("Failed to restart the Tracker.");
                return false;
            }
        }

        return true;
    }
    #endregion // PRIVATE_METHODS
}