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 | +} |
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