Showing
31 changed files
with
722 additions
and
0 deletions
면담보고서/20200429_면담보고서.jpeg
0 → 100644

716 KB
면담보고서/20200528_면담보고서.jpeg
0 → 100644

769 KB
보고서/~$보고서_2014104089.docx
deleted
100644 → 0
No preview for this file type
보고서/최종보고서_2014104089.pdf
0 → 100644
No preview for this file type
This diff is collapsed. Click to expand it.
No preview for this file type
No preview for this file type
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
3 | +<plist version="1.0"> | ||
4 | +<dict> | ||
5 | + <key>SchemeUserState</key> | ||
6 | + <dict> | ||
7 | + <key>extract_facial_expression.xcscheme_^#shared#^_</key> | ||
8 | + <dict> | ||
9 | + <key>orderHint</key> | ||
10 | + <integer>0</integer> | ||
11 | + </dict> | ||
12 | + </dict> | ||
13 | +</dict> | ||
14 | +</plist> |
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
3 | +<plist version="1.0"> | ||
4 | +<dict> | ||
5 | + <key>SchemeUserState</key> | ||
6 | + <dict> | ||
7 | + <key>extract_facial_expression.xcscheme_^#shared#^_</key> | ||
8 | + <dict> | ||
9 | + <key>orderHint</key> | ||
10 | + <integer>0</integer> | ||
11 | + </dict> | ||
12 | + </dict> | ||
13 | +</dict> | ||
14 | +</plist> |
1 | +// | ||
2 | +// AppDelegate.swift | ||
3 | +// extract_facial_expression | ||
4 | +// | ||
5 | +// Created by Jerry kim on 2020/06/11. | ||
6 | +// Copyright © 2020 hoya. All rights reserved. | ||
7 | +// | ||
8 | + | ||
9 | +import UIKit | ||
10 | + | ||
11 | +@UIApplicationMain | ||
12 | +class AppDelegate: UIResponder, UIApplicationDelegate { | ||
13 | + | ||
14 | + | ||
15 | + | ||
16 | + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { | ||
17 | + // Override point for customization after application launch. | ||
18 | + return true | ||
19 | + } | ||
20 | + | ||
21 | + // MARK: UISceneSession Lifecycle | ||
22 | + | ||
23 | + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { | ||
24 | + // Called when a new scene session is being created. | ||
25 | + // Use this method to select a configuration to create the new scene with. | ||
26 | + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) | ||
27 | + } | ||
28 | + | ||
29 | + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { | ||
30 | + // Called when the user discards a scene session. | ||
31 | + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. | ||
32 | + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. | ||
33 | + } | ||
34 | + | ||
35 | + | ||
36 | +} | ||
37 | + |
1 | +{ | ||
2 | + "images" : [ | ||
3 | + { | ||
4 | + "idiom" : "iphone", | ||
5 | + "scale" : "2x", | ||
6 | + "size" : "20x20" | ||
7 | + }, | ||
8 | + { | ||
9 | + "idiom" : "iphone", | ||
10 | + "scale" : "3x", | ||
11 | + "size" : "20x20" | ||
12 | + }, | ||
13 | + { | ||
14 | + "idiom" : "iphone", | ||
15 | + "scale" : "2x", | ||
16 | + "size" : "29x29" | ||
17 | + }, | ||
18 | + { | ||
19 | + "idiom" : "iphone", | ||
20 | + "scale" : "3x", | ||
21 | + "size" : "29x29" | ||
22 | + }, | ||
23 | + { | ||
24 | + "idiom" : "iphone", | ||
25 | + "scale" : "2x", | ||
26 | + "size" : "40x40" | ||
27 | + }, | ||
28 | + { | ||
29 | + "idiom" : "iphone", | ||
30 | + "scale" : "3x", | ||
31 | + "size" : "40x40" | ||
32 | + }, | ||
33 | + { | ||
34 | + "idiom" : "iphone", | ||
35 | + "scale" : "2x", | ||
36 | + "size" : "60x60" | ||
37 | + }, | ||
38 | + { | ||
39 | + "idiom" : "iphone", | ||
40 | + "scale" : "3x", | ||
41 | + "size" : "60x60" | ||
42 | + }, | ||
43 | + { | ||
44 | + "idiom" : "ipad", | ||
45 | + "scale" : "1x", | ||
46 | + "size" : "20x20" | ||
47 | + }, | ||
48 | + { | ||
49 | + "idiom" : "ipad", | ||
50 | + "scale" : "2x", | ||
51 | + "size" : "20x20" | ||
52 | + }, | ||
53 | + { | ||
54 | + "idiom" : "ipad", | ||
55 | + "scale" : "1x", | ||
56 | + "size" : "29x29" | ||
57 | + }, | ||
58 | + { | ||
59 | + "idiom" : "ipad", | ||
60 | + "scale" : "2x", | ||
61 | + "size" : "29x29" | ||
62 | + }, | ||
63 | + { | ||
64 | + "idiom" : "ipad", | ||
65 | + "scale" : "1x", | ||
66 | + "size" : "40x40" | ||
67 | + }, | ||
68 | + { | ||
69 | + "idiom" : "ipad", | ||
70 | + "scale" : "2x", | ||
71 | + "size" : "40x40" | ||
72 | + }, | ||
73 | + { | ||
74 | + "idiom" : "ipad", | ||
75 | + "scale" : "1x", | ||
76 | + "size" : "76x76" | ||
77 | + }, | ||
78 | + { | ||
79 | + "idiom" : "ipad", | ||
80 | + "scale" : "2x", | ||
81 | + "size" : "76x76" | ||
82 | + }, | ||
83 | + { | ||
84 | + "idiom" : "ipad", | ||
85 | + "scale" : "2x", | ||
86 | + "size" : "83.5x83.5" | ||
87 | + }, | ||
88 | + { | ||
89 | + "idiom" : "ios-marketing", | ||
90 | + "scale" : "1x", | ||
91 | + "size" : "1024x1024" | ||
92 | + } | ||
93 | + ], | ||
94 | + "info" : { | ||
95 | + "author" : "xcode", | ||
96 | + "version" : 1 | ||
97 | + } | ||
98 | +} |
1 | +{ | ||
2 | + "images" : [ | ||
3 | + { | ||
4 | + "filename" : "Extract Facial Expression on playing video (2).png", | ||
5 | + "idiom" : "universal", | ||
6 | + "scale" : "1x" | ||
7 | + }, | ||
8 | + { | ||
9 | + "idiom" : "universal", | ||
10 | + "scale" : "2x" | ||
11 | + }, | ||
12 | + { | ||
13 | + "idiom" : "universal", | ||
14 | + "scale" : "3x" | ||
15 | + } | ||
16 | + ], | ||
17 | + "info" : { | ||
18 | + "author" : "xcode", | ||
19 | + "version" : 1 | ||
20 | + } | ||
21 | +} |
.png)
27.3 KB
1 | +{ | ||
2 | + "images" : [ | ||
3 | + { | ||
4 | + "filename" : "backward.png", | ||
5 | + "idiom" : "universal", | ||
6 | + "scale" : "1x" | ||
7 | + }, | ||
8 | + { | ||
9 | + "idiom" : "universal", | ||
10 | + "scale" : "2x" | ||
11 | + }, | ||
12 | + { | ||
13 | + "idiom" : "universal", | ||
14 | + "scale" : "3x" | ||
15 | + } | ||
16 | + ], | ||
17 | + "info" : { | ||
18 | + "author" : "xcode", | ||
19 | + "version" : 1 | ||
20 | + } | ||
21 | +} |
1 | +{ | ||
2 | + "images" : [ | ||
3 | + { | ||
4 | + "filename" : "forward.png", | ||
5 | + "idiom" : "universal", | ||
6 | + "scale" : "1x" | ||
7 | + }, | ||
8 | + { | ||
9 | + "idiom" : "universal", | ||
10 | + "scale" : "2x" | ||
11 | + }, | ||
12 | + { | ||
13 | + "idiom" : "universal", | ||
14 | + "scale" : "3x" | ||
15 | + } | ||
16 | + ], | ||
17 | + "info" : { | ||
18 | + "author" : "xcode", | ||
19 | + "version" : 1 | ||
20 | + } | ||
21 | +} |

