opencv是一个强大的计算机视觉库,对图像处理的底层函数进行了很好的封装,并提供全面的C和C++接口函数供上层开发。本文简单的介绍在xcoe中应用opencv开发一个实例的程序。
首先,为了对objective-c有个整体的了解,上张关于objective-c的图:
而关于如何在xcode中应用opencv开发iphone程序可以参考博文:IOS平台下OpenCV的配置和使用。首先,我们创建一个single view application,取名为HelloWorld_CV,记住勾选住“using storyboard"复选框。创建后的界面如下所示:
接着,点击左栏的”MainStoryboard.storyboard“文件,从”控件“中选择”UIImageView“拖到storyboard上,另外找到”toolbar“控件,也拖到storyboard上,并调整大小。完成后的界面如下所示:
接下来,打开”HelloWorld_CVViewController.h“文件,分别添加一个UIImageView和UIBarButtonItem属性,并申明一个IBAction的操作,完成后代码如下:
@interface HelloWorld_CVViewController : UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
//UIImage* image;
}
@property (nonatomic, weak) IBOutlet UIImageView* imageView;
@property (nonatomic, weak) IBOutlet UIBarButtonItem* loadButton;
- (IBAction)loadButtonPressed:(id)sender;
@end
在调用opencv中的图像处理函数之前,首先我们还要完成一件工作,那就是要实现opencv中的cv::Mat和UIImage的转换,因此先实现这个类直接的相互转换,其代码如下:
// convert cv::Mat to UIImage
static UIImage* MattoUIImage( const cv::Mat& m)
{
//CV_ASSERT(m.depth() == CV_8U);
if (m.depth() !=CV_8U)
return nil;
NSData* data = [NSData dataWithBytes:m.data length:m.elemSize()*m.total()];
CGColorSpaceRef colorSpace = m.channels() ==1 ? CGColorSpaceCreateDeviceGray():CGColorSpaceCreateDeviceRGB();
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
// Creating CGImage from cv::Mat®
CGImageRef imageRef = CGImageCreate(m.cols, m.rows, m.elemSize1()*8, m.elemSize()*8, m.step[0], colorSpace, kCGImageAlphaNoneSkipFirst|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);
UIImage* finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return finalImage;
}
// convert UIImage to cv::Mat
static void UIImagetoMat(const UIImage* image, cv::Mat& m)
{
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
CGFloat cols = image.size.width;
CGFloat rows = image.size.height;
m.create(rows, cols, CV_8UC4);
CGContextRef contextRef = CGBitmapContextCreate(m.data, cols,rows, 8, m.step[0], colorSpace, kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
}
接下来的工作就是从iphone的工作目录中加载一张图片,并调用opencv库函数处理后显示出来。思路很简单,不一一细述,直接贴代码,以下是HelloWorld_CVViewController.mm除了上面两个函数的代码:
@interface HelloWorld_CVViewController ()
@end
@implementation HelloWorld_CVViewController
@synthesize imageView;
@synthesize loadButton;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString* filename = [[NSBundle mainBundle] pathForResource:@"helloworld" ofType:@"png"];
UIImage* image = [UIImage imageWithContentsOfFile:filename];
if ( image!=nil)
{
// imageView.image = image;
cv::Mat m, gray;
UIImagetoMat(image, m);
cv::cvtColor(m, gray, CV_BGR2GRAY);
cv::GaussianBlur(gray, gray, cv::Size(5,5), 1.2,1.2);
cv::Canny(gray, gray, 0, 50);
m = cv::Scalar::all(255);
m.setTo(cv::Scalar(0,128,255,255),gray);
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image = MattoUIImage(m);
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)loadButtonPressed:(id)sender
{
UIImagePickerController* picker = [[UIImagePickerController alloc]init];
picker.delegate=self;
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
return;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
UIImage* image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
if ( image!=nil)
{
// imageView.image = image;
cv::Mat m, gray;
UIImagetoMat(image, m);
cv::cvtColor(m, gray, CV_BGR2GRAY);
cv::GaussianBlur(gray, gray, cv::Size(5,5), 1.2,1.2);
cv::Canny(gray, gray, 0, 50);
m = cv::Scalar::all(255);
m.setTo(cv::Scalar(0,128,255,255),gray);
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image = MattoUIImage(m);
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
到这里,代码部分已经完成了,接下来的工作就是要实现imageView和loadButton与storyboard对象的连接。连接方式为:按住”control“键,点击”Hello WorldCV View Controller“并拖到UIImageView控件上,选择imageView,如下图所示。同样实现loadButton与 loadButtonPressed的连接。
这个程序的代码可以通过下面的连接下载:http://download.csdn.net/detail/kezunhai/6021719