DJI IOS开发之三:Step By Step搭建基于DJI Phantom和iOS的计算机视觉及UAV控制开发平台
2015-05-14 17:02
453 查看
1 前言
在这之前,世界上有很多研究团队花了大量时间自己造四轴,自己开发硬件,才终于可以研究空中机器人的飞行控制,视觉等方面的问题,了不起在几年前用AR Drone来做。但我们知道AR Drone飞行范围太小,摄像头也很不稳定,因此用AR Drone来做研究有很大的局限性。现在好了,使用DJI的飞行器,我们轻而易举的拥有了一个非常棒的研究平台,去研究最前沿的问题,或者说最值得去研究的问题,那就是 计算机视觉+机器学习+机器人控制 。把这三个领域结合起来会产生什么令人兴奋的东西呢?说了一些废话,回到正题。在上一篇文章中,我介绍了如何使用iOS平台来搭建基本的计算机视觉开发环境,在本文中,我将介绍如何搭建基于DJI Phantom和iOS的开发平台。2 开发环境
Mac OS X 10.10 YosemiteXcode 6.1DJI SDK 1.0.6OpenCV for iOS 2.4.103 搭建步骤
对于基本的建立iOS工程和使用DJI SDK这里就不详细介绍了,http://blog.csdn.net/songrotek/article/details/44408081上面这篇Blog介绍了基本的使用DJI SDK的东西。那么本文主要是说明如何修改DJI SDK的东西使得我们可以直接添加OpenCV的代码对图像进行处理。链接的库如上所示,主要还是加了很多和图像处理有关的库,有的可能用不着。将DJI SDK中的ViewPreviewer文件夹直接拉进来。注意lib和header的search path:
要对应我主要在VideoPreviewer和MovieGLView两个文件进行更改
Step 1:在VideoPreviewer中添加UIImageView用于显示
@property (strong,nonatomic) UIImageView *imageView;
Step 2:在setView:中初始化这个UIImageView
-(BOOL)setView:(UIView *)view { BEGIN_DISPATCH_QUEUE if(_glView == nil){ _glView = [[MovieGLView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, view.frame.size.width/2, view.frame.size.height/2)]; _status.isGLViewInit = YES; } if (self.imageView == nil) { self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(view.frame.size.width/2, 0.0f, view.frame.size.width/2, view.frame.size.height/2)]; } dispatch_async(dispatch_get_main_queue(), ^{ [_glView setFrame:CGRectMake(0.0f, 0.0f, view.frame.size.width/2, view.frame.size.height/2)]; [view addSubview:_glView]; [view addSubview:self.imageView]; }); END_DISPATCH_QUEUE return NO; }上面的view的大小显然可以自己更改
Step 3:修改startRun的代码
主要是修改下面这一段代码:if(_status.isGLViewInit && !_status.isPause && !_status.isBackground){
UIImage *image = [_glView render:_renderYUVFrame[_renderFrameIndex]];
if(self.delegate !=nil && [self.delegate respondsToSelector:@selector(processImage:)]){
dispatch_async(dispatch_get_main_queue(), ^{
UIImageToMat(image,matImage);
[self.delegate processImage:matImage];
self.imageView.image = MatToUIImage(matImage);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
});
}
}
我更改了render这个代码,从而将glview转换为UIImage,然后对UIImage进行Mat格式转换,并设置Delegate从而在外部进行处理,然后在转换回来。使用dispatch_async从而在主线程进行操作。
Step 4:修改render代码
// grabbing image from FBO NSInteger x = 0, y = 0; NSInteger dataLength = _backingWidth * _backingHeight * 4; GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte)); glPixelStorei(GL_PACK_ALIGNMENT, 4); glReadPixels(x, y, _backingWidth, _backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, data); CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CGImageRef iref = CGImageCreate(_backingWidth, _backingHeight, 8, 32, _backingWidth * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, ref, NULL, true, kCGRenderingIntentDefault); UIGraphicsBeginImageContext(CGSizeMake(_backingWidth, _backingHeight)); CGContextRef cgcontext = UIGraphicsGetCurrentContext(); CGContextSetBlendMode(cgcontext, kCGBlendModeCopy); CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, _backingWidth, _backingHeight), iref); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); free(data); CFRelease(ref); CGImageRelease(iref); return image;在method后部添加了如上的代码实现glview转UIImage。经过上面的处理,我们在viewController就可以很方便调用了。
Step 5:ViewController的代码
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // Setup Drone self.drone = [[DJIDrone alloc] initWithType:DJIDrone_Phantom]; self.drone.delegate = self; self.drone.camera.delegate = self; // 设置视频流 [[VideoPreviewer instance] start]; [VideoPreviewer instance].delegate = self; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [[VideoPreviewer instance] setView:self.view]; [self.drone connectToDrone]; } -(void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.drone.camera startCameraSystemStateUpdates]; } -(void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.drone disconnectToDrone]; [self.drone destroy]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - DJICameraDelegate // OpenCV的处理都在下面这个Method里面 - (void)processImage:(cv::Mat &)image { cvtColor(image, image, CV_BGR2GRAY); } - (void)camera:(DJICamera *)camera didReceivedVideoData:(uint8_t *)videoBuffer length:(int)length { uint8_t *pBuffer = (uint8_t*)malloc(length); memcpy(pBuffer, videoBuffer, length); [[[VideoPreviewer instance] dataQueue] push:pBuffer length:length]; }大家看到,在ViewController的代码可以非常简单,因为整个处理过程都在ViewPreviewer中实现,在这里,可以说我们只要在processImage:里面贴Opencv的代码就OK了。
相关文章推荐
- App开发日报 2015-05-15 大疆无人机IOS开发之搭建DJI Phantom和iOS视觉平台
- Windows平台上iPhone基于cygwin开发环境的搭建方法
- [iOS_Dev] Win平台 搭建 iOS开发环境 ---- 使用VMWare虚拟机
- SDN开发之基于OpenDaylight和Mininet的试验床平台搭建
- 毕业设计项目展示作品四:基于iOS平台《百思不得姐》(似快手APP)Xcode开发技术研究与实现
- 基于Node.js平台mongoDB开发——mongoskin(by vczero)
- 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET - 对象控制反转
- Python 学习之中的一个:在Mac OS X下基于Sublime Text搭建开发平台包括numpy,scipy
- PhoneGap开发-IOS平台环镜搭建
- WinCE平台搭建--基于数据库的.NET应用程序开发(wince6.0+vs2008+sqlce)
- 区块链开发(二)Mac平台搭建基于以太坊的区块链开发环境
- 基于Swift的iOS应用程序开发:使用表格显示并控制数据(二):删除表格中的数据
- JeeFast是一款基于SpringBoot+Mybatis-Plus+Bootstrap+Vue搭建的JAVA WEB快速开发平台
- 基于Jenkins搭建iOS持续集成开发环境
- 基于Visual C++2010与windows SDK fo windows7开发windows7平台的新特性--HighDPI为视觉障碍的人服务
- s3c2410上搭建QT/Embedded4.8.5开发环境(三)--安装intel-x86嵌入式平台(基于qvfb)的qt库qt-everywhere-opensource-src-4.8.5
- 基于LBS平台的iOS开发
- 如何在IOS平台下搭建PhoneGap开发环境(PhoneGap2.5)
- 深入浅出 - Android系统移植与平台开发(六)- 搭建基于Linux的Android开发环境
- 搭建基于Windows 7 的Beagleboard开发平台: 编写一个可在Beagleboard上运行的Hello World