簡(jiǎn)介
Core Image是一個(gè)圖片處理及分析庫(kù),里面封裝了非常易用的API,比如大量常用濾鏡歪沃。因?yàn)樗柚鶪PU或者CPU渲染,所以可以接近實(shí)時(shí)的速度處理靜態(tài)圖片和視頻圖片嫌松,圖片可來(lái)自Core Graphics沪曙、Core Video以及I/O框架。
功能列表
Core Image提供的能力包括:
- 通過(guò)大量?jī)?nèi)置濾鏡處理圖片
- 通過(guò)濾鏡鏈自定義處理效果
- 自動(dòng)化圖片增強(qiáng)
- 特征檢測(cè)萎羔,比如人臉液走、矩形、文字等
- 創(chuàng)建自定義濾鏡
基本概念
濾鏡
一個(gè)濾鏡在語(yǔ)義上表示某種能力,當(dāng)作用在一張圖片上時(shí)缘眶,可以經(jīng)過(guò)某種變換從而得到另一張圖片嘱根。
我們都知道,圖片在計(jì)算機(jī)中是以像素為基本單位而保存的像素矩陣巷懈,通過(guò)圖像處理單元GPU才能將其顯示在屏幕上该抒。在數(shù)學(xué)上,濾鏡其實(shí)也是一個(gè)矩陣顶燕,也叫卷積核凑保,通常比圖片的像素矩陣維度小得多。在真正處理圖片時(shí),圖片像素矩陣和卷積核做卷積運(yùn)算椿访,最終輸出一個(gè)“新”圖片浸遗。
濾鏡鏈
顧名思義,濾鏡鏈就是將多個(gè)濾鏡鏈接在一起维咸,前一個(gè)濾鏡的輸出作為下一個(gè)濾鏡的輸入,就像流水線一樣惠爽,圖片從第一個(gè)濾鏡中進(jìn)入癌蓖,處理之后再進(jìn)入下一個(gè),一直到最后一個(gè)濾鏡婚肆。通過(guò)這種方式租副,可以創(chuàng)建出更加如何需求的效果。
但實(shí)際上较性,Core Image的處理邏輯有點(diǎn)不同用僧,它并不會(huì)讓一張圖片經(jīng)過(guò)多次處理。為了性能考慮赞咙,Core Image會(huì)先將多個(gè)濾鏡的卷積核合成為一個(gè)责循,然后一次性得出最終的結(jié)果。
圖片處理
簡(jiǎn)單來(lái)說(shuō)攀操,圖片處理就是將某張圖片作用于某個(gè)濾鏡的過(guò)程院仿。
在Core Image中,圖片為CIImage速和,濾鏡為CIFilter歹垫,為濾鏡設(shè)置參數(shù)要通過(guò)KVC實(shí)現(xiàn)。同時(shí)颠放,還需要一個(gè)上下文對(duì)象CIContext排惨,里面保存著所有相關(guān)的細(xì)節(jié)。因?yàn)檫@些細(xì)節(jié)非常多碰凶,所以最好在合適的時(shí)機(jī)創(chuàng)建一個(gè)可重復(fù)利用的CIContext對(duì)象暮芭。
單濾鏡
最基本的用法就是只使用單個(gè)濾鏡鹿驼,如下所示。
- (void)blurImageWithRadius:(CGFloat)radius {
UIImage *originalImage = [UIImage imageNamed:@"blackboard.jpg"];
CIImage *ciimage = [CIImage imageWithData: UIImageJPEGRepresentation(originalImage, .9)];
CIFilter *gaussianBlur = [CIFilter filterWithName:@"CIGaussianBlur"];
[gaussianBlur setValue:@(radius) forKey:@"inputRadius"];
[gaussianBlur setValue:ciimage forKey:@"inputImage"];
[self.processedImageView setImage:[UIImage imageWithCIImage:gaussianBlur.outputImage]];
}
在CoreImage中所有相關(guān)操作中只能使用CIImage這個(gè)格式谴麦,但是它并不能直接呈現(xiàn)給用戶蠢沿,因?yàn)?strong>CIImage只是一種用來(lái)生產(chǎn)圖片的“配方”,其實(shí)就是一種操作流程匾效,比如從URL讀取圖片文件舷蟀,某個(gè)濾鏡操作的輸出等,只有在渲染或者輸出時(shí)才會(huì)開(kāi)始執(zhí)行面哼∫耙耍總結(jié)下來(lái),可以通過(guò)下面這些方法創(chuàng)建CIImage:
- NSURL
- NSData
- UIImage
- CGImageRef
- CVImageBufferRef
- CIImageProvider
- (void)createCIImageMethods {
CIImage *ciimg;
// 1. URL
ciimg = [[CIImage alloc] initWithContentsOfURL:[NSURL URLWithString:@"some-url"]];
// 2. bytes
ciimg = [CIImage imageWithData:[NSData dataWithContentsOfFile:@"some-file-path"]];
// 3. UIImage
ciimg = [CIImage imageWithData:UIImageJPEGRepresentation([UIImage imageNamed:@"some-img-name"], .9)];
ciimg = [CIImage imageWithData:UIImagePNGRepresentation([UIImage imageNamed:@"png-name"])];
// 4. CGImageRef
ciimg = [CIImage imageWithCGImage:[UIImage imageNamed:@"some-img"].CGImage];
//...
}
濾鏡分類(lèi)
Core Image中有大量的濾鏡魔策,而且隨著系統(tǒng)的不斷升級(jí)匈子,還在不斷添加新的濾鏡。系統(tǒng)將它們分為以下這些類(lèi)別:
類(lèi)別名稱(chēng) | 說(shuō)明 | 例子 |
---|---|---|
CICategoryBlur | 模糊 | 高斯模糊闯袒、降噪等 |
CICategoryColorAdjustment | 顏色調(diào)整 | 色值虎敦、曝光度、明暗度調(diào)整政敢,色溫其徙,色調(diào)曲線等 |
CICategoryColorEffect | 顏色效果 | 色值轉(zhuǎn)換、黑白效果喷户、褪色等 |
CICategoryCompositeOperation | 合成 | 疊加唾那,顏色混合、差分褪尝、乘除闹获,亮度、色度混合等等 |
CICategoryDistortionEffect | 扭曲 | 隆起河哑、線性隆起避诽,德羅斯特效應(yīng),替換扭曲璃谨,玻璃扭曲等 |
CICategoryGenerator | 生成器 | 生成條形碼茎用、二維碼、星光??睬罗、日光,純色圖片旭斥、隨機(jī)圖片等 |
CICategoryGeometryAdjustment | 幾何變換 | 仿射容达、透視變換,剪裁垂券,蘭索斯縮放 |
CICategoryGradient | 漸變 | 高斯?jié)u變花盐、線性漸變羡滑、徑向漸變等 |
CICategoryHalftoneEffect | 網(wǎng)版效果 | 圓形網(wǎng)屏,點(diǎn)狀網(wǎng)目板等 |
CICategoryReduction | 不知道該如何翻譯 | 區(qū)域平均值算芯、最值柒昏,行、列平均值等 |
CICategorySharpen | 銳化 | 亮度銳化熙揍、非銳化蒙版 |
CICategoryStylize | 風(fēng)格化 | 蒙版混合职祷,軟化邊緣,喜劇效果届囚,卷積有梆,結(jié)晶,邊緣檢測(cè)等 |
CICategoryTileEffect | 鋪貼效果 | 以多種不同形式填充圖案等 |
CICategoryTransition | 過(guò)渡 | 條形過(guò)渡意系,溶劑過(guò)渡等 |
把這些功能組合在一起泥耀,基本可以實(shí)現(xiàn)一個(gè)Photoshop了。
濾鏡鏈
前面說(shuō)了蛔添,當(dāng)要經(jīng)過(guò)多個(gè)濾鏡的處理時(shí)痰催,CoreImage為了提高性能會(huì)將多個(gè)濾鏡合成為一個(gè),并在合適時(shí)機(jī)完成處理迎瞧。
例如夸溶,如果分步處理,其流程如下:
但如果合成為一個(gè)Filter夹攒,則其流程如下:
- (CIImage *)processWithImage:(CIImage *)image fileterName:(NSString *)name params:(NSDictionary *)params {
CIFilter *filter = [CIFilter filterWithName:name];
[filter setValue:image forKey:@"inputImage"];
for (NSString *key in params.allKeys) {
[filter setValue:params[key] forKey:key];
}
return filter.outputImage;
}
- (IBAction)startProcessWithChain:(UIButton *)sender {
CIImage *blurImg, *bloomImg, *croppedImg;
blurImg = [self processWithImage:self.inputImage
fileterName:@"CIGaussianBlur"
params:@{kCIInputRadiusKey: @(1.2)}];
bloomImg = [self processWithImage:blurImg
fileterName:@"CIBloom"
params:@{kCIInputRadiusKey: @(8.0),
kCIInputIntensityKey: @(1.0)}];
croppedImg = [bloomImg imageByCroppingToRect:CGRectMake(50, 100, 300, 300)];
[self.processedImageView setImage:[UIImage imageWithCIImage:croppedImg]];
}
常用操作
Core Image除過(guò)用CFilter來(lái)處理圖片外蜘醋,還可以通過(guò)一些預(yù)定義的方法直接處理圖片,將更加簡(jiǎn)便咏尝。比如:
-
initWithColor:
純色圖片 -
imageByApplyingTransform:
給圖片進(jìn)行仿射變換 -
imageByCompositingOverImage:
疊加圖片 -
imageByCroppingToRect:
剪裁圖片 -
imageByClampingToRect:
擴(kuò)展邊界 -
imageByInsertingIntermediate
插值
檢測(cè)
在圖片識(shí)別處理中压语,如果要識(shí)別特定對(duì)象,一般都要先進(jìn)行輪廓檢測(cè)编检,然后再根據(jù)輪廓剪裁后識(shí)別物體胎食,這樣會(huì)更加高效準(zhǔn)確。比如人臉允懂、矩形等對(duì)象的識(shí)別厕怜。在Core Image中,提供了開(kāi)箱即用的輪廓檢測(cè)功能蕾总,其中只能進(jìn)行三類(lèi)操作:人臉粥航、矩形、文字生百。下面看看人臉檢測(cè)的使用方法:
- (void)detect:(UIBarButtonItem *)sender{
CIImage *image = [CIImage imageWithData:UIImageJPEGRepresentation(self.image, .95)];
NSLog(@"image size: %@", NSStringFromCGSize(self.image.size));
CIContext *context = [CIContext context];
NSDictionary *options = @{CIDetectorAccuracy: CIDetectorAccuracyHigh};
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:options];
options = @{CIDetectorImageOrientation: [[image properties] valueForKey:(NSString *)kCGImagePropertyOrientation]};
NSArray *features = [detector featuresInImage:image options:options];
for (CIFaceFeature *feature in features) {
NSLog(@"face bounds: %@", NSStringFromCGRect(feature.bounds));
[self drawBorderWithFaceFeature:feature];
}
}
- (void)drawBorderWithFaceFeature:(CIFaceFeature *)feature{
CGRect frame = [self convertFaceBoundsToView:feature.bounds];
NSLog(@"converted face bounds: %@", NSStringFromCGRect(frame));
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.backgroundColor = [UIColor clearColor];
label.layer.borderColor = [UIColor redColor].CGColor;
label.layer.borderWidth = 2.f;
[self.imageView addSubview:label];
}
- (CGRect)convertFaceBoundsToView:(CGRect)bounds{
CGFloat ratio = CGRectGetWidth(self.imageView.bounds)/self.image.size.width;
return CGRectMake(CGRectGetMinX(bounds)*ratio, CGRectGetMinY(bounds)*ratio, CGRectGetWidth(bounds)*ratio, CGRectGetHeight(bounds)*ratio);
}
經(jīng)過(guò)使用發(fā)現(xiàn)递雀,只要當(dāng)圖片中含有少量人時(shí)結(jié)果比較準(zhǔn)確,當(dāng)圖片清晰度降低蚀浆、并且人較多時(shí)結(jié)果不一定準(zhǔn)確缀程。
注意點(diǎn)
為了提高應(yīng)用程序的性能搜吧,在使用Core Image時(shí)盡可能注意以下細(xì)節(jié):
- 不要每次都創(chuàng)建CIContext,應(yīng)盡可能復(fù)用杨凑;
- 如果沒(méi)有必要滤奈,避免動(dòng)畫(huà)和顏色空間管理;
- 盡可能使用更小的圖片撩满、簡(jiǎn)單的濾鏡蜒程;
- 確保不要超過(guò)CPU或者GPU的限度等。