میتوانید از کیت ML برای تشخیص متن در تصاویر یا ویدیو، مانند متن تابلوهای خیابان، استفاده کنید. ویژگی های اصلی این ویژگی عبارتند از:
Text Recognition API | |
---|---|
شرح | متن لاتین را در تصاویر یا ویدیوها تشخیص دهید. |
نام SDK | Google |
پیاده سازی | دارایی ها به صورت ایستا به برنامه شما در زمان ساخت مرتبط می شوند. |
تاثیر اندازه برنامه | حدود 20 مگابایت |
کارایی | زمان واقعی در اکثر دستگاه ها. |
آن را امتحان کنید
- با برنامه نمونه بازی کنید تا نمونه استفاده از این API را ببینید.
- کد را خودتان با Codelab امتحان کنید.
قبل از اینکه شروع کنی
- غلافهای کیت ML زیر را در فایل پادفایل خود قرار دهید:
pod 'GoogleMLKit/TextRecognition','2.2.0'
- پس از نصب یا به روز رسانی Pods پروژه خود، پروژه Xcode خود را با استفاده از
.xcworkspace
. آن باز کنید. کیت ML در Xcode نسخه 12.4 یا بالاتر پشتیبانی می شود.
1. یک نمونه از TextRecognizer
با فراخوانی TextRecognizer
+textRecognizer
یک نمونه از TextRecognizer
ایجاد کنید:let textRecognizer = TextRecognizer.textRecognizer()
MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
2. تصویر ورودی را آماده کنید
تصویر را به عنوان UIImage
یا CMSampleBufferRef
به روش TextRecognizer
process(_:completion:)
منتقل کنید: با استفاده از UIImage
یا CMSampleBuffer
VisionImage
.
اگر از UIImage
استفاده می کنید، این مراحل را دنبال کنید:
- با
VisionImage
یک شیUIImage
کنید. مطمئن شوید که جهت.orientation
را مشخص کرده اید.
اگر از 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
است.
هر TextBlock
یک بلوک مستطیلی از متن را نشان می دهد که حاوی صفر یا چند شی TextLine
است. هر شی TextLine
حاوی صفر یا چند شی TextElement
است که بیانگر کلمات و موجودات کلمه مانندی مانند تاریخ و اعداد است.
برای هر شی 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 بتواند متن را به طور دقیق تشخیص دهد، تصاویر ورودی باید حاوی متنی باشند که با داده پیکسلی کافی نشان داده شود. در حالت ایده آل، هر کاراکتر باید حداقل 16x16 پیکسل باشد. به طور کلی هیچ مزیت دقت برای کاراکترهای بزرگتر از 24x24 پیکسل وجود ندارد.
بنابراین، برای مثال، یک تصویر 640x480 ممکن است برای اسکن کارت ویزیتی که تمام عرض تصویر را اشغال می کند، به خوبی کار کند. برای اسکن یک سند چاپ شده روی کاغذ با اندازه حرف، ممکن است به یک تصویر 720x1280 پیکسل نیاز باشد.
فوکوس ضعیف تصویر می تواند بر دقت تشخیص متن تأثیر بگذارد. اگر نتایج قابل قبولی دریافت نکردید، از کاربر بخواهید که تصویر را دوباره بگیرد.
اگر متن را در یک برنامه بلادرنگ تشخیص می دهید، باید ابعاد کلی تصاویر ورودی را در نظر بگیرید. تصاویر کوچکتر را می توان سریعتر پردازش کرد. برای کاهش تأخیر، اطمینان حاصل کنید که متن تا آنجا که ممکن است از تصویر را اشغال می کند و تصاویر را با وضوح پایین تر ثبت کنید (با در نظر گرفتن الزامات دقت ذکر شده در بالا). برای اطلاعات بیشتر، نکاتی برای بهبود عملکرد را ببینید.
نکاتی برای بهبود عملکرد
- برای پردازش فریمهای ویدئویی، از API همگام
results(in:)
آشکارساز استفاده کنید. این روش را ازAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
کنید تا به طور همزمان نتایج را از فریم ویدیوی داده شده دریافت کنید.AVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
را برای کاهش تماسهای آشکارسازtrue
نگه دارید. اگر یک قاب ویدیویی جدید در حالی که آشکارساز در حال کار است در دسترس باشد، حذف خواهد شد. - اگر از خروجی آشکارساز برای همپوشانی گرافیک روی تصویر ورودی استفاده میکنید، ابتدا نتیجه را از کیت ML دریافت کنید، سپس تصویر را در یک مرحله رندر و همپوشانی کنید. با انجام این کار، برای هر فریم ورودی پردازش شده فقط یک بار به سطح نمایشگر رندر می دهید. به عنوان مثال به updatePreviewOverlayViewWithLastFrame در نمونه راه اندازی سریع ML Kit مراجعه کنید.
- گرفتن تصاویر با وضوح کمتر را در نظر بگیرید. با این حال، الزامات ابعاد تصویر این API را نیز در نظر داشته باشید.