Detect barcode rotation via AVCaptureMetadataOutput or Vision

35 views Asked by At

I have these two barcodes:

enter image description here

enter image description here

That contains the same number: 01069327.
The only difference is that the second one, is flipped horizontally.

I need to recognize the flip because for my scope, the products are differents.


I've tried using both Vision or AVFoundation without results.
Vision and AVFoundation seems not have this information or something that help me to retrieve.

Using AVFoundation:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {

    if let metadataObject = metadataObjects.first {
        guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
        guard let stringValue = readableObject.stringValue else { return }
        
        let topLeft = readableObject.corners[0]
        let topRight = readableObject.corners[1]
        let bottomRight = readableObject.corners[2]
        let bottomLeft = readableObject.corners[3]

        let diffXRight = topRight.x - bottomRight.x
        let diffXLeft = topLeft.x - bottomLeft.x
        let flipThresholdX: CGFloat = 0.01
        let isFlippedHorizontally = abs(diffXRight) > flipThresholdX || abs(diffXLeft) > flipThresholdX

        print("BARCODE: \(stringValue), flipped: \(isFlippedHorizontally ? 0 : 1)\n\n")
        self.parent.didFindCode(stringValue, isFlippedHorizontally ? 0 : 1)
    }

}

Using Vision (and another formula):

private func createRequest() -> VNDetectBarcodesRequest {
    let request = VNDetectBarcodesRequest { request, error in
        [...]
        if let stringValue = observation.payloadStringValue {
            let topLeft = observation.topLeft
            let topRight = observation.topRight
            let bottomLeft = observation.bottomLeft
            
            let angle = atan2(topRight.y - topLeft.y, topRight.x - topLeft.x) * 180.0 / .pi
            let rotationThreshold: Float = 180.0
            let isFlippedHorizontally = angle > rotationThreshold || angle < -rotationThreshold
            
            print("BARCODE: \(stringValue), flipped: \(isFlippedHorizontally ? 0 : 1)")
            self.parent.didFindCode(stringValue, isFlippedHorizontally ? 0 : 1)
        }
    }
    return request
}

Nothing relevant. Always get "1".


Seems to be a valid and retrievable information. That site, https://online-barcode-reader.inliteresearch.com as you can see from the screenshots, detect the correct "Rotation":

enter image description here
enter image description here


There is a way to retrieve or to extract this information?
Also using external (but free) libraries is ok.

0

There are 0 answers