在苹果开发者大会之后,苹果要在iOS 11 、Xcode9中添加ARKit框架,似乎AR没有那么神秘,我们早就用过了,比如QQ的视频挂件、花椒的礼物动画、还有支付宝的扫福都应该属于AR技术。今天我就浅谈视频特效挂件。

  • 思路

    • 1.通过摄像头捕获数据
    • 2.回调数据CMSampleBufferRef
    • 3.进行物体识别(人脸识别)这里用的是CoreImage的人脸识别CIDetector、也可用OpenCV等。
    • 4.显示特效(视频、GIF、图片、文字等等)
    • 5.视频本地写入
  • 涉及到的技术

    • 1.GPUImageVideoCamera的使用
    • 2.GPUImageUIElement的使用
    • 3.FLAnimatedImageView的使用
    • 4.GPUImageMovie的使用
    • 5.GPUImageFilter的使用
    • 6.CIDetector的使用

    我做的是显示GIF特效。效果图: 请忽略我的模样\( ̄︶ ̄)/

Demo没有做美颜,可查看我GPUImage其他博客、应该会有收获

完整Demo地址:

https://coding.net/u/Xoxo_x/p/VideoAndAudio/git/blob/master/GPUImage%E7%9B%B8%E6%9C%BA%E7%89%B9%E6%95%88.zip

主要步骤:

    [self initGPUImageView];//初始化GPUImageView//初始化滤镜GPUImageAlphaBlendFilter,主要用来做半透明的混合的[self initFilter];[self initCamera];//初始化相机

GPUImageUIElement 是GPUImage提供的可以将我们的普通UI转化为纹理输出到视频中

- (UIView *)elementView {if (!_elementView) {gifImageView = [[FLAnimatedImageView alloc] init];gifImageView.frame                = CGRectMake(0, 0, 160, 160);[self.view addSubview:gifImageView];NSData   *gifImageData             = [NSData dataWithContentsOfFile:[[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"hudie"] ofType:@"gif" inDirectory:nil]];[self animatedImageView:gifImageView data:gifImageData];[_elementView addSubview:gifImageView];}return _elementView;
}

FLAnimatedImageView 用于播放gif动画

    GPUImageFilter* progressFilter = [[GPUImageFilter alloc] init];[videoCamera addTarget:progressFilter];

将两个纹理输出到GPUImageView

[progressFilter addTarget:filter];[pictureView addTarget:filter];[filter addTarget:filterView];

设置处理回调

__strong typeof(self) strongSelf = self;[progressFilter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {// update capImageView's frameCGRect rect = strongSelf.faceBounds;CGSize size = gifImageView.frame.size;[UIView animateWithDuration:0.2 animations:^{gifImageView.frame = CGRectMake(rect.origin.x +  (rect.size.width - size.width)/2, rect.origin.y - size.height, size.width, size.height);}];[pictureView updateWithTimestamp:time];[strongSelf->pictureView updateWithTimestamp:time];}];

使用屏幕刷新频率

 CADisplayLink * displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onDisplayLink:)];[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

视频回调代理、获取原始数据

- (void)willOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer {if (!_faceThinking) {CFAllocatorRef allocator = CFAllocatorGetDefault();CMSampleBufferRef sbufCopyOut;CMSampleBufferCreateCopy(allocator,sampleBuffer,&sbufCopyOut);[self performSelectorInBackground:@selector(grepFacesForSampleBuffer:) withObject:CFBridgingRelease(sbufCopyOut)];}
}

将CMSampleBufferRef进行图像转化识别、提取特征

    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate);CIImage *convertedImage = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer options:(__bridge NSDictionary *)attachments];
imageOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:exifOrientation] forKey:CIDetectorImageOrientation];NSArray *features = [self.faceDetector featuresInImage:convertedImage options:imageOptions];// get the clean aperture// the clean aperture is a rectangle that defines the portion of the encoded pixel dimensions// that represents image data valid for display.CMFormatDescriptionRef fdesc = CMSampleBufferGetFormatDescription(sampleBuffer);CGRect clap = CMVideoFormatDescriptionGetCleanAperture(fdesc, false /*originIsTopLeft == false*/);

