Sunday, December 15, 2024
HomeiOS Developmentios - Enhance imaginative and prescient OCR outcomes?

ios – Enhance imaginative and prescient OCR outcomes?


I’m merely attempting to scan bank card info by way of imaginative and prescient and am having combined outcomes. Non-embossed playing cards (which appear extra frequent these days) have probably the most points. I really feel like it could be having troubles with there being restricted distinction between the letters and backgrounds (silver card, white textual content). Ive tried up to now to attempt altering the picture to grayscale earlier than scanning, in addition to growing distinction and sharpness however that made outcomes worse the place it couldn’t acknowledge any textual content. What am i able to do to enhance my code to yield higher outcomes?

    // MARK: Credit score Card Picture Recognition
    open func detectRectangle(in picture: CVPixelBuffer) {
        let request = VNDetectRectanglesRequest(completionHandler: { (request, error) in
            DispatchQueue.principal.async {
                guard let outcomes = request.outcomes as? [VNRectangleObservation], let outcome = outcomes.first else { return }
                self.doPerspectiveCorrection(outcome, from: picture)
            }
        })
        
        request.minimumAspectRatio = VNAspectRatio(1.3)
        request.maximumAspectRatio = VNAspectRatio(1.3)
        request.minimumSize = Float(0.5)
        request.maximumObservations = 1
        
        
        let imageHandler = VNImageRequestHandler(cvPixelBuffer: picture, choices: [:])
        attempt? imageHandler.carry out([request])
    }
    
    open func doPerspectiveCorrection(_ commentary: VNRectangleObservation, from buffer: CVImageBuffer) {
        var ciImage = CIImage(cvImageBuffer: buffer)
        
        ciImage.cropped(to: holedOutRect)
        
        let topLeft = commentary.topLeft.scaled(to: ciImage.extent.measurement)
        let topRight = commentary.topRight.scaled(to: ciImage.extent.measurement)
        let bottomLeft = commentary.bottomLeft.scaled(to: ciImage.extent.measurement)
        let bottomRight = commentary.bottomRight.scaled(to: ciImage.extent.measurement)
        
        ciImage = ciImage.applyingFilter("CIPerspectiveCorrection", parameters: [
            "inputTopLeft": CIVector(cgPoint: topLeft),
            "inputTopRight": CIVector(cgPoint: topRight),
            "inputBottomLeft": CIVector(cgPoint: bottomLeft),
            "inputBottomRight": CIVector(cgPoint: bottomRight),
        ])
        
        let context = CIContext()
        let cgImage = context.createCGImage(ciImage, from: ciImage.extent)
        let output = UIImage(cgImage: cgImage!)
        
        recognizeTextInImage(output)
    }
    
    open func recognizeTextInImage(_ picture: UIImage) {
        guard let cgImage = picture.cgImage else { return }
        
        textRecognitionWorkQueue.async {
            guard !self.captured else { return }
            let requestHandler = VNImageRequestHandler(cgImage: cgImage, choices: [:])
            do {
                guard let textRecognitionRequest = self.textRecognitionRequest else { return }
                attempt requestHandler.carry out([textRecognitionRequest])
            } catch {
                print(error)
            }
        }
    }
    
    open func setupVision() {
        textRecognitionRequest = VNRecognizeTextRequest { (request, error) in
            guard !self.captured, let observations = request.outcomes as? [VNRecognizedTextObservation] else { return }
            
            let creditCard = CardModel()
            
            for commentary in observations {
                guard let topCandidate = commentary.topCandidates(1).first, topCandidate.confidence > 0.25 else { return }
                
                let topCandidateString = topCandidate.string
                
                if topCandidateString.isName {
                    creditCard.identify = topCandidateString
                }

                if topCandidateString.isCardNumber {
                    creditCard.quantity = topCandidateString.onlyDigits
                }
                
                if topCandidateString.isExpirationDate {
                    creditCard.month = topCandidateString.expirationMonth
                    creditCard.yr = topCandidateString.expirationYear
                }
            }
            
            DispatchQueue.principal.async {
                guard let _ = creditCard.quantity else { return }
                // Bank card quantity have been discovered, cease the digicam seize session
                self.hapticScanSuccessResponse()
                self.showScannedCardDetails(identify: creditCard.identify, cardNumber: creditCard.quantity, expiryMonth: creditCard.month, expiryYear: creditCard.yr)

                DispatchQueue.principal.asyncAfter(deadline: .now() + 1, execute: {
                    // Ship it again to the calling protocol/delegate
                    guard !self.captured else { return }
                    self.captured = true
                    self.captureSession.stopRunning()

                    if self.embeddedAsView {
                        self.delegate?.didFinishScanningCreditCard?(cardModel: creditCard)
                        self.onDismissal?(creditCard)
                    } else {
                        self.dismiss(animated: true) {
                            self.delegate?.didFinishScanningCreditCard?(cardModel: creditCard)
                        }
                    }

                })
            }
        }
        
        textRecognitionRequest?.recognitionLevel = .correct
    }
}

// MARK: AVCaptureVideoDataOutputSampleBufferDelegate
extension PaymentScannerViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
    
    // AVCaptureVideoDataOutputSampleBufferDelegate -
    open func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
            return
        }
        
        let ciImage = CIImage(cvPixelBuffer: imageBuffer)
        guard let picture = ciImage.convertToUIImage() else { return }
        
        imageCounter += 1
        
        // Reduces the quantity of pictures processed to each twenty fifth picture with the intention to not attain max cpu utilization
        guard !captured && imageCounter.isMultiple(of: 25) else { return }
        detectRectangle(in: imageBuffer)
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments