คุณใช้ ML Kit เพื่อตรวจหาใบหน้าในรูปภาพและวิดีโอได้
ลองเลย
- ลองใช้แอปตัวอย่างเพื่อ ดูตัวอย่างการใช้ API นี้
- ลองเขียนโค้ดเองด้วย Codelab
ก่อนเริ่มต้น
- ใส่พ็อด ML Kit ต่อไปนี้ใน Podfile
pod 'GoogleMLKit/FaceDetection', '15.5.0'
- หลังจากที่คุณติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspace
ทั้งนี้ ML Kit รองรับ Xcode เวอร์ชัน 12.4 ขึ้นไป
หลักเกณฑ์เกี่ยวกับรูปภาพที่ป้อน
สำหรับการจดจำใบหน้า คุณควรใช้รูปภาพที่มีขนาดอย่างน้อย 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:)
ในตัวตรวจจับ โทร เมธอดนี้จาก ของAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
เพื่อให้ได้ผลลัพธ์จากวิดีโอที่ระบุแบบพร้อมกัน เฟรม เก็บ ของAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
เป็นtrue
เพื่อควบคุมการโทรหาตัวตรวจจับ หาก เฟรมวิดีโอจะพร้อมใช้งานขณะที่ตัวตรวจจับทำงานอยู่ เฟรมนั้นจะหายไป - หากคุณใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางซ้อนกราฟิก รูปภาพอินพุต รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพ ซ้อนทับในขั้นตอนเดียว การดำเนินการดังกล่าวจะแสดงบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุตที่ประมวลผลแล้ว ดู updatePreviewOverlayViewWithLastFrame ในตัวอย่างการเริ่มต้นอย่างรวดเร็วใน ML Kit