12.1 KB
1 | +{ | ||
2 | + "images" : [ | ||
3 | + { | ||
4 | + "filename" : "pause.png", | ||
5 | + "idiom" : "universal", | ||
6 | + "scale" : "1x" | ||
7 | + }, | ||
8 | + { | ||
9 | + "idiom" : "universal", | ||
10 | + "scale" : "2x" | ||
11 | + }, | ||
12 | + { | ||
13 | + "idiom" : "universal", | ||
14 | + "scale" : "3x" | ||
15 | + } | ||
16 | + ], | ||
17 | + "info" : { | ||
18 | + "author" : "xcode", | ||
19 | + "version" : 1 | ||
20 | + } | ||
21 | +} |

2.38 KB
1 | +{ | ||
2 | + "images" : [ | ||
3 | + { | ||
4 | + "filename" : "play.png", | ||
5 | + "idiom" : "universal", | ||
6 | + "scale" : "1x" | ||
7 | + }, | ||
8 | + { | ||
9 | + "idiom" : "universal", | ||
10 | + "scale" : "2x" | ||
11 | + }, | ||
12 | + { | ||
13 | + "idiom" : "universal", | ||
14 | + "scale" : "3x" | ||
15 | + } | ||
16 | + ], | ||
17 | + "info" : { | ||
18 | + "author" : "xcode", | ||
19 | + "version" : 1 | ||
20 | + } | ||
21 | +} |

