คุณสามารถใช้ 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'
หลังจากที่คุณติดตั้งหรืออัปเดต Pod ของโปรเจ็กต์แล้ว อย่าลืมเปิดโปรเจ็กต์ Xcode โดยใช้.xcworkspace
- ในแอปของคุณ ให้นำเข้า Firebase:
สวิฟท์
import Firebase
วัตถุประสงค์-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 ไม่ว่าจะกำหนด ID ใบหน้าหรือไม่ ซึ่งสามารถใช้เพื่อติดตามใบหน้าในรูปภาพต่างๆ โปรดทราบว่าเมื่อเปิดใช้งานการตรวจจับรูปร่าง ระบบจะตรวจจับใบหน้าเดียวเท่านั้น ดังนั้นการติดตามใบหน้าจึงไม่ให้ผลลัพธ์ที่เป็นประโยชน์ ด้วยเหตุผลนี้ และเพื่อปรับปรุงความเร็วในการตรวจจับ อย่าเปิดใช้งานทั้งการตรวจจับรูปร่างและการติดตามใบหน้า |
ตัวอย่างเช่น สร้างออบเจ็กต์ VisionFaceDetectorOptions
ตามตัวอย่างใดตัวอย่างหนึ่งต่อไปนี้:
สวิฟท์
// 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
วัตถุประสงค์-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
ไปยังวิธีการตรวจจับของ VisionFaceDetector
detect(in:)
:- รับอินสแตนซ์ของ
VisionFaceDetector
:สวิฟท์
lazy var vision = Vision.vision() let faceDetector = vision.faceDetector(options: options)
วัตถุประสงค์-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
สวิฟท์
let image = VisionImage(image: uiImage)
วัตถุประสงค์-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
วิธีใช้
CMSampleBufferRef
:สร้างออบเจ็กต์
VisionImageMetadata
ที่ระบุการวางแนวของข้อมูลรูปภาพที่มีอยู่ในบัฟเฟอร์CMSampleBufferRef
เพื่อให้ได้การวางแนวของภาพ:
สวิฟท์
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 } }
วัตถุประสงค์-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; } }
จากนั้นสร้างวัตถุข้อมูลเมตา:
สวิฟท์
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
วัตถุประสงค์-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
และข้อมูลเมตาการหมุน:สวิฟท์
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
วัตถุประสงค์-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- หากจำเป็น ให้หมุนรูปภาพเพื่อให้คุณสมบัติ
- จากนั้นส่งภาพไปยังวิธี
detect(in:)
:สวิฟท์
faceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... }
วัตถุประสงค์-C
[faceDetector detectInImage:image completion:^(NSArray<FIRVisionFace *> *faces, NSError *error) { if (error != nil) { return; } else if (faces != nil) { // Recognized faces } }];
3. รับข้อมูลเกี่ยวกับใบหน้าที่ตรวจพบ
หากการดำเนินการตรวจจับใบหน้าสำเร็จ อุปกรณ์ตรวจจับใบหน้าจะส่งอาร์เรย์ของออบเจ็กต์VisionFace
ไปยังตัวจัดการความสมบูรณ์ วัตถุ VisionFace
แต่ละชิ้นแสดงถึงใบหน้าที่ตรวจพบในภาพ สำหรับแต่ละใบหน้า คุณสามารถรับพิกัดขอบเขตในภาพที่ป้อน รวมถึงข้อมูลอื่น ๆ ที่คุณกำหนดค่าให้เครื่องตรวจจับใบหน้าค้นหา ตัวอย่างเช่น: สวิฟท์
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 } }
วัตถุประสงค์-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; } }
ตัวอย่างรูปทรงใบหน้า
เมื่อคุณเปิดใช้งานการตรวจจับรูปร่างใบหน้า คุณจะได้รับรายการจุดสำหรับลักษณะใบหน้าแต่ละส่วนที่ตรวจพบ จุดเหล่านี้แสดงถึงรูปร่างของจุดสนใจ ดู ภาพรวมแนวคิดการตรวจจับใบหน้า สำหรับรายละเอียดเกี่ยวกับวิธีการแสดงรูปทรง
รูปภาพต่อไปนี้แสดงให้เห็นว่าจุดเหล่านี้แมปกับใบหน้าอย่างไร (คลิกที่ภาพเพื่อขยาย):
การตรวจจับใบหน้าแบบเรียลไทม์
หากคุณต้องการใช้การตรวจจับใบหน้าในแอปพลิเคชันแบบเรียลไทม์ ให้ปฏิบัติตามคำแนะนำเหล่านี้เพื่อให้ได้เฟรมเรตที่ดีที่สุด:
กำหนดค่าเครื่องตรวจจับใบหน้า เพื่อใช้การตรวจจับรูปร่างใบหน้าหรือการจำแนกประเภทและการตรวจจับจุดสังเกต แต่ไม่ใช่ทั้งสองอย่าง:
การตรวจจับรูปร่าง
การตรวจจับจุดสังเกต
การจัดหมวดหมู่
การตรวจจับและจำแนกจุดสังเกต
การตรวจจับรูปร่างและการตรวจจับจุดสังเกต
การตรวจจับและการจำแนกรูปร่าง
การตรวจจับรูปร่าง การตรวจจับจุดสังเกต และการจำแนกประเภทเปิดใช้งานโหมด
fast
(เปิดใช้งานตามค่าเริ่มต้น)ลองถ่ายภาพด้วยความละเอียดที่ต่ำกว่า อย่างไรก็ตาม โปรดคำนึงถึงข้อกำหนดด้านมิติรูปภาพของ API นี้ด้วย
- คันเร่งเรียกไปที่เครื่องตรวจจับ หากมีเฟรมวิดีโอใหม่ในขณะที่ตัวตรวจจับกำลังทำงานอยู่ ให้ปล่อยเฟรมนั้น
- หากคุณใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต อันดับแรกรับผลลัพธ์จาก ML Kit จากนั้นเรนเดอร์รูปภาพและโอเวอร์เลย์ในขั้นตอนเดียว การทำเช่นนี้ คุณจะเรนเดอร์ไปยังพื้นผิวจอแสดงผลเพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุต ดูตัวอย่างคลาส PreviewOverlayView และ FIRDetectionOverlayView ในแอปตัวอย่าง Showcase