Skip to content

Commit ab57e05

Browse files
author
Cesar Vargas Casaseca
committed
Supports SPM, README.md
1 parent 24d75ed commit ab57e05

File tree

9 files changed

+204
-16
lines changed

9 files changed

+204
-16
lines changed

.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Wink/Package.swift renamed to Package.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ let package = Package(
1515
],
1616
dependencies: [],
1717
targets: [
18-
.target(
19-
name: "Wink",
20-
dependencies: [])
18+
.target(name: "Wink")
2119
]
2220
)

README.md

100644100755
Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,175 @@
1-
# Wink
1+
<p align="center">
2+
<img src="winkr.png" width="650 max-width="90%" alt="Wink" />
3+
</p>
4+
5+
<p align="center">
6+
<img src="https://img.shields.io/badge/Swift-5.2-orange.svg" />
7+
<a href="http://makeapullrequest.com">
8+
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square" alt="PRs Welcome" />
9+
</a>
10+
<a href="https://medium.com/@toupper">
11+
<img src="https://img.shields.io/badge/[email protected]" alt="Medium: @toupper" />
12+
</a>
13+
</p>
14+
15+
Welcome to **Wink**! — A light reactive library written in Swift that makes easy the process of Face Expression Detection on IOS. It detects a default set of user face expressions using the TrueDepth camera of the iPhone, and notifies you on real time using Combine.
16+
17+
## Features
18+
19+
- [x] Most common face expressions detection out of the box
20+
- [x] Reactively notifies the current set of user expressions
21+
- [x] Easily extendable to detect more face expressions
22+
- [x] Easily fine-tunable to adjust the expressions acceptance coefficient
23+
- [x] No need to deal or import other frameworks than Wink and Combine. Forget about the cumbersome ARKit
24+
25+
## Requirements
26+
27+
- iOS 13.0+
28+
- Xcode 12.0+
29+
- Device with TrueDepth Camera
30+
31+
## Installation
32+
#### Manually
33+
Since Wink is implemented within two files, you can simply drag and drop the sources dolder into your Xcode project. If however you want to use a dependency manager, I encourage you to use SPM:
34+
35+
36+
#### Swift Package Manager
37+
38+
The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. It is in early development, but Wink does support its use on iOS.
39+
40+
Once you have your Swift package set up, adding Wink as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.
41+
42+
```swift
43+
dependencies: [
44+
.package(url: "https://github.com/toupper/Wink.git", .upToNextMajor(from: "0.1.0"))
45+
]
46+
```
47+
48+
- GIven the easiness of the integration with SPM, I do not support Carthage or CocoaPods at the moment. If you however need one of those, open an issue and I will take care of that.
49+
50+
## Usage example
51+
52+
### Detecting Face Expressions
53+
54+
Wink performs the user face expressions detection within the ```FacialExpressionDetectorViewController``` class. This view controller will contain the camera view that analyzes the user face searching for their
55+
expressions. Therefore, if you want to start detecting expressions, you have to add this view controller to your hyerarchy, for instance through view controller containment, that is, adding it as a child:
56+
57+
```swift
58+
import Wink
59+
60+
let facialExpressionDetectorViewController = FacialExpressionDetectorViewController()
61+
addChild(facialExpressionDetectorViewController)
62+
63+
view.addSubview(facialExpressionDetectorViewController.view)
64+
facialExpressionDetectorViewController.didMove(toParent: self)
65+
```
66+
67+
If you don't want the camera view to appear in your view, you can easily hide the view:
68+
69+
```swift
70+
import Wink
71+
72+
facialExpressionDetectorViewController.view.isHidden = true
73+
```
74+
75+
or change its position:
76+
77+
```swift
78+
import Wink
79+
80+
private func adjustFacialExpressionView() {
81+
facialExpressionDetectorViewController.view.translatesAutoresizingMaskIntoConstraints = false
82+
facialExpressionDetectorViewController.view.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
83+
facialExpressionDetectorViewController.view.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
84+
facialExpressionDetectorViewController.view.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5).isActive = true
85+
facialExpressionDetectorViewController.view.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true
86+
}
87+
```
88+
89+
In order to be notified of the User Face Expressions change, you should subscribe to the ```facialExpression``` publisher:
90+
91+
```swift
92+
import Wink
93+
94+
private func adjustFacialExpressionView() {
95+
facialExpressionDetectorViewController.facialExpressionPublisher.sink(receiveValue: { expressions in
96+
DispatchQueue.main.async {
97+
// react to new face expressions
98+
}
99+
}).store(in: &cancellables)
100+
}
101+
```
102+
103+
That observable returns an array of ```FacialExpression``` objects. You can detect the existance of an specific face expression by checking its equality with the statically declared values:
104+
105+
```swift
106+
import Wink
107+
108+
private func adjustFacialExpressionView() {
109+
facialExpressionDetectorViewController.facialExpressionPublisher.sink(receiveValue: { expressions in
110+
DispatchQueue.main.async {
111+
if expression.first == FaceExpression.mouthSmileLeft {
112+
/// do something
113+
}
114+
}
115+
}).store(in: &cancellables)
116+
}
117+
```
118+
119+
### Advanced
120+
121+
#### Detect more expressions
122+
123+
Currently Wink detects by default the following Face Expressions:
124+
125+
```swift
126+
public static let mouthSmileLeft = FacialExpression(rawValue: "mouthSmileLeft")
127+
public static let mouthSmileRight = FacialExpression(rawValue: "mouthSmileRight")
128+
public static let browInnerUp = FacialExpression(rawValue: "browInnerUp")
129+
public static let tongueOut = FacialExpression(rawValue: "tongueOut")
130+
public static let cheekPuff = FacialExpression(rawValue: "cheekPuff")
131+
public static let eyeBlinkLeft = FacialExpression(rawValue: "eyeBlinkLeft")
132+
public static let eyeBlinkRight = FacialExpression(rawValue: "eyeBlinkRight")
133+
public static let jawOpen = FacialExpression(rawValue: "jawOpen")
134+
```
135+
136+
If you want to detect another face expression, you can add it by appending a new ```FacialExpressionAnalyzer``` into the ```FacialExpressionDetectorViewController``` ```analyzers``` property.
137+
You require three values to initialize that. Firstly a new Wink ```FaceExpression``` object with a ```rawValue``` to check for equality:
138+
139+
```swift
140+
141+
extension FacialExpression {
142+
static let eyeWideLeft = FacialExpression(rawValue: "eyeWideLeft")
143+
}
144+
```
145+
146+
Secondly, the face expression itself that will be dectected. Since Wink uses ARKit to detect expressions, you should pass a ```ARFaceAnchor.BlendShapeLocation``` declaring the expression to be detected. Take a look [here](https://developer.apple.com/documentation/arkit/arfaceanchor/blendshapelocation) for an exhaustive list of possibilities.
147+
148+
Thirdly and optionally, we need the coefficient from 0 to 1 that defines the acceptable degree of the face expression accuracy. For instance, fo an open mouth, 0 would be totally closed and 1 totally open.
149+
150+
```swift
151+
facialExpressionDetectorViewController.analyzers.append(FacialExpressionAnalyzer(facialExpression: FacialExpression.eyeWideLeft, blendShapeLocation: .eyeWideLeft, minimumValidCoefficient: 0.6))
152+
```
153+
154+
#### Modify the default expressions
155+
156+
If you do not want to be notified of all the default face expressions changes, or you want to change their accuracy coefficient, you can set the ```analyzers``` property to your desired value:
157+
158+
```swift
159+
160+
// Notifies only when the left eye is blinked, with a minor acceptance coefficient
161+
facialExpressionDetectorViewController.analyzers = [FacialExpressionAnalyzer(facialExpression: FacialExpression.eyeBlinkLeft, blendShapeLocation: .eyeBlinkLeft, minimumValidCoefficient: 0.3)]
162+
```
163+
164+
165+
## Contribute
166+
167+
I would love you for the contribution to **Wink**, check the ``LICENSE`` file for more info.
168+
169+
## Credits
170+
171+
Created and maintained with love by [César Vargas Casaseca](https://www.cesarvargas.es). You can follow me on Medium [@toupper](https://medium.com/@toupper) for project updates, releases and more stories.
172+
173+
## License
174+
175+
Wink is released under the MIT license. [See LICENSE](https://github.com/toupper/Wink/blob/master/LICENSE) for details.
File renamed without changes.

Wink/Sources/Wink/FacialExpressionDetectorViewController.swift renamed to Sources/Wink/FacialExpressionDetectorViewController.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,22 @@ public class FacialExpressionDetectorViewController: UIViewController, ARSCNView
2121
public override func viewDidLoad() {
2222
super.viewDidLoad()
2323

24-
sceneView = ARSCNView()
24+
checkFaceTrackingSupport()
2525

26+
sceneView = ARSCNView()
2627
self.view.addSubview(sceneView)
2728

28-
guard ARFaceTrackingConfiguration.isSupported else {
29-
fatalError("Face tracking not available on this on this device model!")
30-
}
29+
adjustSceneViewConstraints()
3130

32-
sceneView.delegate = self
33-
sceneView.showsStatistics = true
31+
sceneView.delegate = self
32+
sceneView.showsStatistics = true
33+
}
34+
35+
private func checkFaceTrackingSupport() {
36+
guard ARFaceTrackingConfiguration.isSupported else {
37+
fatalError("Error: This device model does not support face tracking")
3438
}
39+
}
3540

3641
private func adjustSceneViewConstraints() {
3742
sceneView.translatesAutoresizingMaskIntoConstraints = false
@@ -45,7 +50,7 @@ public class FacialExpressionDetectorViewController: UIViewController, ARSCNView
4550
super.viewWillAppear(animated)
4651

4752
let configuration = ARFaceTrackingConfiguration()
48-
sceneView.session.run(configuration)
53+
sceneView.session.run(configuration)
4954
}
5055

5156
public override func viewWillDisappear(_ animated: Bool) {

Wink.xcworkspace/contents.xcworkspacedata

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Wink/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Wink/README.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

wink.png

30.1 KB
Loading

0 commit comments

Comments
 (0)