คุณใช้ ML Kit เพื่อจดจําข้อความในรูปภาพหรือวิดีโอได้ เช่น ข้อความเครื่องหมายจราจร ฟีเจอร์หลักของฟีเจอร์นี้มีดังนี้
API การจดจําข้อความ | |
---|---|
คำอธิบาย | จดจําตัวอักษรภาษาละตินในรูปภาพหรือวิดีโอ |
ชื่อ SDK | Google |
การใช้งาน | ชิ้นงานจะลิงก์อยู่กับแอปในเวลาที่สร้างบิลด์ |
ผลกระทบต่อขนาดแอป | ประมาณ 20 MB |
ประสิทธิภาพ | เรียลไทม์ในอุปกรณ์ส่วนใหญ่ |
ลองใช้งาน
- ลองใช้แอปตัวอย่างเพื่อดูตัวอย่างการใช้งาน API นี้
- ลองใช้โค้ดด้วยตนเองโดยใช้ codelab
ข้อควรทราบก่อนที่จะเริ่มต้น
- รวมพ็อด ML Kit ต่อไปนี้ใน Podfile
pod 'GoogleMLKit/TextRecognition','2.2.0'
- หลังจากติดตั้งหรืออัปเดตพ็อดของโปรเจ็กต์ ให้เปิดโปรเจ็กต์ Xcode โดยใช้
.xcworkspace
XKit เวอร์ชัน 12.4 ขึ้นไปรองรับ ML Kit
1. สร้างอินสแตนซ์ของ TextRecognizer
สร้างอินสแตนซ์ของ TextRecognizer
TextRecognizer
โดยการเรียกใช้
+textRecognizer
:
let textRecognizer = TextRecognizer.textRecognizer()
MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
2. เตรียมรูปภาพอินพุต
ส่งรูปภาพเป็นUIImage
หรือ CMSampleBufferRef
ไปยังเมธอด process(_:completion:)
ของ TextRecognizer
สร้างออบเจ็กต์ VisionImage
โดยใช้ UIImage
หรือ CMSampleBuffer
หากคุณใช้ UIImage
ให้ทําตามขั้นตอนต่อไปนี้
- สร้างออบเจ็กต์
VisionImage
ด้วยUIImage
ตรวจสอบว่าได้ระบุ.orientation
ที่ถูกต้องlet image = VisionImage(image: UIImage)
visionImage.orientation = image.imageOrientationMLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
visionImage.orientation = image.imageOrientation;
หากคุณใช้ CMSampleBuffer
ให้ทําตามขั้นตอนต่อไปนี้
-
ระบุการวางแนวของข้อมูลรูปภาพที่มีอยู่ใน
CMSampleBuffer
วิธีดูการวางแนวรูปภาพ
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
}
}
- (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
และการวางแนวดังนี้let image = VisionImage(buffer: sampleBuffer)
image.orientation = imageOrientation(
deviceOrientation: UIDevice.current.orientation,
cameraPosition: cameraPosition)MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
image.orientation =
[self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
cameraPosition:cameraPosition];
3. ประมวลผลรูปภาพ
จากนั้นส่งรูปภาพไปยังเมธอด process(_:completion:)
ดังนี้
textRecognizer.process(visionImage) { result, error in
guard error == nil, let result = result else {
// Error handling
return
}
// Recognized text
}
[textRecognizer processImage:image
completion:^(MLKText *_Nullable result,
NSError *_Nullable error) {
if (error != nil || result == nil) {
// Error handling
return;
}
// Recognized text
}];
4. ดึงข้อความจากบล็อกของข้อความที่รู้จัก
หากการดําเนินการจดจําข้อความสําเร็จ ระบบจะแสดงออบเจ็กต์ Text
ออบเจ็กต์ Text
มีข้อความฉบับเต็มที่ได้รับการยอมรับในรูปภาพและออบเจ็กต์ TextBlock
อย่างน้อย 0 รายการ
TextBlock
แต่ละรายการแสดงถึงบล็อกข้อความสี่เหลี่ยมผืนผ้าซึ่งมีออบเจ็กต์ TextLine
อย่างน้อย 0 รายการ ออบเจ็กต์ TextLine
แต่ละรายการมีออบเจ็กต์ TextElement
อย่างน้อย 0 รายการ ซึ่งแสดงถึงคําและเอนทิตีที่คล้ายกับคํา เช่น วันที่และตัวเลข
สําหรับออบเจ็กต์ TextBlock
, TextLine
และ TextElement
แต่ละรายการ คุณจะได้รับข้อความที่รู้จักในภูมิภาคและพิกัดขอบเขตของภูมิภาค
เช่น
let resultText = result.text
for block in result.blocks {
let blockText = block.text
let blockLanguages = block.recognizedLanguages
let blockCornerPoints = block.cornerPoints
let blockFrame = block.frame
for line in block.lines {
let lineText = line.text
let lineLanguages = line.recognizedLanguages
let lineCornerPoints = line.cornerPoints
let lineFrame = line.frame
for element in line.elements {
let elementText = element.text
let elementCornerPoints = element.cornerPoints
let elementFrame = element.frame
}
}
}
NSString *resultText = result.text;
for (MLKTextBlock *block in result.blocks) {
NSString *blockText = block.text;
NSArray<MLKTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages;
NSArray<NSValue *> *blockCornerPoints = block.cornerPoints;
CGRect blockFrame = block.frame;
for (MLKTextLine *line in block.lines) {
NSString *lineText = line.text;
NSArray<MLKTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages;
NSArray<NSValue *> *lineCornerPoints = line.cornerPoints;
CGRect lineFrame = line.frame;
for (MLKTextElement *element in line.elements) {
NSString *elementText = element.text;
NSArray<NSValue *> *elementCornerPoints = element.cornerPoints;
CGRect elementFrame = element.frame;
}
}
}
หลักเกณฑ์เกี่ยวกับรูปภาพที่ป้อน
-
รูปภาพที่ป้อนต้องมีข้อความที่แสดงด้วยข้อมูลพิกเซลที่เพียงพอเพื่อให้ ML Kit จดจําข้อความได้อย่างแม่นยํา โดยหลักการแล้ว แต่ละอักขระควรมีขนาดอย่างน้อย 16x16 พิกเซล โดยทั่วไปแล้ว ประโยชน์ที่ได้คืออักขระมีขนาดใหญ่กว่า 24x24 พิกเซล
เช่น รูปภาพขนาด 640x480 อาจทํางานได้ดีสําหรับสแกนนามบัตรที่ใช้เต็มความกว้างของรูปภาพ หากต้องการสแกนเอกสารที่พิมพ์บนกระดาษขนาดตัวอักษร คุณอาจต้องใช้รูปภาพขนาด 720x1280 พิกเซล
-
การโฟกัสรูปภาพที่ไม่ดีอาจส่งผลต่อการจดจําข้อความ หากไม่ได้รับผลการค้นหาที่ยอมรับได้ ให้ลองขอให้ผู้ใช้จับภาพอีกครั้ง
-
หากคุณจําข้อความในแอปพลิเคชันแบบเรียลไทม์ได้ ก็ควรคํานึงถึงขนาดโดยรวมของรูปภาพที่ป้อน รูปภาพขนาดเล็กประมวลผลได้เร็วขึ้น หากต้องการลดเวลาในการตอบสนอง ให้ตรวจสอบว่าข้อความใช้รูปภาพเป็นจํานวนมากที่สุดเท่าที่จะเป็นไปได้ และจับภาพที่ความละเอียดต่ําลง (โปรดคํานึงถึงข้อกําหนดความถูกต้องที่ระบุไว้ข้างต้น) ดูข้อมูลเพิ่มเติมได้ที่เคล็ดลับในการปรับปรุงประสิทธิภาพ
เคล็ดลับในการปรับปรุงประสิทธิภาพ
- สําหรับการประมวลผลเฟรมวิดีโอ ให้ใช้
results(in:)
API แบบพร้อมกันของตัวตรวจจับ เรียกวิธีนี้จากฟังก์ชันcaptureOutput(_, didOutput:from:)
ของAVCaptureVideoDataOutputSampleBufferDelegate
เพื่อให้ได้ผลลัพธ์พร้อมกันจากเฟรมวิดีโอที่ระบุ เก็บalwaysDiscardsLateVideoFrames
ของAVCaptureVideoDataOutput
ไว้เป็นtrue
เพื่อควบคุมการโทรไปยังตัวตรวจจับ หาก เฟรมวิดีโอใหม่พร้อมใช้งานระหว่างตัวตรวจจับจะทํางาน เฟรมจะหายไป - หากใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต ก่อนอื่นให้ดูผลลัพธ์จาก ML Kit จากนั้นแสดงผลรูปภาพและวางซ้อนในขั้นตอนเดียว เมื่อทําเช่นนั้น คุณจะแสดงผลบนพื้นที่แสดงผลเพียงครั้งเดียวสําหรับเฟรมอินพุตแต่ละรายการที่ประมวลผลแล้ว ดูตัวอย่าง update PreviewOverlayViewWithLastFrame ในตัวอย่างคู่มือเริ่มใช้งานฉบับย่อสําหรับ ML Kit
- ลองจับภาพที่ความละเอียดต่ําลง อย่างไรก็ตาม โปรดทราบว่าข้อกําหนดด้านขนาดของรูปภาพของ API นี้เช่นกัน