Faceu must have a core algorithm of its own, so it says “Someone is copying my face…”

Recently, I have been studying some image processing technologies, among which the most common application is “Faceu Facial MOE”. In order to show a clearer picture, I choose to implement the Demo by splitting functions.

🎨 what does the test UI look like?

1. List page 2. Filter effect page 3. Green screen keying page 4. Static compositing pages
Build the basic framework Several filter effects Achieve green screen keying Statically synthesized Gif

Advantages of 🚀 framework

  • 1. Few files, simple code and novel functions
  • 2. High functional integration, good experience and fine structure
  • 3. Solely relying on GPUImage
  • 4. High customization

🤖 requirements

  • iOS 7+
  • Xcode 8+

🛠 Usage

Filter effects

Core code display:

/ / convert UIImage into CIImage CIImage * CIImage = [[CIImage alloc] initWithImage: self. OriginImage]; / / create a filter CIFilter * filter = [CIFilter filterWithName: filterName keysAndValues: kCIInputImageKey, ciImage, nil]; // The existing values are not changed, other values are set to default [filter]setDefaults];
        
//获取绘制上下文
CIContext *context = [CIContext contextWithOptions:nil];
        
//渲染并输出CIImage
CIImage *outputImage = [filter outputImage];
        
//创建CGImage句柄
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
        
//获取图片
UIImage *image = [UIImage imageWithCGImage:cgImage];
        
//释放CGImage句柄
CGImageRelease(cgImage);
        
self.imageView.image = image;
Copy the code

Green screen keyer

Reference header file:

#import "RSChromaKeyFilter.h"
Copy the code

Tools and methods:

RSChromaKeyFilter *filter=[[RSChromaKeyFilter alloc] initWithInputImage:self.greenImageView.image
                                                        backgroundImage:self.resultBgImageView.image];
    
self.resultImageView.image=[[UIImage imageWithCIImage:filter.outputImage] copy];
Copy the code

Static synthesis

Effect demonstration:

Reference header file:

#import <CoreImage/CoreImage.h>
#import "UIImageView+Gif.h"
Copy the code

Core approach:

// Image recognition ability: You can choose between CIDetectorAccuracyHigh(strong processing power) and CIDetectorAccuracyLow(weak processing power). Because want some high accuracy here to choose CIDetectorAccuracyHigh NSDictionary * opts = [NSDictionary dictionaryWithObject: CIDetectorAccuracyHighforKey:CIDetectorAccuracy]; CIDetector *detector=[CIDetector detectorOfType:CIDetectorTypeFace context:nil options:opts]; // CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace // context:nil // options:nil]; CIImage *image=[[CIImage alloc] initWithImage:self.oldImageView.image]; NSArray *faceArray = [detector featuresInImage:image options:nil]; CGSize ciImageSize = [Image extent].size; / / the image along the y axial symmetry CGAffineTransform transform = CGAffineTransformScale (CGAffineTransformIdentity, 1, 1); / / y axis direction of negative translational transform = CGAffineTransformTranslate (transform, 0, - ciImageSize. Height);for (CIFeature *f in faceArray){
    if([f.type isEqualToString:CIFeatureTypeFace]) { CIFaceFeature *faceFeature=(CIFaceFeature *)f; / / realization of coordinate conversion CGSize viewSize = self. OldImageView. Bounds. Size; CGFloat scale = MIN(viewSize.width / ciImageSize.width, viewSize.height / ciImageSize.height); CGFloat offsetX = (viewSize.width - ciImageSize.width * scale) / 2; CGFloat offsetY = (viewSize.height - ciImageSize.height * scale) / 2; / / zoom CGAffineTransform scaleTransform = CGAffineTransformMakeScale (scale, scale); / / to get face frame CGRect faceViewBounds = CGRectApplyAffineTransform (faceFeature bounds, the transform); / / correction faceViewBounds = CGRectApplyAffineTransform (faceViewBounds scaleTransform); faceViewBounds.origin.x += offsetX; faceViewBounds.origin.y += offsetY; UIView *faceView=[[UIView alloc] initWithFrame:faceViewBounds]; faceView.layer.borderWidth=3; faceView.layer.borderColor=[UIColor orangeColor].CGColor; [self.oldImageView addSubview:faceView]; /** UIImageView *imageView=[UIImageView new]; CGFloat haloWidth= faceViewBounds.size.width; CGFloat haloHeight= haloWidth * 159 / 351; . }}Copy the code

The dynamic synthetic

Effect demonstration:

Reference header file:

#import <GPUImage/GPUImage.h>
Copy the code

Core approach:

_faceThinking = YES;
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
CIImage *convertedImage = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer options:(__bridge NSDictionary *)attachments];

if(attachments) CFRelease(attachments); NSDictionary *imageOptions = nil; UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation]; int exifOrientation; enum { PHOTOS_EXIF_0ROW_TOP_0COL_LEFT = 1, // 1 = 0th row is at the top, and 0th column is on the left (THE DEFAULT). PHOTOS_EXIF_0ROW_TOP_0COL_RIGHT = 2, // 2 = 0th row is at the top, and 0th column is on the right. PHOTOS_EXIF_0ROW_BOTTOM_0COL_RIGHT = 3, // 3 = 0th row is at the bottom, and 0th column is on the right. PHOTOS_EXIF_0ROW_BOTTOM_0COL_LEFT = 4, // 4 = 0th row is at the bottom, and 0th column is on the left. PHOTOS_EXIF_0ROW_LEFT_0COL_TOP = 5, // 5 = 0th row is on the left, and 0th column is the top. PHOTOS_EXIF_0ROW_RIGHT_0COL_TOP = 6, // 6 = 0th row is on the right, and 0th column is the top. PHOTOS_EXIF_0ROW_RIGHT_0COL_BOTTOM = 7, // 7 = 0th row is on the right, and 0th column is the bottom. PHOTOS_EXIF_0ROW_LEFT_0COL_BOTTOM = 8 // 8 = 0th row is on the left, and 0th column is the bottom. }; BOOL isUsingFrontFacingCamera = FALSE; AVCaptureDevicePosition currentCameraPosition = [self.videoCamera cameraPosition]; .Copy the code

⚖ agreement

MIT License

Copyright (c) 2017 ReverseScale

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Copy the code

😬 contact

  • WeChat: WhatsXie
  • Mail: [email protected]
  • Blog: reversescale. Making. IO
  • Source: github.com/ReverseScal…