美文网首页SceneKit + ARKitUnity技术VR/AR分享
ARKit应用之识别图像播放视频

ARKit应用之识别图像播放视频

作者: 郑知鱼 | 来源:发表于2018-11-20 18:50 被阅读75次
卧闻海棠花

前言

之前实现了基于第三方EasyAR的扫卡播放视频,因为EasyAR的文档不尽完善且对iOS支持不是很好,故尝试苹果官方系统库ARKit的实现。

ARKit为iOS系统提供了对图像的识别功能。可通过检测用户环境中的已知2D图像,使用其位置放置AR内容。其中的AR内容可以是一个立体模型,也可以是一张图片或一个视频。

这一功能必将使得未来的app更加有趣,也让我们有了新的实现形式,让我们来尝试一下基于ARkit的图片识别功能在app内播放视频吧。

环境:iOS 11.3+ | Xcode 10.0+

Framework:ARkit

启用图像检测

首先,构建目标图像

目标图像即通过摄像头扫描识别的目标图像,使用自己的图像进行检测,需要将目标图像添加到Xcode中的Assets目录中。

添加目标图片
  1. 打开项目的Assets目录,然后添加新的AR资源组。
  2. 将所需添加的图片添加到创建的资源组中。
  3. 对于每个图片,使用检查器来描述你希望在用户的真实环境中找到它的图像的物理大小。(可使用预览来查看图片大小,注意单位,获取后必须添加图片的Size,图片的宽高不得小于480 pixels)

使用ARkit需要引入所需的系统库:

OBJECTIVE-C
#import <SceneKit/SceneKit.h>
#import <ARKit/ARKit.h>
SWIFT
import ARKit
import SceneKit

viewWillAppear:

OBJECTIVE-C
// 添加一个或多个目标图像
ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
configuration.detectionImages = [ARReferenceImage referenceImagesInGroupNamed:@"AR Resources" bundle:nil];

// 创建'world-tracking'配置
[self.sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking | ARSessionRunOptionRemoveExistingAnchors];

// 使用runWithConfiguration:方法使用配置运行会话
[self.sceneView.session runWithConfiguration:configuration];
SWIFT
guard let refernceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
            fatalError("Missing expected asset catalog resources.")
}
        
let configuration = ARWorldTrackingConfiguration()
configuration.detectionImages = refernceImages
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

初始化Scene View

Main.storyboard中添加ARSCNView,设置全屏幕约束。

viewDidLoad中初始化sceneView:

OBJECTIVE-C
self.sceneView.delegate = self;
SCNScene *scene = [SCNScene new];
self.sceneView.scene = scene;
SWIFT
var session: ARSession {
        return sceneView.session
}

sceneView.delegate = self
sceneView.session.delegate = self as? ARSessionDelegate

可视化图像结果

在前文中我们已经添加了识别的目标图像,当应用程序检测到目标图像时我们需要可视化图像结果,根据当前目标,我们在目标图像上播放视频。

在这里,需要实现ARSCNViewDelegate中的代理方法:

OBJECTIVE-C
#pragma mark - ARSCNViewDelegate

- (void)renderer:(id<SCNSceneRenderer>)renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor {
    ARImageAnchor *imageAnchor = (ARImageAnchor *)anchor;
    
    // 获取参考图片对象
    ARReferenceImage *referenceImage = imageAnchor.referenceImage;
    // 根据图片对象播放对应视频
    if (referenceImage.name) {
        NSString *fileName = referenceImage.name;
        [self setFileForPlayerWithFileName:fileName];
        
        SCNNode *tempNode = [SCNNode new];
        CGFloat imageWidth = referenceImage.physicalSize.width;
        CGFloat imageHeight = referenceImage.physicalSize.height;
        
        SCNBox *bgBox = [SCNBox boxWithWidth:imageWidth height:imageHeight length:0.01 chamferRadius:0];
        tempNode.geometry = bgBox;
        tempNode.eulerAngles = SCNVector3Make(-M_PI/2.0, 0.0, 0.0);
        tempNode.opacity = 1.0;
        
        SCNMaterial *material = [[SCNMaterial alloc] init];
        material.diffuse.contents = self.player;
        tempNode.geometry.materials = @[material];
        [self.player play];
        
        [node addChildNode:tempNode];
    }
}

