Skip to content

Commit

Permalink
增加了人脸检测、马赛克以及效果图
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangao0086 committed Sep 18, 2014
1 parent d488404 commit e52144c
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 13 deletions.
13 changes: 12 additions & 1 deletion FaceDetection/FaceDetection/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6245" systemVersion="13E28" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="vXZ-lx-hvc">
<dependencies>
<deployment defaultVersion="1808" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
</dependencies>
<scenes>
Expand All @@ -26,6 +27,16 @@
<action selector="faceDetecing" destination="vXZ-lx-hvc" eventType="touchUpInside" id="5Vs-gj-f4D"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="lcX-8n-NTZ">
<rect key="frame" x="119" y="307" width="83" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="马赛克">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="pixellated" destination="vXZ-lx-hvc" eventType="touchUpInside" id="FQB-3s-9pB"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
Expand All @@ -35,7 +46,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="301" y="291"/>
<point key="canvasLocation" x="668" y="258"/>
</scene>
</scenes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
}
],
"info" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
"idiom" : "universal",
"scale" : "2x",
"filename" : "1@2x.png"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
Expand Down
89 changes: 77 additions & 12 deletions FaceDetection/FaceDetection/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ViewController: UIViewController {
lazy var context: CIContext = {
return CIContext(options: nil)
}()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Expand All @@ -28,31 +28,39 @@ class ViewController: UIViewController {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

// 人脸检测
@IBAction func faceDetecing() {
let inputImage = CIImage(image: originalImage)
let detector = CIDetector(ofType: CIDetectorTypeFace, context: context, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
let faceFeatures = detector.featuresInImage(inputImage) as [CIFaceFeature]

let detector = CIDetector(ofType: CIDetectorTypeFace,
context: context,
options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
var faceFeatures: [CIFaceFeature]!
if let orientation: AnyObject = inputImage.properties()?[kCGImagePropertyOrientation] {
faceFeatures = detector.featuresInImage(inputImage, options: [CIDetectorImageOrientation: orientation]) as [CIFaceFeature]
} else {
faceFeatures = detector.featuresInImage(inputImage) as [CIFaceFeature]
}

println(faceFeatures)

// 1.
let inputImageSize = inputImage.extent().size
var transform = CGAffineTransformIdentity
transform = CGAffineTransformScale(transform, 1, -1)
transform = CGAffineTransformTranslate(transform, 0, -inputImageSize.height)

for faceFeature in faceFeatures {
// var faceViewBounds = CGRectApplyAffineTransform(faceFeature.bounds, transform)

var faceViewBounds = CGRectApplyAffineTransform(faceFeature.bounds, transform)

// 2.
var scale = min(imageView.bounds.size.width / inputImageSize.width,
imageView.bounds.size.height / inputImageSize.height)
imageView.bounds.size.height / inputImageSize.height)
var offsetX = (imageView.bounds.size.width - inputImageSize.width * scale) / 2
var offsetY = (imageView.bounds.size.height - inputImageSize.height * scale) / 2
transform = CGAffineTransformScale(transform, scale, scale)
var faceViewBounds = CGRectApplyAffineTransform(faceFeature.bounds, transform)

faceViewBounds = CGRectApplyAffineTransform(faceViewBounds, CGAffineTransformMakeScale(scale, scale))
faceViewBounds.origin.x += offsetX
faceViewBounds.origin.y += offsetY
println(faceViewBounds)

let faceView = UIView(frame: faceViewBounds)
faceView.layer.borderColor = UIColor.orangeColor().CGColor
Expand All @@ -61,5 +69,62 @@ class ViewController: UIViewController {
imageView.addSubview(faceView)
}
}

// 马赛克
@IBAction func pixellated() {
// 1.
var filter = CIFilter(name: "CIPixellate")
println(filter.attributes())
let inputImage = CIImage(image: originalImage)
filter.setValue(inputImage, forKey: kCIInputImageKey)
// filter.setValue(max(inputImage.extent().size.width, inputImage.extent().size.height) / 60, forKey: kCIInputScaleKey)
let fullPixellatedImage = filter.outputImage
// let cgImage = context.createCGImage(fullPixellatedImage, fromRect: fullPixellatedImage.extent())
// imageView.image = UIImage(CGImage: cgImage)
// 2.
let detector = CIDetector(ofType: CIDetectorTypeFace,
context: context,
options: nil)
let faceFeatures = detector.featuresInImage(inputImage)
// 3.
var maskImage: CIImage!
for faceFeature in faceFeatures {
println(faceFeature.bounds)
// 4.
let centerX = faceFeature.bounds.origin.x + faceFeature.bounds.size.width / 2
let centerY = faceFeature.bounds.origin.y + faceFeature.bounds.size.height / 2
let radius = min(faceFeature.bounds.size.width, faceFeature.bounds.size.height)
let radialGradient = CIFilter(name: "CIRadialGradient",
withInputParameters: [
"inputRadius0" : radius,
"inputRadius1" : radius + 1,
"inputColor0" : CIColor(red: 0, green: 1, blue: 0, alpha: 1),
"inputColor1" : CIColor(red: 0, green: 0, blue: 0, alpha: 0),
kCIInputCenterKey : CIVector(x: centerX, y: centerY)
])
println(radialGradient.attributes())
// 5.
let radialGradientOutputImage = radialGradient.outputImage.imageByCroppingToRect(inputImage.extent())
if maskImage == nil {
maskImage = radialGradientOutputImage
} else {
println(radialGradientOutputImage)
maskImage = CIFilter(name: "CISourceOverCompositing",
withInputParameters: [
kCIInputImageKey : radialGradientOutputImage,
kCIInputBackgroundImageKey : maskImage
]).outputImage
}
}
// 6.
let blendFilter = CIFilter(name: "CIBlendWithMask")
blendFilter.setValue(fullPixellatedImage, forKey: kCIInputImageKey)
blendFilter.setValue(inputImage, forKey: kCIInputBackgroundImageKey)
blendFilter.setValue(maskImage, forKey: kCIInputMaskImageKey)
// 7.
let blendOutputImage = blendFilter.outputImage
let blendCGImage = context.createCGImage(blendOutputImage, fromRect: blendOutputImage.extent())
imageView.image = UIImage(CGImage: blendCGImage)
}
}

Binary file added intro5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e52144c

Please sign in to comment.