An implementation of High Pass Skin Smoothing using Apple's Core Image Framework

Overview

YUCIHighPassSkinSmoothing

CocoaPods Platform CocoaPods Version CocoaPods License

An implementation of High Pass Skin Smoothing using CoreImage.framework

Available on both OS X and iOS.

Ports

A MetalPetal based version can be found here: MetalPetal/MTIHighPassSkinSmoothingFilter

A GPUImage based version can be found here: YUGPUImageHighPassSkinSmoothing

Previews

Preview 1

Preview 2

Preview 3

Preview 4

Preview 5

Preview 6

Performance

Tests are made in Instruments with the "OpenGL ES Analysis" template.

The CIContext object is created with EAGLContext and a sRGB working color space (CGColorSpaceCreateDeviceRGB()).

Image Size: 640 x 800
Input Radius: 7.0
Operating System: iOS 9

Device: iPhone 5s / FPS: 60
Device: iPhone 5  / FPS: ~24

Concepts

The basic routine of YUCIHighPassSkinSmoothing can be described with the following diagram.

Routine

Basic Concept

The main theory behind High Pass Skin Smoothing is Frequency Separation.

Frequency separation splits up the tones and colors of a image from its more detailed textures. It is possible because a digital image can be interpreted as different frequencies represented as sine waves.

High frequencies in an image will contain information about fine details, such as skin pores, hair, fine lines, skin imperfections.

Low frequencies are the image data that contains information about volume, tone and color transitions. In other words: shadows and light areas, colors and tones.

https://fstoppers.com/post-production/ultimate-guide-frequency-separation-technique-8699

By using High Pass filter, the image can be separated into high and low spatial frequencies. Then we will be able to smoothing the image while preseving a fine level of detail by applying adjustments (Curve Adjustment in the diagram) to certain frequencies of the image.

High Pass Filter

There's no High Pass filter in CoreImage. Luckily it's not hard to create one (High Pass Filter section in the diagram):

highpass.rgb = image.rgb - gaussianBlurredImage.rgb + vec3(0.5,0.5,0.5)

Mask Generating

A mask image is generated using high pass filter (Green and blue channel overlay blend -> high pass -> hard light blend X 3) for separating the parts of the image which need to be adjusted from the ones that should remain untouched.

This mask image is then used in Blend with Mask (CIBlendWithMask) filter to blend the adjusted image with the untouched one to produce the final output image.

Improvements

Besides the steps in the diagram, YUCIHighPassSkinSmoothing actually has two more steps.

The exposure of the input image is decreased by 1 EV before being sent to the Mask Generating Routine (in -[YUCIHighPassSkinSmoothingMaskGenerator outputImage] method) and a RGB curve adjustment is added to the mask at the end of the Mask Generating Routine (at the end of YUCIHighPassSkinSmoothingMaskBoost.cikernel).

These steps can make the result better on the areas with high brightness. The whole process can of course work without these two steps.

Input Parameters

inputAmount: A number value that controls the intensity of the Curve Adjustment step and affects the sharpness of the final Sharpen step. You use this value to control the overall filter strength. Valid from 0 to 1.0. The default value is 0.75.

inputToneCurveControlPoints: A array of CIVector that defines the control points of the curve in Curve Adjustment step. The default value of this parameter is [(0,0), (120/255.0,146/255.0), (1,1)].

inputRadius: A number value that controls the radius (in pixel) of the High Pass filter. The default value of this parameter is 8.0. Try adjusting this value according to the resolution of the input image and the level of detail you want to preserve.

inputSharpnessFactor: A number value that controls the sharpness factor of the final Sharpen step. The sharpness value is calculated as inputAmount * inputSharpnessFactor. The default value for this parameter is 0.6. Note: Sharpen is an expensive operation (it involves convolution). The final Sharpen step will make the output image look better, however it is not necessary. Consider setting this parameter to 0 when you need to get the best performance.

Consideration

For the best result, you need to create the CIContext object with a sRGB working color space instead of the default light-linear color space. You can specify a working color space when creating a context using the kCIContextWorkingColorSpace key in the options dictionary.