- (void)setFileForPlayerWithFileName:(NSString *)fileName {
    NSString *urlStr = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp4"];
    NSURL *url = [NSURL fileURLWithPath:urlStr];
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
    self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
}
SWIFT
    // MARK: - ARSCNViewDelegate (Image detection results)
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let imageAnchor = anchor as? ARImageAnchor else {
            return
        }
        let referenceImage = imageAnchor.referenceImage
        if (referenceImage.name != nil) {
            initPlayer(fileName: referenceImage.name! as NSString)
            let imageWidth = referenceImage.physicalSize.width
            let imageHeight = referenceImage.physicalSize.height
            let bgBox = SCNBox(width: imageWidth, height: imageHeight, length: 0.01, chamferRadius: 0.0)
            let tempNode = SCNNode(geometry: bgBox)
            tempNode.eulerAngles = SCNVector3Make(Float(-.pi/2.0), 0.0, 0.0)
            tempNode.opacity = 1.0
            let material = SCNMaterial()
            material.diffuse.contents = player
            tempNode.geometry?.materials = [material]
            player?.play()
            
            node.addChildNode(tempNode)
        }
    }
}

var player : AVPlayer?

func initPlayer(fileName: NSString) {
    let urlStr = Bundle.main.path(forResource: fileName as String, ofType: "mp4")
    let url = URL(fileURLWithPath: urlStr ?? "")
    let playerItem = AVPlayerItem(url: url)
    player = AVPlayer(playerItem: playerItem)
}

注意

在本项目中,由于要用到相机,所以需要到info.plist中添加Privacy - Camera Usage Description

至此,我们就能简单地实现利用ARKit识别图像并播放对应的视频。

为了更加清楚的展现,附上代码以供参考:RecognizingImagesToPlayVideo

其中的视频文件可前往这里下载,当然,你也可以相应修改项目中配置更换你的目标图像和视频文件。

相关文章

  • ARKit应用之识别图像播放视频

    前言 之前实现了基于第三方EasyAR的扫卡播放视频,因为EasyAR的文档不尽完善且对iOS支持不是很好,故尝试...

  • ARKit之播放视频

    1.创建工程(不在赘述),详情请翻阅我上两篇文章!播放视频是3D和2D的结合,需要导入SpriteKit库下来就直...

  • ARKit+视频播放

    以前玩了下vuforia的视频播放,太酷了!它的视频播放是基于上传的目标上面播放,移动目标,视频也会跟着移动。但是...

  • 理解苹果ARKit 1和2

    DEMO包含功能平面检测、环境纹理、物体操作(添加、选中、拖动、缩放、旋转)、图像识别、环境音效 什么是ARKit...

  • 图像识别技术发展中的挑战

    在计算机视觉领域,近年来图像识别技术有了突飞猛进的发展,但在广泛应用之前,仍有许多挑战需要解决。本文综述了图像识别...

  • 学习笔记TF058:人脸识别

    人脸识别,基于人脸部特征信息识别身份的生物识别技术。摄像机、摄像头采集人脸图像或视频流,自动检测、跟踪图像中人脸,...

  • 视频操作

    读取并播放视频 定义的Mat变量,用于存储每一帧的图像。 用摄像头采集视频图像

  • C++车牌识别技术,实用干货分享 (内附源码)!

    车牌识别程序是利用车辆的动态视频或静态图像进行牌照号码、牌照颜色自动识别的模式识别技术。通过对图像的采集和处理,完...

  • 显示图像和视频

    OpenCV 1.0 1.显示图像 2.播放mp4视频 播放视频:循环地读取视频中的每一帧 OpenCV2.0显示...

  • ios中使用ARKit识别平面图片或真实世界对象

    ARKit1.5新增功能 iOS 11.3 上的视频分辨率提升至 1080p,其余不变; 新增竖直平面识别ARWo...

网友评论

本文标题:ARKit应用之识别图像播放视频

本文链接:https://www.haomeiwen.com/subject/xnnxqqtx.html