आप बारकोड पहचानने और डिकोड करने के लिए ML किट का इस्तेमाल कर सकते हैं.
इसे आज़माएं
- इस एपीआई के इस्तेमाल का उदाहरण देखने के लिए, ऐप्लिकेशन के नमूने का इस्तेमाल करें.
शुरू करने से पहले
- अपनी Podfile में ये ML किट पॉड शामिल करें:
pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
- अपने प्रोजेक्ट के पॉड इंस्टॉल करने या अपडेट करने के बाद, अपने
.xcworkspace
कोड का इस्तेमाल करके Xcode प्रोजेक्ट खोलें. ML किट, Xcode के 12.4 या इसके बाद के वर्शन पर काम करती है.
इनपुट इमेज के दिशा-निर्देश
-
मशीन लर्निंग (ML) किट में मौजूद बारकोड को सही तरीके से पढ़ने के लिए, इनपुट इमेज में ऐसे बारकोड होने चाहिए जिन्हें पिक्सल डेटा की मदद से दिखाया गया हो.
पिक्सल से जुड़ी ज़रूरी शर्तें, बारकोड के टाइप और उसमें एन्कोड किए गए डेटा, दोनों के आधार पर तय की जाती हैं. ऐसा इसलिए होता है, क्योंकि कई बारकोड में वैरिएबल साइज़ पेलोड होता है. आम तौर पर, बारकोड की सबसे छोटी और अहम जानकारी वाली यूनिट कम से कम 2 पिक्सल की होनी चाहिए. साथ ही, दो डाइमेंशन वाले कोड और दो पिक्सल लंबे होने चाहिए.
उदाहरण के लिए, EAN-13 बारकोड में ऐसे बार और स्पेस होते हैं जो 1, 2, 3 या 4 यूनिट वाले होते हैं. इसलिए, EAN-13 बारकोड इमेज में कम से कम 2, 4, 6, और 8 पिक्सल की चौड़ाई वाले बार और स्पेस होते हैं. ईएएन-13 बारकोड की लंबाई 95 यूनिट होती है. इसलिए, बारकोड कम से कम 190 पिक्सल का होना चाहिए.
डेंसर के फ़ॉर्मैट, जैसे कि PDF417 का इस्तेमाल करने से, पिक्सल पिक्सल को बेहतर तरीके से पढ़ने में मदद मिलती है. उदाहरण के लिए, PDF417 कोड में एक ही पंक्ति में ज़्यादा से ज़्यादा 34 17 यूनिट वाली चौड़ी "शब्द" हो सकती है जो आम तौर पर कम से कम 1156 पिक्सल चौड़ी होनी चाहिए.
-
इमेज का फ़ोकस ठीक न होने से, स्कैन करने की प्रोसेस पर असर पड़ सकता है. अगर आपके ऐप्लिकेशन को स्वीकार किए जाने वाले नतीजे नहीं मिल रहे हैं, तो उपयोगकर्ता से इमेज को फिर से देखने के लिए कहें.
-
आम तौर पर इस्तेमाल किए जाने वाले ऐप्लिकेशन के लिए, ज़्यादा रिज़ॉल्यूशन वाली इमेज देने का सुझाव दिया जाता है, जैसे कि 1280x720 या 1920x1080. ऐसी इमेज में बारकोड को कैमरे से दूर से स्कैन किया जा सकता है.
हालांकि, जिन ऐप्लिकेशन में इंतज़ार का समय बहुत कम होता है उनमें इमेज को कम रिज़ॉल्यूशन में कैप्चर करके, परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. हालांकि, इनपुट के ज़्यादातर हिस्से में बारकोड शामिल होना चाहिए. रीयल-टाइम परफ़ॉर्मेंस को बेहतर बनाने के लिए सलाह भी देखें.
1. बारकोड स्कैनर कॉन्फ़िगर करें
अगर आपको पता है कि आपको किस बारकोड फ़ॉर्मैट को पढ़ना है, तो आप बारकोड स्कैनर को सिर्फ़ उन फ़ॉर्मैट को स्कैन करने के लिए कॉन्फ़िगर करके, उसकी स्पीड को बेहतर बना सकते हैं.उदाहरण के लिए, सिर्फ़ ऐज़टेक कोड और क्यूआर कोड स्कैन करने के लिए, BarcodeScannerOptions
ऑब्जेक्ट बनाएं, जैसा कि इस उदाहरण में दिया गया है:
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
इस फ़ॉर्मैट का इस्तेमाल किया जा सकता है:
- कोड128
- कोड39
- कोड93
- codaBar
- डेटा मैट्रिक्स
- EAN13
- EAN8
- आईटीएफ़
- क्यूआर कोड
- यूपीसीए
- यूपीसी
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
इस फ़ॉर्मैट का इस्तेमाल किया जा सकता है:
- कोड-128 (
MLKBarcodeFormatCode128
) - कोड-39 (
MLKBarcodeFormatCode39
) - कोड-93 (
MLKBarcodeFormatCode93
) - कोडाबार (
MLKBarcodeFormatCodaBar
) - डेटा मैट्रिक्स (
MLKBarcodeFormatDataMatrix
) - EAN-13 (
MLKBarcodeFormatEAN13
) - ईएएन-8 (
MLKBarcodeFormatEAN8
) - आईटीएफ़ (
MLKBarcodeFormatITF
) - क्यूआर कोड (
MLKBarcodeFormatQRCode
) - यूपीसी-ए (
MLKBarcodeFormatUPCA
) - यूपीसी-ई (
MLKBarcodeFormatUPCE
) - PDF-417 (
MLKBarcodeFormatPDF417
) - ऐज़टेक कोड (
MLKBarcodeFormatAztec
)
2. इनपुट इमेज तैयार करें
बारकोड को स्कैन करने के लिए,BarcodeScanner
या process()
वाले तरीके का इस्तेमाल करके इमेज को UIImage
या
CMSampleBufferRef
के तौर पर पास करें:
UIImage
या CMSampleBuffer
का इस्तेमाल करके, VisionImage
ऑब्जेक्ट बनाएं.
अगर आप UIImage
का इस्तेमाल करते हैं, तो यह तरीका अपनाएं:
UIImage
के साथ एकVisionImage
ऑब्जेक्ट बनाएं..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; } }
CMSampleBuffer
ऑब्जेक्ट और ओरिएंटेशन का इस्तेमाल करकेVisionImage
ऑब्जेक्ट बनाएं: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. BarcodeScanner का एक उदाहरण पाएं
BarcodeScanner
का एक उदाहरण पाएं:
Swift
let barcodeScanner = BarcodeScanner.barcodeScanner() // Or, to change the default settings: // let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)
Objective-C
MLKBarcodeScanner *barcodeScanner = [MLKBarcodeScanner barcodeScanner]; // Or, to change the default settings: // MLKBarcodeScanner *barcodeScanner = // [MLKBarcodeScanner barcodeScannerWithOptions:options];
4. इमेज को प्रोसेस करें
इसके बाद, इमेज कोprocess()
वाले तरीके पर भेजें:
Swift
barcodeScanner.process(visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // Error handling return } // Recognized barcodes }
Objective-C
[barcodeScanner processImage:image completion:^(NSArray<MLKBarcode *> *_Nullable barcodes, NSError *_Nullable error) { if (error != nil) { // Error handling return; } if (barcodes.count > 0) { // Recognized barcodes } }];
5. बारकोड से जानकारी पाएं
अगर बारकोड स्कैनिंग की कार्रवाई पूरी होती है, तो स्कैनरBarcode
ऑब्जेक्ट की कैटगरी दिखाता है. हर Barcode
ऑब्जेक्ट, बारकोड में दिखता है जो इमेज में मिला था. हर बारकोड के लिए, आपको इनपुट इमेज में इसके बाउंडिंग कोऑर्डिनेट के साथ-साथ बारकोड से एन्कोड किया गया रॉ डेटा मिल सकता है. साथ ही, अगर बारकोड स्कैनर यह तय कर सकता है कि बारकोड से किस तरह का डेटा एन्कोड किया जाएगा, तो आपको पार्स किया गया डेटा वाला एक ऑब्जेक्ट मिल सकता है.
उदाहरण के लिए :
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 (MLKBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; MLKBarcodeValueType valueType = barcode.valueType; switch (valueType) { case MLKBarcodeValueTypeWiFi: ssid = barcode.wifi.ssid; password = barcode.wifi.password; encryptionType = barcode.wifi.type; break; case MLKBarcodeValueTypeURL: url = barcode.URL.url; title = barcode.URL.title; break; // ... default: break; } }
रीयल-टाइम में परफ़ॉर्मेंस को बेहतर बनाने के लिए सलाह
अगर आप रीयल-टाइम ऐप्लिकेशन में बारकोड स्कैन करना चाहते हैं, तो सबसे अच्छे फ़्रेम रेट पाने के लिए, इन दिशा-निर्देशों का पालन करें:
-
इनपुट को कैमरे के खास रिज़ॉल्यूशन में कैप्चर न करें. कुछ डिवाइसों पर, नेटिव रिज़ॉल्यूशन पर इनपुट कैप्चर करने से बहुत बड़ी (10+ मेगापिक्सल) इमेज बनती हैं. इस वजह से, इंतज़ार का समय बहुत कम होता है और सटीक होने का कोई फ़ायदा नहीं होता. इसके बजाय, बारकोड के लिए ज़रूरी कैमरे से ही साइज़ का अनुरोध करें. आम तौर पर, फ़ाइल का साइज़ दो मेगापिक्सल से ज़्यादा नहीं होना चाहिए.
नाम वाले कैप्चर प्रीसेट—
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
, वगैरह) का सुझाव नहीं दिया जाता, क्योंकि वे कुछ डिवाइसों पर सही रिज़ॉल्यूशन पर मैप हो सकते हैं. इसके बजाय, खास प्रीसेट, जैसे किAVCaptureSessionPreset1280x720
का इस्तेमाल करें.अगर स्कैनिंग की गति अहम है, तो इमेज कैप्चर करने के रिज़ॉल्यूशन को कम किया जा सकता है. हालांकि, ध्यान रखें कि ऊपर बताए गए बारकोड के साइज़ की शर्तें कम से कम हों.
अगर वीडियो स्ट्रीम करने वाले क्रम में मौजूद बारकोड को पहचानने की कोशिश की जा रही है, तो हो सकता है कि पहचानकर्ता फ़्रेम-टू-फ़्रेम पर अलग-अलग नतीजे दिखाए. आपको अच्छे नतीजे देने के लिए, एक ही वैल्यू की लगातार सीरीज़ मिलने तक इंतज़ार करना चाहिए.
Checksum अंक का इस्तेमाल ITF और CODE-39 के लिए नहीं किया जा सकता.
- वीडियो फ़्रेम प्रोसेस करने के लिए, डिटेक्टर के
results(in:)
सिंक्रोनस एपीआई का इस्तेमाल करें. दिए गए वीडियो फ़्रेम से सिंक्रोनस रूप से परिणाम पाने के लिएAVCaptureVideoDataOutputSampleBufferDelegate
केcaptureOutput(_, didOutput:from:)
फ़ंक्शन से इस विधि को कॉल करें.AVCaptureVideoDataOutput
कीalwaysDiscardsLateVideoFrames
कोtrue
के तौर पर रखें, ताकि डिटेक्टर को कॉल थ्रॉटल किए जा सकें. अगर डिटेक्टर चलने के दौरान नया वीडियो फ़्रेम उपलब्ध हो जाता है, तो उसे छोड़ दिया जाएगा. - अगर आप इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए डिटेक्टर के आउटपुट का इस्तेमाल करते हैं, तो पहले ML किट से नतीजा पाएं. इसके बाद, इमेज और ओवरले को एक ही चरण में रेंडर करें. ऐसा करके, आप हर प्रोसेस किए गए इनपुट फ़्रेम के लिए डिसप्ले को सिर्फ़ एक बार रेंडर करते हैं. उदाहरण के लिए, ML किट क्विकस्टार्ट सैंपल में updatepreviewOverlayViewWithLastFrame देखें.