我们假定读者开发环境已完全符合上述要求,如不符合请下载安装相关组件插件。接下来我们将利用TensorFlowSharp来开发AR物体识别功能。
一、安装Unity TensorFlow Plugin插件
我们这里使用的是0.3版的Unity TensorFlow Plugin,导入到unity工程中,如下图所示:
二、编写代码
在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。