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

iOS Vision框架矩形检测结果不准确 识别框与真实矩形不匹配求助

问题修复方案

核心问题1:矩形检测参数配置错误

当前设置的宽高比检测范围为1.3~1.6,是适配长方形信用卡检测的参数,和你需要检测的正方形特征不匹配,导致Vision框架主动过滤了正方形的检测结果,返回符合设置宽高比的错误结果。

核心问题2:坐标转换未适配预览层缩放规则

预览层videoGravity设置为.resizeAspectFill后,相机原始帧比例和屏幕预览比例不一致,直接用预览层宽高做坐标缩放会导致绘制的框出现尺寸、位置偏差。

核心问题3:图像检测未传入正确方向参数

初始化VNImageRequestHandler时未指定图像方向,Vision框架基于默认方向检测也会导致坐标结果偏差。


修改后的代码

1. 调整矩形检测参数与图像方向配置

private func detectRectangle(in image: CVPixelBuffer) {
    let request = VNDetectRectanglesRequest(completionHandler: { (request: VNRequest, error: Error?) in
        DispatchQueue.main.async {
            guard let results = request.results as? [VNRectangleObservation], let rect = results.first else { 
                self.maskLayer.removeFromSuperlayer()
                return 
            }
            self.drawBoundingBox(rect: rect, image: image)
        }
    })
    // 适配正方形检测,宽高比范围调整为0.9~1.1,可根据实际需求调整容差
    request.minimumAspectRatio = VNAspectRatio(0.9)
    request.maximumAspectRatio = VNAspectRatio(1.1)
    request.minimumSize = Float(0.5)
    request.maximumObservations = 1
    // 传入和相机输出匹配的图像方向参数
    let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: image, orientation: .right, options: [:])
    try? imageRequestHandler.perform([request])
}

2. 调整坐标转换逻辑适配预览层缩放

func drawBoundingBox(rect : VNRectangleObservation, image: CVPixelBuffer) {
    // 计算原始图像和预览层的缩放比例与偏移量
    let imageSize = CVImageBufferGetEncodedSize(image)
    let previewSize = previewLayer.bounds.size
    let imageAspect = imageSize.width / imageSize.height
    let previewAspect = previewSize.width / previewSize.height
    
    var scale: CGFloat
    var xOffset: CGFloat = 0
    var yOffset: CGFloat = 0
    
    if imageAspect > previewAspect {
        scale = previewSize.height / imageSize.height
        xOffset = (previewSize.width - imageSize.width * scale) / 2
    } else {
        scale = previewSize.width / imageSize.width
        yOffset = (previewSize.height - imageSize.height * scale) / 2
    }
    
    // 修正坐标转换逻辑
    let transform = CGAffineTransform(scaleX: scale, y: -scale)
        .translatedBy(x: xOffset/scale, y: -(previewSize.height/scale + yOffset/scale))
    
    let path = UIBezierPath()
    path.move(to: rect.bottomLeft)
    path.addLine(to: rect.bottomRight)
    path.addLine(to: rect.topRight)
    path.addLine(to: rect.topLeft)
    path.close()
    path.apply(transform)
    
    maskLayer.removeFromSuperlayer()
    maskLayer = CAShapeLayer()
    maskLayer.fillColor = UIColor.clear.cgColor
    maskLayer.lineWidth = 5
    maskLayer.strokeColor = UIColor.red.cgColor
    maskLayer.path = path.cgPath
    
    previewLayer.insertSublayer(maskLayer, at: 1)
}

内容的提问来源于stack exchange,提问作者sergii.tsyban

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:24:05