Когда происходит сбой приложения для захвата в реальном времени, выявляйте текст при получении изображения с помощью обратного вызова AVCaptureDataSampleBufferDelegate
.Получите изображение, перезвоните от отправленного API Google vision Я использовал этот код Кто-нибудь работал?Мой код
import UIKit
import FirebaseMLVision
import FirebaseMLModelInterpreter
import AVKit
protocol ImageDelegate: class {
func getImage(imageOutFrame: String)
}
var photoOutput: AVCaptureVideoDataOutput!
var videoDataOutputQueue: DispatchQueue!
var previewLayer:AVCaptureVideoPreviewLayer!
var captureDevice : AVCaptureDevice!
var captureSession = AVCaptureSession()
var context = CIContext()
weak var delegate: ImageDelegate?
var vision = Vision.vision()
var textRecognizer = vision.onDeviceTextRecognizer()
extension UIViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
// To set the camera and its position to capture
func setUpAVCapture(capturePreview: UIView) {
captureSession.sessionPreset = AVCaptureSession.Preset.vga640x480
guard let device = AVCaptureDevice
.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera,
for: .video,
position: AVCaptureDevice.Position.back) else {
return
}
captureDevice = device
captureDevice.isFocusModeSupported(.continuousAutoFocus)
try! captureDevice.lockForConfiguration()
captureDevice.focusMode = .continuousAutoFocus
captureDevice.unlockForConfiguration()
beginSession(capturePreview: capturePreview)
}
// Function to setup the beginning of the capture session
func beginSession(capturePreview : UIView){
var deviceInput: AVCaptureDeviceInput!
do {
deviceInput = try AVCaptureDeviceInput(device: captureDevice)
guard deviceInput != nil else {
print("error: cant get deviceInput")
return
}
if captureSession.canAddInput(deviceInput){
captureSession.addInput(deviceInput)
}
photoOutput = AVCaptureVideoDataOutput()
photoOutput.alwaysDiscardsLateVideoFrames=true
videoDataOutputQueue = DispatchQueue(label: "VideoDataOutputQueue")
photoOutput.setSampleBufferDelegate(self, queue: videoDataOutputQueue)
if captureSession.canAddOutput(photoOutput){
captureSession.addOutput(photoOutput)
}
photoOutput.connection(with: .video)?.isEnabled = true
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
let rootLayer :CALayer = capturePreview.layer
rootLayer.masksToBounds=true
rootLayer.addSublayer(previewLayer)
captureDevice.configureDesiredFrameRate(0)
captureSession.startRunning()
} catch let error as NSError {
deviceInput = nil
exit(0)
print("error: \(error.localizedDescription)")
}
}
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
connection.videoOrientation = AVCaptureVideoOrientation.portrait
DispatchQueue.global(qos: .userInteractive).async {
guard let imag = self.imageFromSampleBuffer(sampleBuffer : sampleBuffer) else { return }
let image = VisionImage(image: imag)
textRecognizer.process(image) { result, error in
guard error == nil, let result = result else {
return
}
let resultText = result.text
let matched = self.matches(for: RegEx.wholeRegex , in: resultText)
let m = matched.joined(separator: "")
print(m)
delegate?.getImage(imageOutFrame: m)
}
}
}
func imageFromSampleBuffer(sampleBuffer : CMSampleBuffer) -> UIImage? {
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil }
let ciImage = CIImage(cvPixelBuffer: imageBuffer)
guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else { return nil }
let img = UIImage(cgImage: cgImage)
let n = img.fixedOrientation()
return n
}
func stopCamera(){
captureSession.stopRunning()
captureDevice = nil
}
}
extension AVCaptureDevice {
/// http://stackoverflow.com/questions/21612191/set-a-custom-avframeraterange-for-an-avcapturesession#27566730
func configureDesiredFrameRate(_ desiredFrameRate: Int) {
var isFPSSupported = false
do {
if let videoSupportedFrameRateRanges = activeFormat.videoSupportedFrameRateRanges as? [AVFrameRateRange] {
for range in videoSupportedFrameRateRanges {
if (range.maxFrameRate >= Double(desiredFrameRate) && range.minFrameRate <= Double(desiredFrameRate)) {
isFPSSupported = true
break
}
}
}
if isFPSSupported {
try lockForConfiguration()
activeVideoMaxFrameDuration = CMTimeMake(value: 1, timescale: Int32(desiredFrameRate))
activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: Int32(desiredFrameRate))
unlockForConfiguration()
}
} catch {
print("lockForConfiguration error: \(error.localizedDescription)")
}
}
}
get let r esultText = result.text
получить только значение Доллера, например, в режиме реального времени захвата
xcsrf $ 16.54245 ssxvcxv
Я получил выводдля
$ 16,54245
Моя проблема в том, что приложение медленно распознает текст.
- 1) Я установил частоту кадров, но не работает
- 2) Я использовал Dispatch, но не работает.
получить кадры -> преобразовать в изображение, преобразовать в изображение -> отправить google
API распознавания текста, обнаруживающий текст -> преобразовать для получения единственного точного результата
> Пожалуйста, поделитесь своим кодом, чтобы ценить Спасибо.