คุณใช้ ML Kit เพื่อตรวจหาใบหน้าในรูปภาพและวิดีโอได้
ก่อนเริ่มต้น
- หากยังไม่ได้เพิ่ม Firebase ลงในแอป โปรดทำตามขั้นตอนในคู่มือเริ่มต้นใช้งาน
- รวมไลบรารี ML Kit ไว้ใน Podfile ดังนี้
pod 'Firebase/MLVision', '6.25.0' # If you want to detect face contours (landmark detection and classification # don't require this additional model): pod 'Firebase/MLVisionFaceModel', '6.25.0'
หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว อย่าลืมเปิดโปรเจ็กต์ Xcode โดยใช้.xcworkspace
- ในแอป ให้นำเข้า Firebase ดังนี้
Swift
import Firebase
Objective-C
@import Firebase;
หลักเกณฑ์เกี่ยวกับรูปภาพที่ป้อน
เพื่อให้ ML Kit ตรวจจับใบหน้าได้อย่างแม่นยำ รูปภาพที่ป้อนต้องมีใบหน้าที่แสดงด้วยข้อมูลพิกเซลที่เพียงพอ โดยทั่วไป ใบหน้าแต่ละใบหน้าที่คุณต้องการตรวจจับในรูปภาพควรมีขนาดอย่างน้อย 100x100 พิกเซล หากต้องการตรวจจับรูปทรงของใบหน้า ML Kit ต้องใช้อินพุตที่มีความละเอียดสูงขึ้น โดยแต่ละใบหน้าควรมีขนาดอย่างน้อย 200x200 พิกเซล
หากคุณกำลังตรวจจับใบหน้าในแอปพลิเคชันแบบเรียลไทม์ คุณอาจต้องพิจารณาขนาดโดยรวมของรูปภาพอินพุตด้วย ระบบประมวลผลรูปภาพขนาดเล็กได้เร็วกว่า ดังนั้นหากต้องการลดเวลาในการตอบสนอง ให้จับภาพด้วยความละเอียดที่ต่ำลง (โปรดทราบข้อกำหนดด้านความแม่นยำข้างต้น) และตรวจสอบว่าใบหน้าของวัตถุอยู่ในพื้นที่ในรูปภาพมากที่สุดเท่าที่จะเป็นไปได้ นอกจากนี้ โปรดดู เคล็ดลับเพื่อปรับปรุงประสิทธิภาพแบบเรียลไทม์
การโฟกัสของรูปภาพไม่ดีอาจทำให้ความแม่นยำลดลง หากไม่ได้ผลลัพธ์ที่ยอมรับได้ ให้ลองขอให้ผู้ใช้จับภาพอีกครั้ง
การวางแนวของใบหน้าที่สัมพันธ์กับกล้องอาจส่งผลต่อสิ่งที่ใบหน้าของ ML Kit ตรวจพบด้วย ดูแนวคิดในการตรวจจับใบหน้า
1. กำหนดค่าตัวตรวจจับใบหน้า
ก่อนใช้การตรวจจับใบหน้ากับรูปภาพ หากต้องการเปลี่ยนการตั้งค่าเริ่มต้นของตัวตรวจจับใบหน้า ให้ระบุการตั้งค่าเหล่านั้นด้วยออบเจ็กต์VisionFaceDetectorOptions
คุณสามารถเปลี่ยนการตั้งค่าต่อไปนี้
การตั้งค่า | |
---|---|
performanceMode |
fast (ค่าเริ่มต้น) | accurate
เลือกความเร็วหรือความแม่นยำในการตรวจจับใบหน้า |
landmarkMode |
none (ค่าเริ่มต้น) | all
กำหนดว่าจะพยายามตรวจหา "จุดสังเกต" บนใบหน้า เช่น ตา หู จมูก แก้ม ปาก ของใบหน้าทั้งหมดที่ตรวจพบหรือไม่ |
contourMode |
none (ค่าเริ่มต้น) | all
เลือกว่าจะตรวจหารูปร่างของใบหน้าหรือไม่ ระบบจะตรวจจับเฉพาะขอบของใบหน้าที่โดดเด่นที่สุดในรูปภาพเท่านั้น |
classificationMode |
none (ค่าเริ่มต้น) | all
จำแนกใบหน้าออกเป็นหมวดหมู่ต่างๆ เช่น "ยิ้ม" และ "ลืมตา" หรือไม่ |
minFaceSize |
CGFloat (ค่าเริ่มต้น: 0.1 )
ขนาดต่ำสุดซึ่งสัมพันธ์กับภาพของใบหน้าที่จะตรวจจับ |
isTrackingEnabled |
false (ค่าเริ่มต้น) | true
ระบุหรือไม่กำหนดรหัสสำหรับใบหน้า ซึ่งสามารถใช้เพื่อติดตามใบหน้าในรูปภาพต่างๆ โปรดทราบว่าเมื่อเปิดใช้การตรวจจับรูปร่างหน้าตา ระบบจะตรวจจับใบหน้าเพียง 1 ใบหน้า การติดตามใบหน้าจึงไม่สร้างผลลัพธ์ที่เป็นประโยชน์ ด้วยเหตุนี้ อย่าเปิดใช้ทั้งการตรวจจับเส้นขอบและการติดตามใบหน้า หากต้องการปรับปรุงความเร็วในการตรวจจับ |
เช่น สร้างออบเจ็กต์ VisionFaceDetectorOptions
ตามตัวอย่างต่อไปนี้
Swift
// High-accuracy landmark detection and face classification let options = VisionFaceDetectorOptions() options.performanceMode = .accurate options.landmarkMode = .all options.classificationMode = .all // Real-time contour detection of multiple faces let options = VisionFaceDetectorOptions() options.contourMode = .all
Objective-C
// High-accuracy landmark detection and face classification FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init]; options.performanceMode = FIRVisionFaceDetectorPerformanceModeAccurate; options.landmarkMode = FIRVisionFaceDetectorLandmarkModeAll; options.classificationMode = FIRVisionFaceDetectorClassificationModeAll; // Real-time contour detection of multiple faces FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init]; options.contourMode = FIRVisionFaceDetectorContourModeAll;
2. เรียกใช้ตัวตรวจจับใบหน้า
หากต้องการตรวจจับใบหน้าในรูปภาพ ให้ส่งรูปภาพเป็นUIImage
หรือ CMSampleBufferRef
ไปยังเมธอด detect(in:)
ของ VisionFaceDetector
ดังนี้
- รับอินสแตนซ์ของ
VisionFaceDetector
:Swift
lazy var vision = Vision.vision() let faceDetector = vision.faceDetector(options: options)
Objective-C
FIRVision *vision = [FIRVision vision]; FIRVisionFaceDetector *faceDetector = [vision faceDetector]; // Or, to change the default settings: // FIRVisionFaceDetector *faceDetector = // [vision faceDetectorWithOptions:options];
-
สร้างออบเจ็กต์
VisionImage
โดยใช้UIImage
หรือCMSampleBufferRef
วิธีใช้
UIImage
- หากจำเป็น ให้หมุนรูปภาพเพื่อให้พร็อพเพอร์ตี้
imageOrientation
เป็น.up
- สร้างออบเจ็กต์
VisionImage
โดยใช้UIImage
ที่หมุนอย่างถูกต้อง และไม่ระบุข้อมูลเมตาการหมุนเวียน ระบบจะใช้ค่าเริ่มต้นซึ่งก็คือ.topLeft
Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
วิธีใช้
CMSampleBufferRef
-
สร้างออบเจ็กต์
VisionImageMetadata
ที่ระบุการวางแนวของข้อมูลรูปภาพที่อยู่ในบัฟเฟอร์CMSampleBufferRef
วิธีดูการวางแนวรูปภาพ
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
จากนั้นสร้างออบเจ็กต์ข้อมูลเมตา ดังนี้
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- สร้างออบเจ็กต์
VisionImage
โดยใช้ออบเจ็กต์CMSampleBufferRef
และข้อมูลเมตาการหมุน ดังนี้Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- หากจำเป็น ให้หมุนรูปภาพเพื่อให้พร็อพเพอร์ตี้
-
จากนั้นส่งรูปภาพไปยังเมธอด
detect(in:)
Swift
faceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... }
Objective-C
[faceDetector detectInImage:image completion:^(NSArray<FIRVisionFace *> *faces, NSError *error) { if (error != nil) { return; } else if (faces != nil) { // Recognized faces } }];
3. รับข้อมูลเกี่ยวกับใบหน้าที่ตรวจพบ
หากการตรวจจับใบหน้าสำเร็จ ตัวตรวจจับใบหน้าจะส่งอาร์เรย์ของออบเจ็กต์VisionFace
ไปยังเครื่องจัดการเสร็จสมบูรณ์ ออบเจ็กต์ VisionFace
แต่ละรายการแสดงใบหน้าที่ตรวจพบในรูปภาพ สำหรับใบหน้าแต่ละด้าน คุณจะดูพิกัดขอบเขตของใบหน้าได้ในรูปภาพอินพุต รวมถึงข้อมูลอื่นๆ ที่คุณกำหนดค่าให้ตัวตรวจจับใบหน้าค้นหา ตัวอย่างเช่น
Swift
for face in faces { let frame = face.frame if face.hasHeadEulerAngleY { let rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees } if face.hasHeadEulerAngleZ { let rotZ = face.headEulerAngleZ // Head is rotated upward 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 (FIRVisionFace *face in faces) { // Boundaries of face in image CGRect frame = face.frame; 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): FIRVisionFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar]; if (leftEar != nil) { FIRVisionPoint *leftEarPosition = leftEar.position; } // If contour detection was enabled: FIRVisionFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom]; if (upperLipBottomContour != nil) { NSArray<FIRVisionPoint *> *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 นี้ด้วย
- กดคันเร่งไปยังตัวตรวจจับ หากมีเฟรมวิดีโอใหม่ขณะที่ตัวตรวจจับทำงานอยู่ ให้วางเฟรมดังกล่าว
- หากคุณกำลังใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต ให้รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพและการวางซ้อนในขั้นตอนเดียว การทำเช่นนี้จะทําให้คุณแสดงผลบนพื้นผิวจอแสดงผลเพียงครั้งเดียวสําหรับเฟรมอินพุตแต่ละเฟรม โปรดดูคลาส previewOverlayView และ FIRDetectionOverlayView ในแอปตัวอย่าง Showcase