You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARCore for Unity保存相机图像识别二维码异常:图像比例失真重复

解决Unity ARCore相机图像转RGB后比例异常、二维码无法识别的问题

我之前也踩过这个坑!ARCore通过Frame.CameraImage.AcquireCameraImageBytes()获取的是YUV_420_888格式的原始图像数据,不是直接可用的RGB格式。如果直接粗暴转换,会因为YUV的4:2:0采样特性导致像素排列错误,出现图像拉伸、重复的情况,二维码自然就识别不了了。

下面给你一步步解决:

核心问题拆解

  • 格式不匹配:YUV_420_888是平面格式,Y、U、V分量分开存储,且U/V分量的分辨率是Y的一半,直接转RGB会导致像素映射错误。
  • 尺寸不匹配:如果你的Texture2D尺寸和相机原始图像尺寸不一致,拉伸后会让二维码变形,无法被识别器正确解析。

修正后的完整代码示例

using UnityEngine;
using GoogleARCore;
using ZXing;
using ZXing.Common;
using System.Collections.Generic;

public class ARQRCodeScanner : MonoBehaviour
{
    private Texture2D _cameraTexture;
    private BarcodeReader _barcodeReader;

    void Update()
    {
        // 每3帧处理一次,优化性能(可选)
        if (Time.frameCount % 3 != 0)
            return;

        using (var cameraImage = Frame.CameraImage.AcquireCameraImageBytes())
        {
            if (!cameraImage.IsAvailable)
                return;

            // 初始化/更新纹理:确保尺寸和相机图像完全一致
            if (_cameraTexture == null || 
                _cameraTexture.width != cameraImage.Width || 
                _cameraTexture.height != cameraImage.Height)
            {
                // 用RGBA32格式,兼容大多数识别库
                _cameraTexture = new Texture2D(cameraImage.Width, cameraImage.Height, TextureFormat.RGBA32, false);
                
                // 初始化二维码识别器,指定只识别QR码
                _barcodeReader = new BarcodeReader
                {
                    Options = new DecodingOptions
                    {
                        TryHarder = true, // 提高识别成功率
                        PossibleFormats = new List<BarcodeFormat> { BarcodeFormat.QR_CODE }
                    }
                };
            }

            // 用ARCore官方方法转换YUV到Color32,避免手动计算出错
            var colorPixels = new Color32[cameraImage.Width * cameraImage.Height];
            cameraImage.CopyToColor32(colorPixels);

            // 更新纹理并应用
            _cameraTexture.SetPixels32(colorPixels);
            _cameraTexture.Apply();

            // 执行二维码识别
            var scanResult = _barcodeReader.Decode(
                _cameraTexture.GetPixels32(), 
                _cameraTexture.width, 
                _cameraTexture.height);
            
            if (scanResult != null)
            {
                Debug.Log($"识别到二维码内容:{scanResult.Text}");
                // 这里添加你的业务逻辑,比如跳转、显示内容等
            }
        }
    }

    // 销毁时释放资源
    void OnDestroy()
    {
        if (_cameraTexture != null)
            Destroy(_cameraTexture);
    }
}

关键注意事项

  • 用官方转换方法:cameraImage.CopyToColor32()是ARCore提供的原生转换方法,能完美处理YUV_420_888到RGB的映射,这是解决比例和重复问题的核心,别自己手动计算YUV分量,容易出错。
  • 严格匹配尺寸:必须保证Texture2D的宽高和cameraImage.Width/cameraImage.Height完全一致,任何拉伸都会导致二维码变形。
  • 性能优化:每帧处理相机图像和二维码识别会比较耗性能,建议隔几帧处理一次(比如示例中的每3帧),根据你的需求调整频率。
  • 资源释放:用using包裹CameraImage确保及时释放,销毁脚本时记得销毁Texture2D,避免内存泄漏。

内容的提问来源于stack exchange,提问作者balaji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:09:19