6.48 KB
1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||
3 | + <dependencies> | ||
4 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> | ||
5 | + <capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
6 | + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
7 | + </dependencies> | ||
8 | + <scenes> | ||
9 | + <!--View Controller--> | ||
10 | + <scene sceneID="EHf-IW-A2E"> | ||
11 | + <objects> | ||
12 | + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||
13 | + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||
14 | + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> | ||
15 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
16 | + <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> | ||
17 | + <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> | ||
18 | + </view> | ||
19 | + </viewController> | ||
20 | + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||
21 | + </objects> | ||
22 | + <point key="canvasLocation" x="53" y="375"/> | ||
23 | + </scene> | ||
24 | + </scenes> | ||
25 | +</document> |
This diff is collapsed. Click to expand it.
소스코드/extract_facial_expression/Info.plist
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
3 | +<plist version="1.0"> | ||
4 | +<dict> | ||
5 | + <key>CFBundleDevelopmentRegion</key> | ||
6 | + <string>$(DEVELOPMENT_LANGUAGE)</string> | ||
7 | + <key>CFBundleExecutable</key> | ||
8 | + <string>$(EXECUTABLE_NAME)</string> | ||
9 | + <key>CFBundleIdentifier</key> | ||
10 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
11 | + <key>CFBundleInfoDictionaryVersion</key> | ||
12 | + <string>6.0</string> | ||
13 | + <key>CFBundleName</key> | ||
14 | + <string>$(PRODUCT_NAME)</string> | ||
15 | + <key>CFBundlePackageType</key> | ||
16 | + <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string> | ||
17 | + <key>CFBundleShortVersionString</key> | ||
18 | + <string>1.0</string> | ||
19 | + <key>CFBundleVersion</key> | ||
20 | + <string>1</string> | ||
21 | + <key>LSRequiresIPhoneOS</key> | ||
22 | + <true/> | ||
23 | + <key>UIApplicationSceneManifest</key> | ||
24 | + <dict> | ||
25 | + <key>UIApplicationSupportsMultipleScenes</key> | ||
26 | + <false/> | ||
27 | + <key>UISceneConfigurations</key> | ||
28 | + <dict> | ||
29 | + <key>UIWindowSceneSessionRoleApplication</key> | ||
30 | + <array> | ||
31 | + <dict> | ||
32 | + <key>UISceneConfigurationName</key> | ||
33 | + <string>Default Configuration</string> | ||
34 | + <key>UISceneDelegateClassName</key> | ||
35 | + <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string> | ||
36 | + <key>UISceneStoryboardFile</key> | ||
37 | + <string>Main</string> | ||
38 | + </dict> | ||
39 | + </array> | ||
40 | + </dict> | ||
41 | + </dict> | ||
42 | + <key>UILaunchStoryboardName</key> | ||
43 | + <string>LaunchScreen</string> | ||
44 | + <key>UIMainStoryboardFile</key> | ||
45 | + <string>Main</string> | ||
46 | + <key>NSCameraUsageDescription</key> | ||
47 | + <string></string> | ||
48 | + <key>UIRequiredDeviceCapabilities</key> | ||
49 | + <array> | ||
50 | + <string>armv7</string> | ||
51 | + <string>arkit</string> | ||
52 | + </array> | ||
53 | + <key>UISupportedInterfaceOrientations</key> | ||
54 | + <array> | ||
55 | + <string>UIInterfaceOrientationPortrait</string> | ||
56 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
57 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
58 | + </array> | ||
59 | + <key>UISupportedInterfaceOrientations~ipad</key> | ||
60 | + <array> | ||
61 | + <string>UIInterfaceOrientationPortrait</string> | ||
62 | + <string>UIInterfaceOrientationPortraitUpsideDown</string> | ||
63 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
64 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
65 | + </array> | ||
66 | +</dict> | ||
67 | +</plist> |
1 | +// | ||
2 | +// SceneDelegate.swift | ||
3 | +// extract_facial_expression | ||
4 | +// | ||
5 | +// Created by Jerry kim on 2020/06/11. | ||
6 | +// Copyright © 2020 hoya. All rights reserved. | ||
7 | +// | ||
8 | + | ||
9 | +import UIKit | ||
10 | + | ||
11 | +class SceneDelegate: UIResponder, UIWindowSceneDelegate { | ||
12 | + | ||
13 | + var window: UIWindow? | ||
14 | + | ||
15 | + | ||
16 | + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { | ||
17 | + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. | ||
18 | + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. | ||
19 | + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). | ||
20 | + guard let _ = (scene as? UIWindowScene) else { return } | ||
21 | + } | ||
22 | + | ||
23 | + func sceneDidDisconnect(_ scene: UIScene) { | ||
24 | + // Called as the scene is being released by the system. | ||
25 | + // This occurs shortly after the scene enters the background, or when its session is discarded. | ||
26 | + // Release any resources associated with this scene that can be re-created the next time the scene connects. | ||
27 | + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). | ||
28 | + } | ||
29 | + | ||
30 | + func sceneDidBecomeActive(_ scene: UIScene) { | ||
31 | + // Called when the scene has moved from an inactive state to an active state. | ||
32 | + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. | ||
33 | + } | ||
34 | + | ||
35 | + func sceneWillResignActive(_ scene: UIScene) { | ||
36 | + // Called when the scene will move from an active state to an inactive state. | ||
37 | + // This may occur due to temporary interruptions (ex. an incoming phone call). | ||
38 | + } | ||
39 | + | ||
40 | + func sceneWillEnterForeground(_ scene: UIScene) { | ||
41 | + // Called as the scene transitions from the background to the foreground. | ||
42 | + // Use this method to undo the changes made on entering the background. | ||
43 | + } | ||
44 | + | ||
45 | + func sceneDidEnterBackground(_ scene: UIScene) { | ||
46 | + // Called as the scene transitions from the foreground to the background. | ||
47 | + // Use this method to save data, release shared resources, and store enough scene-specific state information | ||
48 | + // to restore the scene back to its current state. | ||
49 | + } | ||
50 | + | ||
51 | + | ||
52 | +} | ||
53 | + |
1 | +// | ||
2 | +// VideoViewController.swift | ||
3 | +// extract_facial_expression | ||
4 | +// | ||
5 | +// Created by Jerry kim on 2020/06/11. | ||
6 | +// Copyright © 2020 hoya. All rights reserved. | ||
7 | +// | ||
8 | + | ||
9 | +import UIKit | ||
10 | +import AVFoundation | ||
11 | +import ARKit | ||
12 | + | ||
13 | +class VideoViewController: UIViewController, ARSCNViewDelegate { | ||
14 | + let videoPlayerView = UIView() | ||
15 | + var player: AVPlayer? | ||
16 | + | ||
17 | + public struct emotions { | ||
18 | + let expression: String | ||
19 | + let count: Int | ||
20 | + } | ||
21 | + | ||
22 | + @IBOutlet var sceneView: ARSCNView! | ||
23 | + @IBOutlet weak var expressionLabel: UILabel! | ||
24 | + @IBOutlet weak var expression1: UILabel! // smile | ||
25 | + @IBOutlet weak var expression2: UILabel! // dumbfounded | ||
26 | + @IBOutlet weak var expression3: UILabel! // suprise | ||
27 | + @IBOutlet weak var expression4: UILabel! // nyah | ||
28 | + @IBOutlet weak var expression5: UILabel! // awful | ||
29 | + @IBOutlet weak var expression6: UILabel! // eye smile | ||
30 | + | ||
31 | + @IBOutlet weak var resultLabel: UILabel! // result label | ||
32 | + | ||
33 | + var faceExpression = "" | ||
34 | + var count1 = 0 // smile | ||
35 | + var count2 = 0 // dumbfounded | ||
36 | + var count3 = 0 // suprise | ||
37 | + var count4 = 0 // nyah | ||
38 | + var count5 = 0 // awful | ||
39 | + var count6 = 0 // eye smile | ||
40 | + | ||
41 | + // Sample Videos | ||
42 | + let videos = ["http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", | ||
43 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4", | ||
44 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4", | ||
45 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4", | ||
46 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4", | ||
47 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4", | ||
48 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4", | ||
49 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4", | ||
50 | + "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4"] | ||
51 | + | ||
52 | + override func viewDidLoad() { | ||
53 | + super.viewDidLoad() | ||
54 | + videoPlayerView.backgroundColor = UIColor.white | ||
55 | + videoPlayerView.translatesAutoresizingMaskIntoConstraints = false | ||
56 | + // Add constraints, pinnning each of the four sides | ||
57 | +// let topConstraint = NSLayoutConstraint(item: videoPlayerView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0) | ||
58 | +// let bottomConstraint = NSLayoutConstraint(item: videoPlayerView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0) | ||
59 | +// let leadingConstraint = NSLayoutConstraint(item: videoPlayerView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0) | ||
60 | +// let trailingConstraint = NSLayoutConstraint(item: videoPlayerView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0) | ||
61 | + | ||
62 | + | ||
63 | + view.addSubview(videoPlayerView) | ||
64 | + | ||
65 | + videoPlayerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true | ||
66 | + videoPlayerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true | ||
67 | + videoPlayerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3).isActive = true | ||
68 | + videoPlayerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true | ||
69 | + | ||
70 | +// view.addConstraints([topConstraint, bottomConstraint, leadingConstraint, trailingConstraint]) | ||
71 | + view.sendSubviewToBack(videoPlayerView) | ||
72 | + | ||
73 | + // for ARSCNView | ||
74 | + guard ARFaceTrackingConfiguration.isSupported else { | ||
75 | + fatalError("Face tracking not available on this on this device model!") | ||
76 | + } | ||
77 | + sceneView.delegate = self | ||
78 | + sceneView.showsStatistics = true | ||
79 | + | ||
80 | +// sceneView.translatesAutoresizingMaskIntoConstraints = false | ||
81 | +// sceneView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true | ||
82 | +// sceneView.topAnchor.constraint(equalToSystemSpacingBelow: videoPlayerView.bottomAnchor, multiplier: 0.3).isActive = true | ||
83 | +// sceneView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3).isActive = true | ||
84 | + | ||
85 | + } | ||
86 | + | ||
87 | + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { | ||
88 | + // for view video, left landscape | ||
89 | + return .landscapeLeft | ||
90 | + } | ||
91 | + | ||
92 | + func setupVideoPlayer() { // Play random video | ||
93 | + let randNum = arc4random_uniform(9) | ||
94 | + guard let url = URL(string: self.videos[Int(randNum)]) else { | ||
95 | + return | ||
96 | + } | ||
97 | + | ||
98 | + player = AVPlayer(url: url) | ||
99 | + | ||
100 | + let playerLayer = AVPlayerLayer(player: player) | ||
101 | + playerLayer.frame = videoPlayerView.bounds | ||
102 | + videoPlayerView.layer.addSublayer(playerLayer) | ||
103 | + player?.play() | ||
104 | + } | ||
105 | + | ||
106 | + override func viewWillAppear(_ animated: Bool) { | ||
107 | + super.viewWillAppear(animated) | ||
108 | + | ||
109 | + // Create a session configuration | ||
110 | + let configuration = ARFaceTrackingConfiguration() | ||
111 | + | ||
112 | + // Run the view's session | ||
113 | + sceneView.session.run(configuration) | ||
114 | + } | ||
115 | + | ||
116 | + override func viewWillDisappear(_ animated: Bool) { | ||
117 | + super.viewWillDisappear(animated) | ||
118 | + | ||
119 | + // Pause the view's session | ||
120 | + sceneView.session.pause() | ||
121 | + } | ||
122 | + | ||
123 | + override func viewDidAppear(_ animated: Bool) { | ||
124 | + super.viewDidAppear(animated) | ||
125 | + setupVideoPlayer() | ||
126 | + } | ||
127 | + | ||
128 | + func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? { | ||
129 | + let faceMesh = ARSCNFaceGeometry(device: sceneView.device!) | ||
130 | + let node = SCNNode(geometry: faceMesh) | ||
131 | + node.geometry?.firstMaterial?.fillMode = .lines | ||
132 | + return node | ||
133 | + } | ||
134 | + | ||
135 | + func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { | ||
136 | + if let faceAnchor = anchor as? ARFaceAnchor, let faceGeometry = node.geometry as? ARSCNFaceGeometry { | ||
137 | + faceGeometry.update(from: faceAnchor.geometry) | ||
138 | + facePoseAnalyzer(anchor: faceAnchor) | ||
139 | + | ||
140 | + DispatchQueue.main.async { | ||
141 | + self.expressionLabel.text = self.faceExpression | ||
142 | + self.expression1.text = String(self.count1) | ||
143 | + self.expression2.text = String(self.count2) | ||
144 | + self.expression3.text = String(self.count3) | ||
145 | + self.expression4.text = String(self.count4) | ||
146 | + self.expression5.text = String(self.count5) | ||
147 | + self.expression6.text = String(self.count6) | ||
148 | + self.extractMost() | ||
149 | + } | ||
150 | + | ||
151 | + } | ||
152 | + } | ||
153 | + | ||
154 | + func extractMost() { | ||
155 | + let structedArray = [ | ||
156 | + emotions(expression: "smile", count: self.count1), | ||
157 | + emotions(expression: "dumbfounded", count: self.count2), | ||
158 | + emotions(expression: "surprise", count: self.count3), | ||
159 | + emotions(expression: "nyah", count: self.count4), | ||
160 | + emotions(expression: "awful", count: self.count5), | ||
161 | + emotions(expression: "eye smile", count: self.count6) | ||
162 | + ] | ||
163 | + let sortedArray = structedArray.sorted(by: {$0.count > $1.count}) | ||
164 | + self.resultLabel.text = sortedArray[0].expression | ||
165 | + | ||
166 | + } | ||
167 | + | ||
168 | + func facePoseAnalyzer(anchor: ARFaceAnchor) { | ||
169 | + let smileLeft = anchor.blendShapes[.mouthSmileLeft] | ||
170 | + let smileRight = anchor.blendShapes[.mouthSmileRight] | ||
171 | + let innerUp = anchor.blendShapes[.browInnerUp] | ||
172 | + let tongue = anchor.blendShapes[.tongueOut] | ||
173 | + let eyeBlinkLeft = anchor.blendShapes[.eyeBlinkLeft] | ||
174 | + let jawOpen = anchor.blendShapes[.jawOpen] | ||
175 | + | ||
176 | + let mouthFrownLeft = anchor.blendShapes[.mouthFrownLeft] | ||
177 | + let mouthFrownRight = anchor.blendShapes[.mouthFrownRight] | ||
178 | + | ||
179 | + var newFaceExpression = "" | ||
180 | + | ||
181 | + if ((smileLeft?.decimalValue ?? 0.0) + (smileRight?.decimalValue ?? 0.0)) > 0.9 { | ||
182 | + newFaceExpression = "😀" | ||
183 | + self.count1 = self.count1 + 1 | ||
184 | + } | ||
185 | + | ||
186 | + if ((jawOpen?.decimalValue ?? 0.0) + (innerUp?.decimalValue ?? 0.0)) > 0.85 { | ||
187 | + newFaceExpression = "😧" | ||
188 | + self.count2 = self.count2 + 1 | ||
189 | + } | ||
190 | + | ||
191 | + | ||
192 | + if innerUp?.decimalValue ?? 0.0 > 0.8 { | ||
193 | + newFaceExpression = "😳" | ||
194 | + self.count3 = self.count3 + 1 | ||
195 | + } | ||
196 | + | ||
197 | + if tongue?.decimalValue ?? 0.0 > 0.08 { | ||
198 | + newFaceExpression = "😛" | ||
199 | + self.count4 = self.count4 + 1 | ||
200 | + } | ||
201 | + | ||
202 | + if (mouthFrownLeft?.decimalValue ?? 0.0) > 0.3 || (mouthFrownRight?.decimalValue ?? 0.0) > 0.3 { | ||
203 | + newFaceExpression = "🤢" | ||
204 | + self.count5 = self.count5 + 1 | ||
205 | + } | ||
206 | + | ||
207 | + | ||
208 | + if eyeBlinkLeft?.decimalValue ?? 0.0 > 0.5 { | ||
209 | + newFaceExpression = "😊" | ||
210 | + self.count6 = self.count6 + 1 | ||
211 | + } | ||
212 | + | ||
213 | + if self.faceExpression != newFaceExpression { | ||
214 | + self.faceExpression = newFaceExpression | ||
215 | + } | ||
216 | + // if cheekPuff?.decimalValue ?? 0.0 > 0.5 { | ||
217 | + // newFaceExpression = "🤢" | ||
218 | + // self.count5 = self.count5 + 1 | ||
219 | + // } | ||
220 | + | ||
221 | + } | ||
222 | + | ||
223 | + func session(_ session: ARSession, didFailWithError error: Error) { | ||
224 | + // Present an error message to the user | ||
225 | + | ||
226 | + } | ||
227 | + | ||
228 | + func sessionWasInterrupted(_ session: ARSession) { | ||
229 | + // Inform the user that the session has been interrupted, for example, by presenting an overlay | ||
230 | + | ||
231 | + } | ||
232 | + | ||
233 | + func sessionInterruptionEnded(_ session: ARSession) { | ||
234 | + // Reset tracking and/or remove existing anchors if consistent tracking is required | ||
235 | + | ||
236 | + } | ||
237 | +} |
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> | ||
3 | + <device id="retina6_1" orientation="landscape" appearance="light"/> | ||
4 | + <dependencies> | ||
5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> | ||
6 | + <capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
7 | + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
8 | + </dependencies> | ||
9 | + <objects> | ||
10 | + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> | ||
11 | + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> | ||
12 | + <view contentMode="scaleToFill" id="m5W-Np-e6E"> | ||
13 | + <rect key="frame" x="0.0" y="0.0" width="896" height="414"/> | ||
14 | + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> | ||
15 | + <subviews> | ||
16 | + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2IZ-Qo-Rl0"> | ||
17 | + <rect key="frame" x="425" y="192" width="46" height="30"/> | ||
18 | + <state key="normal" title="Button"/> | ||
19 | + </button> | ||
20 | + </subviews> | ||
21 | + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> | ||
22 | + <constraints> | ||
23 | + <constraint firstItem="2IZ-Qo-Rl0" firstAttribute="centerY" secondItem="m5W-Np-e6E" secondAttribute="centerY" id="Xpn-17-T2q"/> | ||
24 | + <constraint firstItem="2IZ-Qo-Rl0" firstAttribute="centerX" secondItem="m5W-Np-e6E" secondAttribute="centerX" id="xUd-ag-9LJ"/> | ||
25 | + </constraints> | ||
26 | + <viewLayoutGuide key="safeArea" id="1md-eY-o7C"/> | ||
27 | + <point key="canvasLocation" x="139" y="154"/> | ||
28 | + </view> | ||
29 | + </objects> | ||
30 | +</document> |
1 | +// | ||
2 | +// ViewController.swift | ||
3 | +// extract_facial_expression | ||
4 | +// | ||
5 | +// Created by Jerry kim on 2020/06/11. | ||
6 | +// Copyright © 2020 hoya. All rights reserved. | ||
7 | +// | ||
8 | + | ||
9 | +import UIKit | ||
10 | + | ||
11 | +class ViewController: UIViewController { | ||
12 | + | ||
13 | + override func viewDidLoad() { | ||
14 | + super.viewDidLoad() | ||
15 | + // Do any additional setup after loading the view. | ||
16 | + } | ||
17 | + | ||
18 | + | ||
19 | + | ||
20 | +} | ||
21 | + |
-
Please register or login to post a comment