ARCore之路-计算机视觉之实例(五)

版权声明:David Wang原创ARCore文章,仅供学习研究之用,不得用于任何商业目的,未经授权不得转载! https://blog.csdn.net/yolon3000/article/details/86258887

  我们假定读者开发环境已完全符合上述要求,如不符合请下载安装相关组件插件。接下来我们将利用TensorFlowSharp来开发AR物体识别功能。

一、安装Unity TensorFlow Plugin插件

  我们这里使用的是0.3版的Unity TensorFlow Plugin,导入到unity工程中,如下图所示:

DavidWang原创
  导入后会在Assets目录下创建ML-Agents文件夹,包含有Computer、Android、ios各平台下的TensorFlowSharpt动态链接库及相应的Tensorflow代码库。

二、编写代码

  在Scripts文件夹下新建PhoneCamera脚本,这个脚本的主要作用是获取摄像头图像,将图像信息连同设置好的训练模型及标签传递给TensorFlow进行识别,同时还处理图像高宽比、识别图像大小 、在图像上画矩形框等操作。关键代码如下:

//进行摄像头获取图像的相应处理
 private void Update()
    {
        if(!this.camAvailable)
        {
            return;
        }
        float ratio = (float)backCamera.width / (float)backCamera.height;
        fitter.aspectRatio = ratio;
        float scaleY = backCamera.videoVerticallyMirrored ? -1f : 1f;
        background.rectTransform.localScale = new Vector3(1f, scaleY, 1f);
        int orient = -backCamera.videoRotationAngle;
        background.rectTransform.localEulerAngles = new Vector3(0, 0, orient);
    }
  //调用图像识别代码对图像中物体进行识别
    private async void TFDetect()
    {
        UpdateBackgroundOrigin();
        var snap = TakeTextureSnap();
        var scaled = Scale(snap, detectImageSize);
        var rotated = await RotateAsync(scaled.GetPixels32(), scaled.width, scaled.height);
        this.boxOutlines = await this.detector.DetectAsync(rotated);
        Destroy(snap);
        Destroy(scaled);
    }

  在PhoneCamera代码中,我们只是调用了图像识别方法,现在我们来真实实现图像识别功能。在Scripts文件夹下新建Detector脚本,该脚本就是图像识别的执行代码,主要思路就是调用TensorFlow,利用训练好的模型输入的图像进行物体识别。关键代码如下:

public Detector(byte[] model, string[] labels, int inputSize)
        {
            TensorFlowSharp.Android.NativeBinding.Init();
            this.labels = labels;
            this.inputSize = inputSize;
            this.graph = new TFGraph();
            this.graph.Import(new TFBuffer(model));
        }

        public Task<List<BoxOutline>> DetectAsync(Color32[] data)
        {
            return Task.Run(() =>
            {
                using (var session = new TFSession(this.graph))
                using (var tensor = TransformInput(data, this.inputSize, this.inputSize))
                {
                    var runner = session.GetRunner();
                    runner.AddInput(this.graph["image_tensor"][0], tensor)
                          .Fetch(this.graph["detection_boxes"][0],
                                 this.graph["detection_scores"][0],
                                 this.graph["detection_classes"][0],
                                 this.graph["num_detections"][0]);
                    var output = runner.Run();
                    var boxes = (float[,,])output[0].GetValue(jagged: false);
                    var scores = (float[,])output[1].GetValue(jagged: false);
                    var classes = (float[,])output[2].GetValue(jagged: false);                        
                    foreach(var ts in output)
                    {
                        ts.Dispose();
                    }
                    return GetBoxes(boxes, scores, classes, MINIMUM_CONFIDENCE);
                }
            });
        }

三、代码及环境设置

  前文说过,我们需要使用Tensorflow训练的模型集以及标签集(Lables)。为了降低移动设备的开销,我们使用专们为移动设备优化的模型集ssd_mobilenet_v1_android_export,以及精减的标签集coco_labels_list。
  为使用TensorFlowSharp,我们还需要对项目进行如下设置:
  1、Edit -> Project Settings ->Player -> Other settings 在 Scripting Define Symbols 里添加 ENABLE_TENSORFLOW ;
  2、Edit -> Project Settings ->Player -> Other settings将Scripting runtime version 设为 .NET 4.x Equivalent;
  3、Edit -> Project Settings ->Player -> Other settings将Api Compatibility Level 设为 .NET 4.x。

DavidWang原创
  在场景摄像机下挂载我们的获取相机图像的脚本PhoneCamera,并将模型文件ssd_mobilenet_v1_android_export及标签文件coco_labels_list赋给对应变量。如下图所示:
DavidWang原创
  设置好所有这些之后,编译、运行,效果如下图所示:
DavidWang原创

猜你喜欢

转载自blog.csdn.net/yolon3000/article/details/86258887