В основном для изучения библиотеки iOS Vision
Эффект
Исходное изображение (если изображение загружено из Интернета, если уведомление о нарушении изменено)
вырезать картинки
Детали все еще относительно грубые, а лицо отсутствует ?
Метод реализации
1. Предоставляется через фреймворк Vision системы iOS.VNGenerateObjectnessBasedSaliencyImageRequest
Область заметности изображения может быть получена, обратите внимание на использованиеObjectnessBased
В основном на основе заметности области объекта.
Полученная тепловая карта
CIImage *ciOriginImg = [CIImage imageWithCGImage:originImage.CGImage];//原始图片
VNImageRequestHandler *imageHandler = [[VNImageRequestHandler alloc]
initWithCIImage:ciOriginImg
options:nil];
VNGenerateObjectnessBasedSaliencyImageRequest *attensionRequest = [[VNGenerateObjectnessBasedSaliencyImageRequest alloc] init];//基于物体的显著性区域检测请求
NSError *err = nil;
BOOL haveAttension = [imageHandler performRequests:@[attensionRequest] error:&err];//有物品
if ( haveAttension ) {//有物品
if(attensionRequest.results && [attensionRequest.results count] > 0) {
VNSaliencyImageObservation *observation = [attensionRequest.results firstObject];
//获取显著区域热力图,接下来对该图进行边缘检测
[self heatMapProcess:observation.pixelBuffer catOrigin:ciOriginImg];
}
}
2. После получения тепловой карты области значимости используйтеVNDetectContoursRequest
Обнаружение краев получает край значимой области на изображении, и данные о крае существуют.VNContoursObservation
свойстваnormalizedPath
заCGPathRef
Серия нормализованных точек, сохраненных объектом, и эти точки необходимо окончательно преобразовать в координаты на картинке.
CIImage *heatImage = [CIImage imageWithCVPixelBuffer:hotRef];
VNDetectContoursRequest *contourRequest = [[VNDetectContoursRequest alloc] init];
contourRequest.revision = VNDetectContourRequestRevision1;
contourRequest.contrastAdjustment = 1.0;
contourRequest.detectDarkOnLight = NO;
contourRequest.maximumImageDimension = 512;
VNImageRequestHandler *handler = [[VNImageRequestHandler alloc] initWithCIImage:heatImage options:nil];
NSError *err = nil;
BOOL result = [handler performRequests:@[contourRequest] error:&err];
if(result) {
VNContoursObservation *contoursObv = [contourRequest.results firstObject];
CIContext *cxt = [[CIContext alloc] initWithOptions:nil];
CGImageRef origin = [cxt createCGImage:catOrigin
fromRect:catOrigin.extent];
//抠图
UIImage *clipImage = [self drawContourWith:contoursObv
withCgImg:nil
originImg:origin];
}
3, наконец прошелimage.layer
Метод установки ключа маски из содержимого выступающей области.
отрезать
- (UIImage *)drawContourWith:(VNContoursObservation *)contourObv
withCgImg:(CGImageRef)img
originImg:(CGImageRef)origin{
CGSize size = CGSizeMake(CGImageGetWidth(origin), CGImageGetHeight(origin));
UIImageView *originImgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
originImgV.image = [UIImage imageWithCGImage:origin];
CAShapeLayer *layer = [CAShapeLayer layer];
CGAffineTransform flipMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);//坐标转换为底部为(0, 0)
CGAffineTransform scaleTranform = CGAffineTransformScale(flipMatrix, size.width, size.height); //对path 进行按图尺寸放大
CGPathRef scaedPath = CGPathCreateCopyByTransformingPath(contourObv.normalizedPath, &scaleTranform);//对归一化的path进行变换
layer.path = scaedPath;
[originImgV.layer setMask:layer];
UIGraphicsBeginImageContext(originImgV.bounds.size);
[originImgV.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//对于扣出来的主要内容进行截取
//原数据放大的范围是ui的
CGAffineTransform originScale = CGAffineTransformMakeScale(size.width, size.height);
CGPathRef originScalePath = CGPathCreateCopyByTransformingPath(contourObv.normalizedPath, &originScale);//归一化的path进行还原,并拿到在图中位置的框
CGRect targetReact = CGPathGetBoundingBox(originScalePath);
CIImage *getBoundImage = [[CIImage alloc] initWithImage:image];
CIImage *targetBoundImg = [getBoundImage imageByCroppingToRect:targetReact];//截取范围的图片
CIImage *cropImg = [ciOriginImg imageByCroppingToRect:normalRect];
return [UIImage imageWithCIImage:targetBoundImg];
}