qr-code - 在 Unity 中使用 ZXing 和 Vuforia 进行 QR 检测

标签 qr-code augmented-reality unity-game-engine vuforia

我们已使用 Unity 5.3.4f1 中的 ZXing.dll 和 Vuforia Unity SDK 5.5.9 实现了 QR 检测功能。我们在 GameObject 上有一个 QR 检测脚本,该脚本在整个应用程序中保持事件状态并使用下面提到的 (QRScanner.cs) 代码(如 Unity Zxing QR code scanner integration 中所述)。

我们还在预期进行 QR 检测的同一场景中使用 Vuforia 进行图像检测(50 个图像目标)。根据我们的要求,Vuforia 插件被多次启用/禁用。在 Android 和 iOS 设备上,图像和二维码检测都可以完美运行,直到应用程序聚焦为止。每当 VuforiaBehaviour 被禁用和启用时,QR 检测就会停止工作。应用程序恢复或 AR 相机重新加载后,QRScanner 脚本始终收到空数据。我们尝试过将 QR 检测脚本保留在 AR 相机预制件上,也尝试过

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

每次 AR 相机启动时都会回调,但没有成功。由于任何原因暂停 Vuforia 插件后,二维码检测完全停止工作。

有人知道如何解决这个问题吗?

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);
            }
        }
    }
  }

最佳答案

我有这个问题 但我用 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
}

关于qr-code - 在 Unity 中使用 ZXing 和 Vuforia 进行 QR 检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37968169/

相关文章:

java - 执行二维码需要导入吗?

ios - 如何从 QR Code Swift 4 中检索所有数据

Android studio com.google.ar.sceneform.ux.ArFragment 与 androidx.fragment.app.Fragment 不兼容

android - 为 android 构建统一项目(具有 firebase)时出错

iphone - Objective-C : is it possible to detect QR code data type?

php - 通过扫描二维码使用 cURL 发送 POST 数据

android - 图像目标 Vufroria 示例

ios - 将子项添加到场景 ARKit/SceneKit 时 FPS 下降

ios - unity IOS firebase 处理前台推送通知

unity-game-engine - Cinemachine - 从代码中更改来自 CinemachineVirtualCamera 的 TrackedDolly 路径