คุณใช้ ML Kit เพื่อจดจำและถอดรหัสบาร์โค้ดได้
ก่อนเริ่มต้น
- หากยังไม่ได้เพิ่ม Firebase ลงในแอป ให้ดำเนินการดังนี้ ขั้นตอนในคู่มือเริ่มต้นใช้งาน
- รวมไลบรารี ML Kit ไว้ใน Podfile ดังนี้
pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์แล้ว อย่าลืมเปิด Xcode โดยใช้.xcworkspace
- ในแอป ให้นำเข้า Firebase ดังนี้
Swift
import Firebase
Objective-C
@import Firebase;
หลักเกณฑ์เกี่ยวกับรูปภาพที่ป้อน
-
เพื่อให้ ML Kit อ่านบาร์โค้ดได้อย่างถูกต้อง รูปภาพที่ป้อนต้องมี บาร์โค้ดที่แสดงด้วยข้อมูลพิกเซลที่เพียงพอ
สำหรับข้อกำหนดด้านข้อมูลพิกเซลที่เจาะจงจะขึ้นอยู่กับทั้ง และปริมาณของข้อมูลที่เข้ารหัสในนั้น (เนื่องจากบาร์โค้ดส่วนใหญ่ รองรับเพย์โหลดความยาวที่เปลี่ยนแปลงได้) โดยทั่วไป ตัวแปรที่น้อยที่สุด หน่วยบาร์โค้ดควรกว้างอย่างน้อย 2 พิกเซล (และสำหรับ โค้ด 2 มิติ ความสูง 2 พิกเซล)
ตัวอย่างเช่น บาร์โค้ด EAN-13 ประกอบด้วยแท่งและการเว้นวรรคที่ 1 ความกว้าง 2, 3 หรือ 4 หน่วย ดังนั้นรูปภาพบาร์โค้ด EAN-13 จะมีแถบและ ช่องว่างที่มีความกว้างอย่างน้อย 2, 4, 6 และ 8 พิกเซล เนื่องจาก EAN-13 บาร์โค้ดมีความกว้างรวม 95 หน่วย บาร์โค้ดควรมีอย่างน้อย 190 พิกเซล
รูปแบบที่หนาแน่นกว่า เช่น PDF417 ต้องมีขนาดพิกเซลมากขึ้น ML Kit ให้อ่านได้อย่างน่าเชื่อถือ ตัวอย่างเช่น รหัส PDF417 สามารถมีได้สูงสุด "คำ" กว้าง 17 หน่วย 34 คำ ในแถวเดียว ซึ่งอย่างน้อยก็ กว้าง 1156 พิกเซล
-
การโฟกัสของรูปภาพไม่ดีอาจส่งผลเสียต่อความแม่นยำในการสแกน หากคุณไม่ได้รับ ผลลัพธ์ที่ยอมรับได้ ลองขอให้ผู้ใช้จับภาพอีกครั้ง
-
สำหรับแอปพลิเคชันทั่วไป ขอแนะนำให้ใช้ รูปภาพที่มีความละเอียด (เช่น 1280x720 หรือ 1920x1080) ซึ่งทำให้บาร์โค้ด ตรวจพบได้ในระยะที่ห่างจากกล้องมากขึ้น
อย่างไรก็ตาม ในแอปพลิเคชันที่เวลาในการตอบสนองเป็นสิ่งที่สำคัญ คุณสามารถ ด้วยการจับภาพด้วยความละเอียดที่ต่ำลง บาร์โค้ดนั้นทำให้พื้นที่ส่วนใหญ่ของภาพป้อนข้อมูล ดูนี่ด้วย เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
1. กำหนดค่าตัวตรวจจับบาร์โค้ด
หากคุณทราบว่าจะอ่านบาร์โค้ดรูปแบบใด คุณสามารถเร่งความเร็ว ในตัวตรวจจับบาร์โค้ดโดยกำหนดค่าให้ตรวจหาเฉพาะรูปแบบเหล่านั้นตัวอย่างเช่น หากต้องการตรวจหาเฉพาะโค้ดแอซเท็กและคิวอาร์โค้ด ให้สร้าง
VisionBarcodeDetectorOptions
เช่นเดียวกับใน
ตัวอย่างต่อไปนี้
Swift
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
รูปแบบที่รองรับมีดังนี้
- โค้ด 128
- โค้ด 39
- โค้ด 93
- คอดาบาร์
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- คิวอาร์โค้ด
- PDF417
- แอซเท็ก
- เมทริกซ์ข้อมูล
Objective-C
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
รูปแบบที่รองรับมีดังนี้
- รหัส 128 (
FIRVisionBarcodeFormatCode128
) - รหัส 39 (
FIRVisionBarcodeFormatCode39
) - รหัส 93 (
FIRVisionBarcodeFormatCode93
) - คอดาบาร์ (
FIRVisionBarcodeFormatCodaBar
) - EAN-13 (
FIRVisionBarcodeFormatEAN13
) - EAN-8 (
FIRVisionBarcodeFormatEAN8
) - ITF (
FIRVisionBarcodeFormatITF
) - UPC-A (
FIRVisionBarcodeFormatUPCA
) - UPC-E (
FIRVisionBarcodeFormatUPCE
) - คิวอาร์โค้ด (
FIRVisionBarcodeFormatQRCode
) - PDF417 (
FIRVisionBarcodeFormatPDF417
) - แอซเท็ก (
FIRVisionBarcodeFormatAztec
) - เมทริกซ์ข้อมูล (
FIRVisionBarcodeFormatDataMatrix
)
2. เรียกใช้ตัวตรวจจับบาร์โค้ด
หากต้องการสแกนบาร์โค้ดในรูปภาพ ให้ส่งรูปภาพเป็นUIImage
หรือ
CMSampleBufferRef
ไปยัง detect(in:)
ของ VisionBarcodeDetector
วิธีการ:
- รับอินสแตนซ์ของ
VisionBarcodeDetector
:Swift
lazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
Objective-C
FIRVision *vision = [FIRVision vision]; FIRVisionBarcodeDetector *barcodeDetector = [vision barcodeDetector]; // Or, to change the default settings: // FIRVisionBarcodeDetector *barcodeDetector = // [vision barcodeDetectorWithOptions: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
barcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... }
Objective-C
[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }];
3. รับข้อมูลจากบาร์โค้ด
หากการดำเนินการจดจำบาร์โค้ดสำเร็จ ตัวตรวจจับจะส่งอาร์เรย์ของVisionBarcode
ออบเจ็กต์ ออบเจ็กต์ VisionBarcode
แต่ละรายการแสดงถึง
บาร์โค้ดที่ตรวจพบในรูปภาพ สำหรับบาร์โค้ดแต่ละรายการ คุณสามารถดู
พิกัดขอบเขตในภาพอินพุต รวมถึงข้อมูลดิบที่เข้ารหัสโดย
บาร์โค้ด นอกจากนี้ หากตัวตรวจจับบาร์โค้ดระบุประเภทข้อมูล
ที่เข้ารหัสโดยบาร์โค้ด คุณจะสามารถรับออบเจ็กต์ที่มีข้อมูลที่แยกวิเคราะห์แล้ว
เช่น
Swift
for barcode in barcodes { let corners = barcode.cornerPoints let displayValue = barcode.displayValue let rawValue = barcode.rawValue let valueType = barcode.valueType switch valueType { case .wiFi: let ssid = barcode.wifi!.ssid let password = barcode.wifi!.password let encryptionType = barcode.wifi!.type case .URL: let title = barcode.url!.title let url = barcode.url!.url default: // See API reference for all supported value types } }
Objective-C
for (FIRVisionBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; FIRVisionBarcodeValueType valueType = barcode.valueType; switch (valueType) { case FIRVisionBarcodeValueTypeWiFi: // ssid = barcode.wifi.ssid; // password = barcode.wifi.password; // encryptionType = barcode.wifi.type; break; case FIRVisionBarcodeValueTypeURL: // url = barcode.URL.url; // title = barcode.URL.title; break; // ... default: break; } }
เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
หากต้องการสแกนบาร์โค้ดในแอปพลิเคชันแบบเรียลไทม์ โปรดทำตามขั้นตอนต่อไปนี้ เพื่อให้ได้อัตราเฟรมที่ดีที่สุด
-
อย่าจับภาพอินพุตที่ความละเอียดดั้งเดิมของกล้อง ในอุปกรณ์บางรุ่น การบันทึกอินพุตที่ความละเอียดดั้งเดิมทำให้เกิดขนาดใหญ่มาก (10+ (เมกะพิกเซล) ซึ่งส่งผลให้เวลาในการตอบสนองต่ำมาก โดยที่ไม่เกิดประโยชน์ใดๆ ความแม่นยำ ให้ขอเฉพาะขนาดจากกล้องที่จำเป็นต้องใช้เท่านั้นแทน สำหรับการตรวจจับบาร์โค้ด: โดยปกติจะไม่เกิน 2 เมกะพิกเซล
ค่าที่กำหนดล่วงหน้าของเซสชันการบันทึกที่มีชื่อ -
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
AVCaptureSessionPresetMedium
และอื่นๆ) แต่ไม่แนะนำเนื่องจากสามารถจับคู่กับ ความละเอียดที่ไม่เหมาะสมในบางอุปกรณ์ ให้ใช้ค่าที่กำหนดล่วงหน้าแทน เช่นAVCaptureSessionPreset1280x720
หากความเร็วในการสแกนเป็นสิ่งสำคัญ คุณจะลดการจับภาพลงได้ ความละเอียดสูงสุดของคุณ แต่โปรดคำนึงถึงข้อกำหนดเกี่ยวกับขนาดบาร์โค้ดขั้นต่ำ ตามที่ระบุไว้ข้างต้น
- กดคันเร่งไปยังตัวตรวจจับ หากเฟรมวิดีโอใหม่กลายเป็น วางเฟรมได้ในขณะที่ตัวตรวจจับกำลังทำงานอยู่
- หากคุณกำลังใช้เอาต์พุตของเครื่องมือตรวจจับเพื่อวางซ้อนกราฟิก รูปภาพอินพุต รับผลลัพธ์จาก ML Kit ก่อน จากนั้นจึงแสดงผลรูปภาพ ซ้อนทับในขั้นตอนเดียว การทำเช่นนี้จะช่วยให้แสดงผลบนพื้นผิวจอแสดงผล เพียงครั้งเดียวสำหรับเฟรมอินพุตแต่ละเฟรม โปรดดู previewOverlayView และ FIRDetectionOverlayView ในตัวอย่างแอป Showcase