支付宝(扫脸登录)、微信、QQ 、美拍、秒拍、美图秀秀……
都应用到了OpenCV
核心框架:基于OpenCV框架(图像处理框架)
OpenCV?
第一点:开源(源代码+核心算法;改进和优化)
第二点:跨平台
第三点:支持多个语言
第四点:稳定,性能高 (1999年 V1.0 ~2017.8.3年 V3.3)
首先我们先下载OpenVC中关于iOS的framework。
导入工程中。
build。
我们会发现有个error。
enum { NO, GAIN, GAIN_BLOCKS };
我们可以将其更改为
enum { NO_EXPOSURE_COMPENSATOR = 0, GAIN, GAIN_BLOCKS };
或者
enum { CNO, GAIN, GAIN_BLOCKS };
都可以解决这个问题。
#import
//支持iOS平台
#import
- (IBAction)clickImgGray:(id)sender {
Mat mat_image_src;
//第一步 : 将iOS平台的UIImage -> OpenCV图片 (Mat 数据结构)
/*
参数一: 源文件
参数二:目标文件 <#cv::Mat &m#>
*/
UIImageToMat(_imgView.image, mat_image_src);
//第二步:将彩色图片 -> 灰色
/*
在OpenCV中,有这样一个方法。
参数一:源文件
参数二:目标文件
参数三:转换类型
三通道的颜色 -> Gray
*/
Mat mat_imag_dst;
cvtColor(mat_image_src, mat_imag_dst, COLOR_BGR2GRAY);
//第三步:灰色图片 -> 可显示图片
cvtColor(mat_imag_dst, mat_image_src, COLOR_GRAY2BGR);
//将OpenCV图片(Mat) -> iOS平台下UIImage
UIImage *img = MatToUIImage(mat_image_src);
_imgView.image = img;
}
UIImageToMat(_imgView.image, mat_image_src);
上面OpenCV中,只有一个方法。我们自己实现一下一探究竟。
#import
#import
#import
#import
#include "opencv2/core/core.hpp"
//UIImage -> Mat
void WKUIImageToMat(const UIImage* image, Mat& m);
//UIImage -> Mat
void WKUIImageToMat(const UIImage* image, Mat& m){
//第一步:创建颜色空间
//开辟内存空间
CGColorSpaceRef colorSpaceRef = CGImageGetColorSpace(image.CGImage);
//第二步:根据iOS大小创建OpenCV图片
CGFloat width = image.size.width;
CGFloat height = image.size.height;
/*
高
宽
规则类型
在OpenCV里面有很多规范 (图像学相关,定义了很多很多宏定义)
CV_8UC4 表示:使用8位无符号类型 unsigned char, 每一个像素由4个元素组成四个通道的格式(ARGB)
规范格式(宏定义格式): CV_[位数][是否有符号][类型前缀]C[通道数量]
CV_8UC4 8位 U:unsigned char 无符号 C 4个通道(ARGB)
CV_8SC4 8位 S:signed char 有符号 C 4个通道(ARGB)
都是C++/OC 代码混合编程
*/
Mat mat_img_src(height,width,CV_8UC4);
m = mat_img_src;
//第三部:创建图片上下文。 解析UIImage图片信息 (格式,大小...)
/*
数据源
宽
高
每个像素占用多大内存(一个像素点由RGB组成。R 8位 G 8位 B 8位,占用内存:3字节)
每一行占用的内存( m.step[0] 第一行多大)
颜色空间
位图信息(是否需要透明度)
kCGImageAlphaNoneSkipLast 不需要透明度
kCGBitmapByteOrderDefault 默认排版
*/
CGContextRef cntextRef = CGBitmapContextCreate(m.data,
width,
height,
8,
m.step[0],
colorSpaceRef,
kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(cntextRef, CGRectMake(0, 0, width, height), image.CGImage);
CGContextRelease(cntextRef);
CGColorSpaceRelease(colorSpaceRef);
}
UIImage* WKMatToUIImage(const cv::Mat& image){
//第一步:将OpenCV图片 -> NSData
NSData *data = [NSData dataWithBytes:image.data length:image.elemSize() * image.total()];
//第二步:创建颜色空间
CGColorSpaceRef colorSpaceRef ;
if (image.elemSize() == 1) {
//灰色颜色空间
colorSpaceRef = CGColorSpaceCreateDeviceGray();
}else{
//彩色颜色空间
colorSpaceRef = CGColorSpaceCreateDeviceRGB();
}
//第三步:创建数据集合(C/C++图片)
CGDataProviderRef providerRef = CGDataProviderCreateWithCFData((CFDataRef)data);
//第四步:创建一张图片
/*
图片宽
图片高
每个像素占用多大内存(一个像素点由RGB组成。R 8位 G 8位 B 8位,占用内存:3字节)
每一个像素占用内存大小
每一行占用的内存大小( m.step[0] 第一行多大)
颜色空间
说白了就是图片是否需要透明度
数据集合
数据解码器
抗锯齿
图片渲染器
*/
CGImageRef imageRef = CGImageCreate(image.cols,
image.rows,
8,
8*image.elemSize(),
image.step[0],
colorSpaceRef,
kCGImageAlphaNone | kCGBitmapByteOrderDefault,
providerRef,
NULL,
false,
kCGRenderingIntentDefault);
CGDataProviderRelease(providerRef);
CGColorSpaceRelease(colorSpaceRef);
UIImage *im = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return im;
}