You can also try to apply this filter only to the skin/face area of a image, by using a skin detection filter or the core image face detector.

Requirements

  • iOS 8.0+ / OS X 10.11+
  • Xcode 7.0+

Usage

Use the YUCIHighPassSkinSmoothing, like any other built in core image filters.

Documentation for the input parameters can be found here.

let filter = YUCIHighPassSkinSmoothing()
filter.inputImage = ...
filter.inputAmount = ...
let outputImage = filter.outputImage!

/* Or */

let filter = CIFilter(name: "YUCIHighPassSkinSmoothing")!
filter.setValue(inputImage, forKey: kCIInputImageKey)
filter.setValue(0.7, forKey: "inputAmount")
let outputImage = filter.outputImage!

Open YUCIHighPassSkinSmoothingDemo/YUCIHighPassSkinSmoothingDemo.xcworkspace to run the iOS demo app. The demo app demonstrated how to use the filter and how to use different kinds of core image context to render the output image. The Metal core image context is only available on 64-bit devices with iOS 9.

Please run the demo app on an actual device. The iOS simulator does not provide a pixel-accurate match to the graphics hardware. Rendering performance of OpenGL ES in Simulator has no relation to the performance of OpenGL ES on an actual device.

Installation

YUCIHighPassSkinSmoothing makes use of Vivid.

CocoaPods

Add the following to your Podfile

pod 'YUCIHighPassSkinSmoothing'

Manually

Clone this repo and Vivid, then manually add the files in Sources directories to your project.

Contributing

You are encouraged to try different input parameters or tweak the interal procedure to make this filter better or just fit your needs.

Don't hesitate to open an issue if you have any idea or suggestion.

If you find a bug and know exactly how to fix it, please open a pull request. Be sure to test the code on both OS X and iOS.

Credits

Thanks a lot to Yien Ma for providing a lot of suggestions and fine-tunings to the procedure.

License

YUCIHighPassSkinSmoothing is MIT-licensed. See LICENSE file for detail.

Copyright © 2016 Yu Ao

Comments
  • let filter = CIFilter(name:

    let filter = CIFilter(name: "YUCIHighPassSkinSmoothing")! Crash

    I am trying to access YUCIHighPassSkinSmoothing filter with CIFilter but I am not able to access it.

    I am using the same code which you have provided in the sample like below:

    let filter = CIFilter(name: "YUCIHighPassSkinSmoothing")!

    Thanks!

    opened by yashesh87 3
  • Love this project, but is it possible to implement this filter by GPUImage?

    Love this project, but is it possible to implement this filter by GPUImage?

    When I use this filter to process live video buffer, cpu usage can goes up to 70% . Is it possible to reduce the cpu usage to under 15%, 25 frames per second. Besides, is GPUImage able to imitate the same effect with this great filter?

    opened by jinbo0122 3
  • Cannot use sRGB texture binding with format BGRA8 for sampler 0 in kernel 'filterKernel'.

    Cannot use sRGB texture binding with format BGRA8 for sampler 0 in kernel 'filterKernel'.

    Hi YuAo , your work is fantastic . ( Unfortunately im not smart enough to use it ). Failed to use RGBToneCurve to filtering live iOS camera. I would appreciate for your help . Thanks.

    https://stackoverflow.com/questions/49933477/ios-yucirgbtonecurve-cannot-use-srgb-texture-binding-with-format-bgra8-for-sam

    opened by gazind 2
  • How to implement this beautify filter in live camera to beautify face

    How to implement this beautify filter in live camera to beautify face

    Hi @yien1108 , @YuAo ,

    I tried GPUImage2, but there is no method to beautify face in the live camera. Can you please help how to implement this filter with the camera?

    Thanks in advance.

    opened by aaasifrz9 2
  • inputToneCurveControlPoints invalid name in README

    inputToneCurveControlPoints invalid name in README

    Hi, thanks for this great library!

    I've noticed that there's a parameter called inputControlPoints in the README, but it's actually called inputToneCurveControlPoints in the code, so trying to set inputControlPoints param leads to exception.

    Also where I can read what exactly is "curve from the Curve Adjustment step" and what its values are responsible for? Thanks!

    opened by RomanFrom710 1
  • c#?

    c#?

    Hi YuAo! Very interesting work. Do you have the capability to port this over to c# .NET or other Windows application code? Is there any way to reach you by email or other method about contract work opportunities for you?

    Thank you.

    opened by GITMIKRO 1
  • Pimples remover

    Pimples remover

    I have applied your High Paas filter to my desired images. Doing great job but one thing is missing, pimples are still there, Can you suggest some thing to remove these pimples? Original image is this pic

    And after applying your filter img_6891 As you can see they are dimmed but not removed, Need urgently this work to be done, please suggest some thing, Thanks

    opened by kk143g 1
  • Removal of Red dots from Face

    Removal of Red dots from Face

    I have tried different values of parameters but red dots are not removed from face. Is there any filter which can remove red dots from face. Acne is removed but red dots are still obvious. Suggest some filter or combination of filters. I have tried CIBloom filter with your algorithm, it just bloomed the face but still red dots are there.

    opened by kk143g 1
  • Apply filter on selected part of image

    Apply filter on selected part of image

    How to apply that YUCIHighPassSkinSmoothing filter on selected/specific part of image, like pass a particular portion of image from image to apply filter on it, i have tried this let imageCenter = CIVector(x:0.55 * 100 , y:0.6 * 100) self.filter.setValue(imageCenter, forKey:"inputCenter") But it says "this class is not key value coding-compliant for the key inputCenter" I have applied above inputCenter in processImage() method of class DefaultRenderContextViewController.

    opened by kk143g 1
  • YUCIHighPassSkinSmoothing drains battery and increases CPU usage significantly

    YUCIHighPassSkinSmoothing drains battery and increases CPU usage significantly

    Hi Yu Ao, Thanks for this sweet and useful library. I notice that after applying this filter for realtime processing (let's say from a camera running at 24fps), it drains battery very fast and incurs a lot more CPU usage. Could you please show some pointers on why this happens and how to mitigate it? Thanks a lot.

    opened by vincent284 1
  • how to do you create nice looking diagram at

    how to do you create nice looking diagram at

    from your readme, the diagram looks really nice. How to do you create nice looking diagram at http://yuao.github.io/YUCIHighPassSkinSmoothing/docs/filter-routine.jpg

    thanks

    opened by steve21124 1
  • LowPass Skin Smoothing

    LowPass Skin Smoothing

    Hi, thanks for creating this awesome repository.

    I am a newbie at writing shader string, so can you please suggest me a way to target the low-frequency areas in the image just like you are creating the high pass filter in the following way, to target the high frequencies areas of the image

    highpass.rgb = image.rgb - gaussianBlurredImage.rgb + vec3(0.5,0.5,0.5)

    Any help would be highly appreciated. Thanks

    opened by swakez 0
Releases(1.4)
Owner
Yu Ao
Yu Ao
📷 A composable image editor using Core Image and Metal.

Brightroom - Composable image editor - building your own UI Classic Image Editor PhotosCrop Face detection Masking component ?? v2.0.0-alpha now open!

Muukii 2.8k Jan 2, 2023
A pure Swift high-performance asynchronous image loading framework. SwiftUI supported.

Longinus Longinus is a pure-Swift high-performance asynchronous web image loading,caching,editing framework. It was learned from Objective-C web image

Qitao Yang 290 Dec 17, 2022
High Quality Image ScrollView using cropped tiled images.

THTiledImageView Feature ?? THTiledImageView fully support UIScrollView. You can subclass it and use it. ?? Support Async Image Downloading & Caching.

null 28 Oct 28, 2022
An extremely high-performance, lightweight, and energy-efficient pure Swift async web image loader with memory and disk caching for iOS and  Watch.

KFSwiftImageLoader KFSwiftImageLoader is an extremely high-performance, lightweight, and energy-efficient pure Swift async web image loader with memor

Kiavash Faisali 343 Oct 29, 2022
A high-performance image library for downloading, caching, and processing images in Swift.

Features Asynchronous image downloader with priority queuing Advanced memory and database caching using YapDatabase (SQLite) Guarantee of only one ima

Yap Studios 72 Sep 19, 2022
BeatboxiOS - A sample implementation for merging multiple video files and/or image files using AVFoundation

MergeVideos This is a sample implementation for merging multiple video files and

null 3 Oct 24, 2022
Twitter Image Pipeline is a robust and performant image loading and caching framework for iOS clients

Twitter Image Pipeline (a.k.a. TIP) Background The Twitter Image Pipeline is a streamlined framework for fetching and storing images in an application

Twitter 1.8k Dec 17, 2022
APNGKit is a high performance framework for loading and displaying APNG images in iOS and macOS.

APNGKit is a high performance framework for loading and displaying APNG images in iOS and macOS. It's built on top of a modified version of libpng wit

Wei Wang 2.1k Dec 30, 2022
Core Image Filter Explorer & Showcase

Filterpedia Core Image Filter explorer Filterpedia is an iPad app for exploring (almost) the entire range of image filters offered by Apple's Core Ima

simon gladman 2.2k Dec 28, 2022
Syntactic Sugar for Accelerate/vImage and Core Image Filters

ShinpuruImage Syntactic Sugar for Accelerate/vImage and Core Image Filters ShinpuruImage offers developers a consistent and strongly typed interface t

simon gladman 100 Jan 6, 2023
Playing with Core Image and Metal Shader Language for fun.

Playing with Core Image and Metal Shader Language for fun.

Makeeyaf 6 Jan 5, 2023
An image download extension of the image view written in Swift for iOS, tvOS and macOS.

Moa, an image downloader written in Swift for iOS, tvOS and macOS Moa is an image download library written in Swift. It allows to download and show an

Evgenii Neumerzhitckii 330 Sep 9, 2022
AsyncImage before iOS 15. Lightweight, pure SwiftUI Image view, that displays an image downloaded from URL, with auxiliary views and local cache.

URLImage URLImage is a SwiftUI view that displays an image downloaded from provided URL. URLImage manages downloading remote image and caching it loca

Dmytro Anokhin 1k Jan 4, 2023
AYImageKit is a Swift Library for Async Image Downloading, Show Name's Initials and Can View image in Separate Screen.

AYImageKit AYImageKit is a Swift Library for Async Image Downloading. Features Async Image Downloading. Can Show Text Initials. Can have Custom Styles

Adnan Yousaf 11 Jan 10, 2022
A complete Mac App: drag an image file to the top section and the bottom section will show you the text of any QRCodes in the image.

QRDecode A complete Mac App: drag an image file to the top section and the bottom section will show you the text of any QRCodes in the image. QRDecode

David Phillip Oster 2 Oct 28, 2022
Convert the image to hexadecimal to send the image to e-paper

ConvertImageToHex Convert the image to hexadecimal to send the image to e-paper Conversion Order // 0. hex로 변환할 이미지 var image = UIImage(named: "sample

Hankyeol Park 0 Feb 26, 2022
Image-cropper - Image cropper for iOS

Image-cropper Example To run the example project, clone the repo, and run pod in

Song Vuthy 0 Jan 6, 2022
An instagram-like image editor that can apply preset filters passed to it and customized editings to a binded image.

CZImageEditor CZImageEditor is an instagram-like image editor with clean and intuitive UI. It is pure swift and can apply preset filters and customize

null 8 Dec 16, 2022
GPUImage 3 is a BSD-licensed Swift framework for GPU-accelerated video and image processing using Metal.

GPUImage 3 Janie Clayton http://redqueengraphics.com @RedQueenCoder Brad Larson http://www.sunsetlakesoftware.com @bradlarson contact@sunsetlakesoftwa

Brad Larson 2.4k Jan 3, 2023