[Core Image Programming Guide] 이미지에서 얼굴 탐지하기

애플의 ‘Core Image Programming Guide — Detecting Faces in an Image’ 해석

naljin
5 min readMar 23, 2020

코어 이미지는 이미지에서 사람의 얼굴을 분석하고 찾을 수 있다. 인식이 아닌 탐지를 수행한다. 얼굴 탐지인간의 얼굴 특징이 들어 있는 직사각형의 식별이며, 얼굴 인식은 특정 인간의 얼굴을 식별하는 것이다(존, 메리 등). 코어 이미지는 얼굴을 감지한 후 눈, 입 위치 등 얼굴 특징에 대한 정보를 제공할 수 있다. 또한 비디오에서 식별된 얼굴 위치를 추적할 수 있다.

이미지에서 얼굴이 어디에 있는지 알면 얼굴의 영상 화질을 다듬거나 조정하는 등의 다른 작업을 수행할 수 있다(톤 밸런스, 적목 보정 등). 얼굴에서 다른 흥미로운 작업을 수행할 수도 있다.

Note: 얼굴 감지는 iOS 버전 5.0 이상, OS X 버전 10.7 이상에서 가능하다.

얼굴 탐지

Listing 2–1에서는 얼굴을 찾기 위해 CIDetector 클래스를 사용한다.

Listing 2–1 얼굴 탐지기 만들기

let context = CIContext() // 1var opts = [
CIDetectorAccuracy: CIDetectorAccuracyHigh
] // 2
let detector = CIDetector(ofType: CIDetectorTypeFace, context: context, options: opts) // 3if let value = myImage.properties().value(forKey: kCGImagePropertyOrientation as String), let value1 = [
CIDetectorImageOrientation: value
] as? [String : String] {
opts = value1
} // 4
let features = detector?.features(in: myImage, options: opts) // 5

코드가 하는 일은 아래와 같다

기본 옵션으로 컨텍스트를 생성하십시오. 이미지 처리에 설명된 컨텍스트 생성 기능을 사용할 수 있다.) 또한 디텍터를 생성할 때 컨텍스트 대신 0을 제공하는 옵션도 있다.)

  1. 기본 옵션으로 CIContext를 생성한다. Processing Images에 나오는 context 생성 함수 중 아무거나 사용해도 된다.
  2. 탐지기의 정확도를 지정하는 옵션의 dictionary을 작성한다. 정확도를 낮음 또는 높음으로 지정할 수 있다. 낮은 정확도(CIDetectorAccuracyLow)는 빠르고, 이 예시에서 사용된 높은 정확도는 철저하지만 느리다.
  3. 얼굴에 대한 탐지기를 생성한다. 당신이 만들 수 있는 탐지기의 유일한 유형은 사람 얼굴이다.
  4. 얼굴 찾기를 위한 옵션 dictionary를 설정한다. 탐지기가 똑바른 얼굴을 찾을 수 있도록 Core Image에 이미지 방향을 알려주는 것이 중요하다. 대부분의 경우 이미지 자체에서 이미지 방향을 읽은 다음 옵션 dictionary에 해당 값을 제공한다.
  5. 이미지에서 형상을 찾기 위해 탐지기를 사용한다. 당신이 제공하는 이미지는 CIImage 객체여야 한다. Core Image는 CIFeature 객체의 배열을 반환하는데 각 요소는 얼굴을 나타낸다.

얼굴의 array를 갖게 되면 눈과 입이 어디에 위치하는지와 같은 얼굴의 특성을 알아내고 싶을 것이다. 다음 절에서는 알아보자.

얼굴과 이목구비 가져오기

얼굴 형상은 다음을 포함한다.

  • 눈의 좌우 위치
  • 입 위치
  • Core Image가 비디오 세그먼트에서 얼굴을 따라가는 데 사용하는 추적 ID 및 추적 프레임 수(OS v6.0 이상 및 OS X v10.8 이상)

CIDetector 객체에서 얼굴의 배열을 얻은 후, Listing 2–2와 같이 loop를 돌면서 각 얼굴과 이목구비를 검사할 수 있다.

Listing 2–2 얼굴 및 얼굴 특징 경계 검사

for f in features {
print("\(NSStringFromRect(f.bounds as? NSRect ?? NSRect.zero))")
if f.hasLeftEyePosition {
print("Left eye \(f.leftEyePosition.x) \(f.leftEyePosition.y)")
}
if f.hasRightEyePosition {
print("Right eye \(f.rightEyePosition.x) \(f.rightEyePosition.y)")
}
if f.hasMouthPosition {
print("Mouth \(f.mouthPosition.x) \(f.mouthPosition.y)")
}
}

원문

--

--

No responses yet