DJI IOS开发之三:Step By Step搭建基于DJI Phantom和iOS的计算

1 前言

在这之前,世界上有很多研究团队花了大量时间自己造四轴,自己开发硬件,才终于可以研究空中机器人的飞行控制,视觉等方面的问题,了不起在几年前用AR Drone来做。但我们知道AR Drone飞行范围太小,摄像头也很不稳定,因此用AR Drone来做研究有很大的局限性。

现在好了,使用DJI的飞行器,我们轻而易举的拥有了一个非常棒的研究平台,去研究最前沿的问题,,或者说最值得去研究的问题,那就是 计算机视觉+机器学习+机器人控制 。把这三个领域结合起来会产生什么令人兴奋的东西呢?

说了一些废话,回到正题。在上一篇文章中,我介绍了如何使用iOS平台来搭建基本的计算机视觉开发环境,在本文中,我将介绍如何搭建基于DJI Phantom和iOS的开发平台。

2 开发环境

Mac OS X 10.10 Yosemite

Xcode 6.1

DJI SDK 1.0.6

OpenCV for iOS 2.4.10

3 搭建步骤

对于基本的建立iOS工程和使用DJI SDK这里就不详细介绍了,

上面这篇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_QUEUEif(_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_QUEUEreturn 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 FBONSInteger 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 Droneself.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了。

有希望在的地方,痛苦也成欢乐

DJI IOS开发之三:Step By Step搭建基于DJI Phantom和iOS的计算

相关文章:

你感兴趣的文章:

标签云: