Skip to content

Instantly share code, notes, and snippets.

@sooop

sooop/main.swift Secret

Last active August 14, 2018 01:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sooop/b497dd84fea5db13559c498792dd5374 to your computer and use it in GitHub Desktop.
Save sooop/b497dd84fea5db13559c498792dd5374 to your computer and use it in GitHub Desktop.
Detect faces and apply pixellate filter on it
#!/usr/bin/swift
//
// main.swift
// Anonymizer
//
// Created by sooopd on 2018. 3. 30..
// Copyright © 2018년 sooopd. All rights reserved.
//
import Cocoa
import CoreImage
import Vision
/// find facial feature and process it
func detectFaces(in source: CIImage, completionHandler:((CIImage) -> Void)?)
{
let request = VNDetectFaceLandmarksRequest { req, error in
guard error == nil else {
NSLog("Error: \(error!.localizedDescription)")
return
}
guard let results = req.results as? [VNFaceObservation] else {
NSLog("Fail: Not supported result type.")
return
}
print("> found \(results.count) faces in the image")
print("> anonymizing...")
// Create Reulst Image
let boundingBoxes = results.map{ $0.boundingBox }
let resultImage = createAnonymizedImage(from: source,
boundingBoxes: boundingBoxes)
// call completeionHandler
completionHandler?(resultImage)
}
let handler = VNImageRequestHandler(ciImage: source,
options: [:])
try? handler.perform([request])
}
func createAnonymizedImage(from source: CIImage, boundingBoxes: [CGRect]) -> CIImage
{
let (imageWidth, imageHeight): (Int, Int) = {
let size = source.extent.size
return (Int(size.width), Int(size.height))
}()
// Create Bitmap Context
let maskImage: CIImage = {
let ctx = CGContext(data: nil,
width: imageWidth,
height: imageHeight,
bitsPerComponent: 8,
bytesPerRow: 0,
space: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGImageAlphaInfo.none.rawValue)!
ctx.setFillColor(NSColor.white.cgColor)
// fill(_ rects:) 를 사용하여 얼굴 영역을 칠한다.
ctx.fill(boundingBoxes.map{VNImageRectForNormalizedRect($0, imageWidth, imageHeight)})
return CIImage(cgImage: ctx.makeImage()!)
}()
let inputImage = source.applyingFilter("CIPixellate", parameters:
[kCIInputScaleKey: 18.0])
let resultImage = inputImage.applyingFilter("CIBlendWithMask", parameters:
[kCIInputMaskImageKey: maskImage,
kCIInputBackgroundImageKey: source])
return resultImage
}
func main() {
guard case let arguments = CommandLine.arguments, arguments.count > 1
else {
print("Usage: anonymizer <filepath>")
return
}
let context = CIContext()
if case let fileURL = URL(fileURLWithPath:(arguments[1] as NSString).expandingTildeInPath),
let image = CIImage(contentsOf:fileURL)
{
let saveFileURL: URL = {
let filename = fileURL.lastPathComponent
let path = fileURL.deletingLastPathComponent()
return path.appendingPathComponent("anony-\(filename).png")
}()
print("Analyze Image...")
detectFaces(in: image){ resultImage in
defer {
DispatchQueue.main.async{
CFRunLoopStop(CFRunLoopGetMain())
}
}
print("Trying to save processed file.")
do {
try context.writePNGRepresentation(
of: resultImage,
to: saveFileURL,
format: kCIFormatARGB8,
colorSpace: CGColorSpaceCreateDeviceRGB(),
options: [:])
print("Complete.")
} catch {
fatalError("Fail to write image data.")
}
}
CFRunLoopRun()
}
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment