支付寶(掃臉登錄)、微信、QQ 、美拍、秒拍、美圖秀秀……
都應用到了OpenCV
核心框架:基於OpenCV框架(圖像處理框架)
OpenCV?
第一點:開源(源代碼+核心算法;改進和優化)
第二點:跨平臺
第三點:支持多個語言
第四點:穩定,性能高 (1999年 V1.0 ~2017.8.3年 V3.3)
利用OpenVC將圖片變爲灰色圖片
1、下載導入framework
首先我們先下載OpenVC中關於iOS的framework。
導入工程中。
build。
我們會發現有個error。
enum { NO, GAIN, GAIN_BLOCKS };
我們可以將其更改爲
enum { NO_EXPOSURE_COMPENSATOR = 0, GAIN, GAIN_BLOCKS };
或者
enum { CNO, GAIN, GAIN_BLOCKS };
都可以解決這個問題。
2、在Controller中導入頭文件。
#import <opencv2/opencv.hpp>
//支持iOS平臺
#import <opencv2/imgcodecs/ios.h>
3、使用OpenVC進行處理
- (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的實現
UIImageToMat(_imgView.image, mat_image_src);
上面OpenCV中,只有一個方法。我們自己實現一下一探究竟。
#import <UIKit/UIKit.h>
#import <Accelerate/Accelerate.h>
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/ImageIO.h>
#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);
}
探究MatToUIImage的實現
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;
}