进行识别

    dispatch_async(dispatch_get_main_queue(), ^{CGRect previewBox = self.view.frame;if (featureArray.count) {gifImageView.hidden = NO;}else {
//            gifImageView.hidden = YES;return ;}for ( CIFaceFeature *faceFeature in featureArray) {// find the correct position for the square layer within the previewLayer// the feature box originates in the bottom left of the video frame.// (Bottom right if mirroring is turned on)//Update face bounds for iOS Coordinate SystemCGRect faceRect = [faceFeature bounds];// flip preview width and heightCGFloat temp = faceRect.size.width;faceRect.size.width = faceRect.size.height;faceRect.size.height = temp;temp = faceRect.origin.x;faceRect.origin.x = faceRect.origin.y;faceRect.origin.y = temp;// scale coordinates so they fit in the preview box, which may be scaledCGFloat widthScaleBy = previewBox.size.width / clap.size.height;CGFloat heightScaleBy = previewBox.size.height / clap.size.width;faceRect.size.width *= widthScaleBy;faceRect.size.height *= heightScaleBy;faceRect.origin.x *= widthScaleBy;faceRect.origin.y *= heightScaleBy;faceRect = CGRectOffset(faceRect, previewBox.origin.x, previewBox.origin.y);//mirrorCGRect rect = CGRectMake(previewBox.size.width - faceRect.origin.x - faceRect.size.width, faceRect.origin.y, faceRect.size.width, faceRect.size.height);if (fabs(rect.origin.x - self.faceBounds.origin.x) > 5.0) {self.faceBounds = rect;//                if (self.faceView) {//                    [self.faceView removeFromSuperview];//                    self.faceView =  nil;//                }////                // create a UIView using the bounds of the face//                self.faceView = [[UIView alloc] initWithFrame:self.faceBounds];////                // add a border around the newly created UIView//                self.faceView.layer.borderWidth = 1;//                self.faceView.layer.borderColor = [[UIColor redColor] CGColor];////                // add the new view to create a box around the face//                [self.view addSubview:self.faceView];}}});

然后再回到中更改蝴蝶的位置为头顶的位置

完整Demo地址:

https://coding.net/u/Xoxo_x/p/VideoAndAudio/git/blob/master/GPUImage%E7%9B%B8%E6%9C%BA%E7%89%B9%E6%95%88.zip

iOS AR之视频特效挂件(GPUImage)相关推荐

  1. iphone ios 视频特效,视频合成

    如果对av foundation 不熟悉得话,建议先看看wwdc 2010 关于av foundation得讲座.http://blog.csdn.net/linzhiji/article/detai ...

  2. 手把手实现火爆全网的视频特效 “蚂蚁呀嘿”,太魔性了

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 导读 Hi,大家好,今天是周末,今天给各位读者分享最近很火的视频特效. 将会依据现有的demo,一步步 ...

  3. 那么多短视频特效,凭什么抖音出的这么火

    萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI 说到短视频特效,你或许第一时间会想到"抖音特效". 没错,抖音的特效似乎总是火到出圈,像用一段视频让你"重返三 ...

  4. 美摄iOS端短视频SDK视频编辑的流程及方法

    美摄短视频SDK提供视频编辑功能,支持视频图片素材混合导入.滤镜.配音.时间特效.画中画等丰富的编辑效果.本文介绍iOS端短视频SDK视频编辑的流程及方法. 短视频SDK主要包含"视频录制& ...

  5. Android IOS WebRTC 音视频开发总结(三八)-- tx help

    Android IOS WebRTC 音视频开发总结(三八)-- tx help 本文主要介绍帮一个程序员解决webrtc疑问的过程,文章来自博客园RTC.Blacker,支持原创,转载请说明出处(w ...

  6. Android IOS WebRTC 音视频开发总结(二三)-- hurtc使用说明

    Android IOS WebRTC 音视频开发总结(二三)-- hurtc使用说明 本文主要介绍如何测试基于浏览器和手机的视频通话程序,转载请说明出处,文章来自博客园RTC.Blacker,更多详见 ...

  7. Android IOS WebRTC 音视频开发总结(四二)-- webrtc开发者大会

    Android IOS WebRTC 音视频开发总结(四二)-- webrtc开发者大会 本文主要介绍11月要在北京举办的webrtc开发者全球大会,文章来自博客园RTC.Blacker,支持原创,转 ...

  8. 短视频APP开发:短视频特效SDK功能火爆来袭!

    为什么短视频这么火呢?因为它符合了用户碎片化时间的需求,既娱乐了大众,又不会浪费用户太多时间. 短视频APP开发以互联网技术为核心,在原有的基础上不断进行创新,进而拥有多种强大的拍摄功能,让用户可以快 ...

  9. Android IOS WebRTC 音视频开发总结(八十七)-- WebRTC中丢包重传NACK实现分析

    Android IOS WebRTC 音视频开发总结(八十七)-- WebRTC中丢包重传NACK实现分析 本文主要介绍WebRTC中丢包重传NACK的实现,作者:weizhenwei ,文章最早发表 ...

最新文章

  1. JNI与NDK学习第二篇-----应用篇
  2. utf8乱码解决方案[适合tomcat部署的jsp应用]
  3. 201771010126.王燕《面向对象程序设计(Java)》第六周学习总结
  4. FPGA的设计艺术(4)STA实战之不同时序路径的建立保持时间计算
  5. Android 开源库获取途径整理
  6. Python 数据结构视频教程一
  7. MATLAB应用实战系列(四十四)-基于matlab的支持向量机分类、回归问题(附源码解析)
  8. iOS开发者React Native学习路线
  9. 百度api语音识别一直“无内容”_PHP开发语音识别功能
  10. OPENCV图像变换-1
  11. mysql 5.6 设置long_query_time的值无效的原因
  12. 第十八届绵竹年画节开幕 大巡游展示清末年画《迎春图》场景
  13. 让Windows Server 2008+IIS 7+ASP.NET支持10万个同时请求
  14. 如何彻底卸载3dmax2020_3DMAX 2020安装失败,怎么把3DMAX 2020彻底卸载删除干净重新安装?...
  15. InnoDB下SQL执行底层原理和redolog、binlog
  16. 图片不能置于底层怎么办_ps怎么把图片置于底层
  17. 帝国cms7.2 linux伪静态,帝国CMS7.0IIS伪静态设置教程
  18. 【推荐】推荐一款云盘 不限速 【下载免登录】【下载不限速】【2T大存储】
  19. 从硬盘中安装ubuntu 18,04
  20. 深度之眼Paper带读笔记NLP.2:word2vec.baseline.1

热门文章

  1. ios h5页面回弹
  2. 公有IP地址和私有IP地址
  3. 全国行政区划代码PHP版数据
  4. VM安装Mac os x10.11的诸多坑人问题
  5. 一块网卡,两个网口,设置两个内网IP
  6. RuntimeError: CUDA error: out of memory
  7. 通过张三与如花悲惨爱情故事,理解“用户“、“shell“、“操作系统“之间的关系
  8. python 修改excel文档
  9. F2833x烧录到FLASH芯片锁住如何解除
  10. postgresql 除法运算