连接OpenCV到iOS项目中
本文学习在项目中添加OpenCV库的设置方法和调用OpenCV库函数的方法。
学习UIImage和cv::Mat之间相互转换。
准备
下载ios版本的 opencv库文件 opencv2.framework本例中使用3.0。解压。
步骤
- 继续使用学习笔记(2)的工程。将解压所得的framework拖入项目侧边栏中
在ViewController.h中加入opencv头文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14#import <UIKit/UIKit.h>
#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
using namespace cv;
@interface ViewController : UIViewController{
UIImage* image;
Mat cvImage;
}
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
- 修改ViewController.m文件名为ViewController.mm ,\.mm*表示object c++ 文件。因为opencv是用c++写的。
编辑ViewController.mm中的viewDidLoad()方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
image = [UIImage imageNamed:@"lena_std.tif"];
if (image!=nil) {
//转换image中的UIImage * 格式图像到Mat格式,结果存到cvImage中
UIImageToMat(image, cvImage);
}
if (!cvImage.empty()) {
Mat cvGrayImage;
//转换cvImage中的图像到单通道灰度图像,结果存到cvGrayImage中
cvtColor(cvImage, cvGrayImage, COLOR_BGR2GRAY);
//高斯模糊去除cvGrayImage中微小的边缘,结果存到cvGrayImage中
GaussianBlur(cvGrayImage, cvGrayImage, cv::Size(5,5), 1.2, 1.2);
//Canny算法得到cvGrayImage中图像的边缘,结果存到cvGrayImage中
Canny(cvGrayImage, cvGrayImage, 0, 50);
//设置cvImage中图像的所有像素为灰度色
cvImage.setTo(Scalar::all(255));
//设置cvImage中图像的边缘部分像素为蓝色
cvImage.setTo(Scalar(0,128,255,255),cvGrayImage);
//转换cvImage中的Mat格式图像到UIImage* 格式并且在imageView组件显示
imageView.image=MatToUIImage(cvImage);
}
}运行程序查看效果。
解释
- framework 简化了处理依赖关系的过程。framework封装了头文件和bin文件,这些文件的依赖关系由xcode处理,我们无须手动处理include 路径。我们也不需要手动处理不同架构(比如armv7,armv7s和x86),xcode会根据不同的编译配置自动寻找合适的库。
- 通常ios应用程序用Objective-C语言,头文件是 *.h , 源代码文件 *.m。Objective-C语言是C语言的超集,所以可以在Objective-C文件中加入C语言。同理,Objective-C++文件中可以加入C++。OpenCv是用C++写的,所以需要使用Objective-C++。Objective-C++文件的后缀名是 *.mm
- 加入
using namespace cv;
声明使用opencv的命名域空间。这样可以在后续调用opencv方法时显得简化一些。例如cv::Mat 只要写成 Mat就好了。 - 在viewDidLoad()中,我们调用
UImageToMat
方法转换UIImage对象到cv::Mat
对象。但请不要频繁调用这个方法,这样做会消耗内存影响程序性能。UImageToMat
和MatToUIImage
方法在头文件中定义。 - 在转换完成图像后,使用opencv做了一些简单的图像处理。首先是转换cvImage中的图像到单通道灰度图像。然后使用高斯模糊去除cvGrayImage中微小的边缘;接着使用Canny算法检测cvGrayImage中图像的边缘。为了显示效果,创建了一幅白色背景,边缘像素设置为蓝色的图像。最后调用
MatToUIImage
将cv::Mat
对象转回UIImage并在屏幕上显示。 - 在viewDidLoad()中,使用:
image = [UIImage imageNamed:@"lena_std.tif"];
方法加载图片有内存溢出的风险。
可以使用如下两句替代:
1 | NSString * path = [[NSBundle mainBundle] pathForResource:@"lena_std" ofType:@"tif"]; |