คุณใช้ ML Kit เพื่อตรวจหาใบหน้าในรูปภาพและวิดีโอได้
ลองเลย
- ลองใช้แอปตัวอย่างเพื่อดูตัวอย่างการใช้งาน API นี้
- ลองใช้โค้ดด้วยตนเองใน Codelab
ก่อนเริ่มต้น
- รวมพ็อด ML Kit ต่อไปนี้ใน Podfile:
pod 'GoogleMLKit/FaceDetection', '3.2.0'
- หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspace
ของโปรเจ็กต์นั้น Xcode เวอร์ชัน 12.4 ขึ้นไปรองรับ ML Kit
หลักเกณฑ์เกี่ยวกับรูปภาพอินพุต
สำหรับการจดจำใบหน้า คุณควรใช้รูปภาพที่มีขนาดอย่างน้อย 480x360 พิกเซล เพื่อให้ ML Kit ตรวจจับใบหน้าได้อย่างแม่นยำ รูปภาพที่ป้อนต้องมีใบหน้าที่แสดงด้วยข้อมูลพิกเซลที่เพียงพอ โดยทั่วไป แต่ละใบหน้าที่คุณต้องการตรวจจับในรูปภาพควรมีขนาดอย่างน้อย 100x100 พิกเซล หากคุณต้องการตรวจจับความโค้งของใบหน้า ML Kit จะต้องใช้อินพุตที่มีความละเอียดสูงกว่า โดยแต่ละด้านควรมีขนาดอย่างน้อย 200x200 พิกเซล
หากคุณตรวจจับใบหน้าในแอปพลิเคชันแบบเรียลไทม์ คุณอาจต้องพิจารณาขนาดโดยรวมของรูปภาพอินพุต รูปภาพที่เล็กลงจะประมวลผลได้เร็วขึ้น จึงลดเวลาในการตอบสนอง ให้จับภาพที่ความละเอียดต่ำลง แต่โปรดคำนึงถึงข้อกำหนดด้านความถูกต้องแม่นยำข้างต้นและตรวจสอบว่าใบหน้าของวัตถุครอบคลุมพื้นที่ในรูปภาพมากที่สุด และโปรดดูเคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
การโฟกัสรูปภาพที่ไม่ดีอาจส่งผลต่อความแม่นยำเช่นกัน หากคุณไม่ได้รับผลลัพธ์ที่ยอมรับ โปรดขอให้ผู้ใช้เรียกคืนรูปภาพ
การวางแนวของใบหน้าที่สัมพันธ์กับกล้องอาจส่งผลต่อสิ่งที่ฟีเจอร์ใบหน้าของ ML Kit ตรวจพบเช่นกัน ดูแนวคิดการตรวจจับใบหน้า
1. กำหนดค่าตัวตรวจจับใบหน้า
ก่อนใช้การตรวจจับใบหน้ากับรูปภาพ หากต้องการเปลี่ยนการตั้งค่าเริ่มต้นของตัวตรวจจับใบหน้า ให้ระบุการตั้งค่าเหล่านั้นด้วยออบเจ็กต์FaceDetectorOptions
คุณสามารถเปลี่ยนการตั้งค่าต่อไปนี้
การตั้งค่า | |
---|---|
performanceMode |
fast (ค่าเริ่มต้น) | accurate
ปรับปรุงความเร็วหรือความแม่นยำเมื่อตรวจจับใบหน้า |
landmarkMode |
none (ค่าเริ่มต้น) | all
ดูว่าจะพยายามตรวจจับ "จุดสังเกต" บนใบหน้าหรือไม่ เช่น ตา หู จมูก แก้ม ปาก ของใบหน้าทั้งหมดที่ตรวจพบ |
contourMode |
none (ค่าเริ่มต้น) | all
ตรวจหาส่วนโค้งของลักษณะใบหน้าหรือไม่ ระบบจะตรวจจับโครงร่างสำหรับใบหน้าที่โดดเด่นที่สุดในรูปภาพเท่านั้น |
classificationMode |
none (ค่าเริ่มต้น) | all
จะจัดประเภทใบหน้าเป็นหมวดหมู่ต่างๆ เช่น "กำลังยิ้ม" และ "อ้าปากค้าง" หรือไม่ |
minFaceSize |
CGFloat (ค่าเริ่มต้น: 0.1 )
ตั้งค่าขนาดใบหน้าที่เล็กที่สุดที่ต้องการ ซึ่งแสดงเป็นอัตราส่วนความกว้างของศีรษะต่อความกว้างของรูปภาพ |
isTrackingEnabled |
false (ค่าเริ่มต้น) | true
กำหนดรหัสให้กับใบหน้าหรือไม่ ซึ่งสามารถใช้เพื่อติดตามใบหน้าในรูปภาพต่างๆ ได้ โปรดทราบว่าเมื่อเปิดใช้การตรวจจับเส้นโครงร่าง ระบบจะตรวจจับเพียงใบหน้าเดียวเท่านั้น การติดตามใบหน้าจึงไม่ได้ให้ผลลัพธ์ที่เป็นประโยชน์ ด้วยเหตุนี้และหากต้องการปรับปรุงความเร็วในการตรวจจับ คุณจึงไม่ควรเปิดใช้ทั้งการตรวจจับเส้นโครงร่างและการติดตามใบหน้า |
เช่น สร้างออบเจ็กต์ FaceDetectorOptions
ตามตัวอย่างต่อไปนี้
Swift
// High-accuracy landmark detection and face classification let options = FaceDetectorOptions() options.performanceMode = .accurate options.landmarkMode = .all options.classificationMode = .all // Real-time contour detection of multiple faces // options.contourMode = .all
Objective-C
// High-accuracy landmark detection and face classification MLKFaceDetectorOptions *options = [[MLKFaceDetectorOptions alloc] init]; options.performanceMode = MLKFaceDetectorPerformanceModeAccurate; options.landmarkMode = MLKFaceDetectorLandmarkModeAll; options.classificationMode = MLKFaceDetectorClassificationModeAll; // Real-time contour detection of multiple faces // options.contourMode = MLKFaceDetectorContourModeAll;
2. เตรียมรูปภาพอินพุต
หากต้องการตรวจจับใบหน้าในรูปภาพ ให้ส่งรูปภาพเป็นUIImage
หรือ CMSampleBufferRef
ไปยัง FaceDetector
โดยใช้เมธอด process(_:completion:)
หรือ results(in:)
ดังนี้
สร้างออบเจ็กต์ VisionImage
โดยใช้ UIImage
หรือ CMSampleBuffer
หากคุณใช้ UIImage
ให้ทำตามขั้นตอนต่อไปนี้
- สร้างออบเจ็กต์
VisionImage
ที่มีUIImage
ตรวจสอบว่าได้ระบุ.orientation
ที่ถูกต้องSwift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
หากคุณใช้ CMSampleBuffer
ให้ทำตามขั้นตอนต่อไปนี้
-
ระบุการวางแนวของข้อมูลรูปภาพที่อยู่ใน
CMSampleBuffer
วิธีดูการวางแนวรูปภาพ
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- สร้างออบเจ็กต์
VisionImage
โดยใช้ออบเจ็กต์CMSampleBuffer
และการวางแนวดังนี้Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. รับอินสแตนซ์ของ FaceDetector
รับอินสแตนซ์ของ FaceDetector
:
Swift
let faceDetector = FaceDetector.faceDetector(options: options)
Objective-C
MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
4. ประมวลผลภาพ
จากนั้นส่งรูปภาพไปยังเมธอดprocess()
ดังนี้
Swift
weak var weakSelf = self faceDetector.process(visionImage) { faces, error in guard let strongSelf = weakSelf else { print("Self is nil!") return } guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... }
Objective-C
[faceDetector processImage:image completion:^(NSArray<MLKFace *> *faces, NSError *error) { if (error != nil) { return; } if (faces.count > 0) { // Recognized faces } }];
5. ดูข้อมูลเกี่ยวกับใบหน้าที่ตรวจพบ
หากการตรวจจับใบหน้าดำเนินการสำเร็จ เครื่องมือตรวจจับใบหน้าจะส่งอาร์เรย์ของFace
วัตถุไปยังตัวแฮนเดิลการเสร็จสมบูรณ์ วัตถุ Face
แต่ละชิ้นแสดงใบหน้าที่ตรวจพบในรูปภาพ คุณสามารถดูพิกัดของใบหน้าแต่ละใบหน้าได้ในภาพอินพุต รวมถึงข้อมูลอื่นๆ ที่คุณกำหนดค่าให้ตัวตรวจจับใบหน้าค้นหา เช่น
Swift
for face in faces { let frame = face.frame if face.hasHeadEulerAngleX { let rotX = face.headEulerAngleX // Head is rotated to the uptoward rotX degrees } if face.hasHeadEulerAngleY { let rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees } if face.hasHeadEulerAngleZ { let rotZ = face.headEulerAngleZ // Head is tilted sideways rotZ degrees } // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): if let leftEye = face.landmark(ofType: .leftEye) { let leftEyePosition = leftEye.position } // If contour detection was enabled: if let leftEyeContour = face.contour(ofType: .leftEye) { let leftEyePoints = leftEyeContour.points } if let upperLipBottomContour = face.contour(ofType: .upperLipBottom) { let upperLipBottomPoints = upperLipBottomContour.points } // If classification was enabled: if face.hasSmilingProbability { let smileProb = face.smilingProbability } if face.hasRightEyeOpenProbability { let rightEyeOpenProb = face.rightEyeOpenProbability } // If face tracking was enabled: if face.hasTrackingID { let trackingId = face.trackingID } }
Objective-C
for (MLKFace *face in faces) { // Boundaries of face in image CGRect frame = face.frame; if (face.hasHeadEulerAngleX) { CGFloat rotX = face.headEulerAngleX; // Head is rotated to the upward rotX degrees } if (face.hasHeadEulerAngleY) { CGFloat rotY = face.headEulerAngleY; // Head is rotated to the right rotY degrees } if (face.hasHeadEulerAngleZ) { CGFloat rotZ = face.headEulerAngleZ; // Head is tilted sideways rotZ degrees } // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): MLKFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar]; if (leftEar != nil) { MLKVisionPoint *leftEarPosition = leftEar.position; } // If contour detection was enabled: MLKFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom]; if (upperLipBottomContour != nil) { NSArray<MLKVisionPoint *> *upperLipBottomPoints = upperLipBottomContour.points; if (upperLipBottomPoints.count > 0) { NSLog("Detected the bottom contour of the subject's upper lip.") } } // If classification was enabled: if (face.hasSmilingProbability) { CGFloat smileProb = face.smilingProbability; } if (face.hasRightEyeOpenProbability) { CGFloat rightEyeOpenProb = face.rightEyeOpenProbability; } // If face tracking was enabled: if (face.hasTrackingID) { NSInteger trackingID = face.trackingID; } }
ตัวอย่างส่วนโค้งของใบหน้า
เมื่อเปิดใช้การตรวจจับรูปร่างของใบหน้า คุณจะเห็นรายการจุดสำหรับฟีเจอร์ใบหน้าแต่ละรายการที่ตรวจพบ จุดเหล่านี้แสดงถึงรูปร่างของฟีเจอร์ ดูรายละเอียดเกี่ยวกับวิธีแสดงเส้นโครงร่างในแนวคิดการตรวจจับใบหน้า
รูปภาพต่อไปนี้แสดงให้เห็นว่าจุดเหล่านี้จับคู่กับใบหน้าอย่างไร ให้คลิกรูปภาพเพื่อขยาย
การตรวจจับใบหน้าแบบเรียลไทม์
หากคุณต้องการใช้การตรวจจับใบหน้าในแอปพลิเคชันแบบเรียลไทม์ ให้ทำตามหลักเกณฑ์ต่อไปนี้เพื่อให้ได้อัตราเฟรมที่ดีที่สุด
กำหนดค่าเครื่องตรวจจับใบหน้าให้ใช้การตรวจจับเส้นรอบวงใบหน้า หรือการจำแนกประเภทและการตรวจจับจุดสังเกต แต่ไม่ใช่ทั้ง 2 อย่างต่อไปนี้
การตรวจจับเส้นโครงร่าง
การตรวจจับจุดสังเกต
การจำแนกประเภท
การตรวจจับและการจัดประเภทจุดสังเกต
การตรวจจับเส้นโครงร่างและการตรวจจับจุดสังเกต
การตรวจจับและการจัดประเภทเส้นโครงร่าง
การตรวจจับเส้นโครงร่าง การตรวจจับจุดสังเกต และการแยกประเภทเปิดใช้โหมด
fast
(เปิดอยู่โดยค่าเริ่มต้น)ลองจับภาพที่ความละเอียดต่ำลง แต่โปรดคำนึงถึงข้อกำหนดขนาดรูปภาพของ API นี้
- สำหรับการประมวลผลเฟรมวิดีโอ ให้ใช้ API แบบซิงโครนัส
results(in:)
ของตัวตรวจจับ เรียกใช้เมธอดนี้จากฟังก์ชันcaptureOutput(_, didOutput:from:)
ของAVCaptureVideoDataOutputSampleBufferDelegate
เพื่อรับผลการค้นหาจากเฟรมวิดีโอที่ระบุแบบพร้อมกัน คงalwaysDiscardsLateVideoFrames
ของAVCaptureVideoDataOutput
เป็นtrue
เพื่อควบคุมการโทรไปยังตัวตรวจจับ หากเฟรมวิดีโอใหม่พร้อมใช้งานขณะที่ตัวตรวจจับทำงานอยู่ เฟรมจะหายไป - หากคุณใช้เอาต์พุตจากตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต ให้รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพและการวางซ้อนในขั้นตอนเดียว การทำเช่นนี้จะทำให้คุณแสดงผลบนพื้นผิวแสดงผลเพียงครั้งเดียวต่อเฟรมอินพุตที่ประมวลผลแต่ละเฟรม ดู updatePreviewOverlayViewWithLastFrame ในตัวอย่างการเริ่มใช้งานอย่างรวดเร็วของ ML Kit