คลาสพระเอกของ entry นี้ก็คือ CIDetector ซึ่งเป็นคลาสที่อยู่ใน CoreImage.framework โดยที่คลาสนี้มี method หลักอยู่ตัวเดียวก็คือ (NSArray *)featuresInImage:(CIImage *)image ที่จะคอยรับ CIImage เข้าไปและ return Array ของ CIFaceFeature กลับออกมา ซึ่งขนาดของ Array ก็จะขึ้นอยู่กับจำนวนของใบหน้าคนที่มีการตรวจพบนั่นเอง ซึ่ง CIFaceFeature ก็จะบรรจุตำแหน่งของ ตาซ้าย ตาขวา และปากไว้
เริ่มจากสมมติว่ามี UIImageView อยู่ 1 รูป
__weak IBOutlet UIImageView *_personImageView;
จากนั้นสร้าง object ของ CIDetector ขึ้นมา พร้อมกำหนด option ให้มัน ซึ่ง option จะเป็นการกำหนดความแม่นยำในการหาว่าจะมากหรือน้อย โดยถ้ากำหนดเป็นความแม่นยำมากก็จะใช้เวลาในการตรวจจับใบหน้าคนนานมากขึ้น
NSDictionary *options = [NSDictionary dictionaryWithObject: CIDetectorAccuracyHigh
forKey: CIDetectorAccuracy];
CIDetector *detector = [CIDetector detectorOfType: CIDetectorTypeFace
context: nil
options: options];
จากโค้ดด้านบนจะสังเกตเห็นตอนสร้าง detector นั้นมีการกำหนด type ให้ด้วย ซึ่งตอนนี้ใน API สามารถกำหนดค่านี้ได้เพียงค่าเดียว (อนาคตอาจกำหนดให้หาส่วนอื่นๆ ได้เพิ่ม?)
เมื่อเราได้ตัว detector มาแล้ว ก็ต้องเตรียม CIImage สำหรับจะส่งเข้าไปให้มันช่วยหาหน้าคนให้หน่อย เนื่องจากในโลกของ CoreImage นั้นมันไม่รู้จัก UIImage ที่เรามักใช้กันนั่นเอง ดังนี้
CIImage *image = [[CIImage alloc] initWithImage: _personImageView.image];
NSArray *features = [detector featuresInImage: image];
หลังจากได้ features มาแล้ว ก็ลองนำ CIFaceFeature แต่ละตัวใน array มาใช้งาน หรือลองแปะลงบนรูปเพื่อเช็คความถูกต้อง
for(CIFaceFeature *feature in features){
if(feature.hasLeftEyePosition){
[self markAtPoint: feature.leftEyePosition];
}
if(feature.hasRightEyePosition){
[self markAtPoint: feature.rightEyePosition];
}
if(feature.hasMouthPosition){
[self markAtPoint: feature.mouthPosition];
}
}
ตอนที่จะ mark ตำแหน่งลงบนรูป ต้องอย่าลืมว่าระบบ coordinate ในโลกของ CoreImage ไม่เหมือนกันกับในโลกของ UIKit ที่คุ้นเคยกันนะ ;)
เท่าที่ทดสอบมาถือว่าใช้งานได้ดีพอสมควร ส่วนความฉลาดในการหาก็น่าจะเป็นแบบเดียวกับที่ใช้ใน iPhone 4S และโปรแกรม iPhoto บน Mac
ที่มาของภาพ: Lenna






