You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过AVCaptureMetadataOutput或Vision检测条形码水平翻转?

问题

我有两个条形码,内容都是数字01069327,唯一区别是第二个条形码被水平翻转。出于业务需求,我需要识别出这种翻转状态。尝试用AVFoundation和Vision框架实现,但两种方案始终返回相同的状态值1,无法区分翻转状态。但在线条码识别工具能正确检测旋转状态,请问有没有方法获取翻转信息?也可以使用免费第三方库。

使用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)
    }

}

使用Vision的尝试代码

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
}
分析与解决方案

原代码问题分析

  • AVFoundation方案:框架会自动规整条码的角点顺序,无论条码是否翻转,corners数组的顺序都保持一致,通过左右边X差值无法判断真实翻转状态。
  • Vision方案:计算的顶部边角度逻辑错误,水平翻转后该角度仍在±0°左右,不会触发±180°的阈值判断。

可行解决方案

方案1:修正Vision框架的判断逻辑

Vision返回的条码顶点坐标是归一化的图像坐标(原点在左上角,X向右递增),水平翻转的条码会出现topLeft.x > topRight.x的特征,直接对比即可:

private func createRequest() -> VNDetectBarcodesRequest {
    let request = VNDetectBarcodesRequest { request, error in
        guard let observations = request.results as? [VNBarcodeObservation],
              let observation = observations.first,
              let stringValue = observation.payloadStringValue else { return }
        
        // 水平翻转时,左上角X坐标大于右上角X坐标
        let isFlippedHorizontally = observation.topLeft.x > observation.topRight.x
        
        print("BARCODE: \(stringValue), flipped: \(isFlippedHorizontally ? 0 : 1)")
        self.parent.didFindCode(stringValue, isFlippedHorizontally ? 0 : 1)
    }
    return request
}

方案2:使用免费第三方库ZBarSDK

ZBar会返回条码的方向信息,可直接区分水平翻转状态:

  1. 集成ZBarSDK到项目中
  2. 通过ZBarSymbol的orientation属性判断状态,ZBarOrientationLeft或ZBarOrientationRight对应水平翻转

示例代码片段:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    ZBarImage *zbarImage = [ZBarImage imageWithUIImage:image];
    ZBarScanner *scanner = [ZBarScanner new];
    ZBarSymbolSet *symbols = [scanner scanImage:zbarImage];
    
    for (ZBarSymbol *symbol in symbols) {
        NSString *code = symbol.data;
        BOOL isFlipped = (symbol.orientation == ZBarOrientationLeft || symbol.orientation == ZBarOrientationRight);
        NSLog(@"BARCODE: %@, flipped: %d", code, isFlipped ? 0 : 1);
    }
    [picker dismissViewControllerAnimated:YES completion:nil];
}

方案3:基于条码编码规则判断(特定场景)

如果是固定类型的条码(如EAN-13),可通过分析起始符/终止符的位置判断:

  • EAN-13的起始符为101,终止符也为101,但左右数据符编码规则不同
  • 水平翻转后,起始符会出现在条码右侧,可通过图像中黑白条的分布特征识别位置差异

此方法需深入了解条码编码规则,适合特定业务场景。

内容的提问来源于stack exchange,提问作者elp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:27:36