Я пытаюсь использовать VNDetectRectangleRequest
из Apple Vision framework для автоматического получения изображения карты. Однако, когда я конвертирую точки для рисования прямоугольника, он деформирован и не следует за прямоугольником, как должен. Я читал эту статью довольно близко
Одно из основных отличий заключается в том, что я встраиваю свой CameraCaptureVC в другой ViewController, так что карта будет сканироваться только тогда, когда она находится в этом меньшем окне.
Ниже показано, как я настроил камеру vc в родительском vc (вызываемом из viewDidLoad).
func configureSubviews() {
clearView.addSubview(cameraVC.view)
cameraVC.view.autoPinEdgesToSuperviewEdges()
self.addChild(cameraVC)
cameraVC.didMove(toParent: self)
}
Ниже приведен код для рисования прямоугольника.
func createLayer(in rect: CGRect) {
let maskLayer = CAShapeLayer()
maskLayer.frame = rect
maskLayer.cornerRadius = 10
maskLayer.opacity = 0.75
maskLayer.borderColor = UIColor.red.cgColor
maskLayer.borderWidth = 5.0
previewLayer.insertSublayer(maskLayer, at: 1)
}
func removeMask() {
if let sublayer = previewLayer.sublayers?.first(where: { $0 as? CAShapeLayer != nil }) {
sublayer.removeFromSuperlayer()
}
}
func drawBoundingBox(rect : VNRectangleObservation) {
let transform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -finalFrame.height)
let scale = CGAffineTransform.identity.scaledBy(x: finalFrame.width, y: finalFrame.height)
let bounds = rect.boundingBox.applying(scale).applying(transform)
createLayer(in: bounds)
}
func detectRectangle(in image: CVPixelBuffer) {
let request = VNDetectRectanglesRequest { (request: VNRequest, error: Error?) in
DispatchQueue.main.async {
guard let results = request.results as? [VNRectangleObservation],
let rect = results.first else { return }
self.removeMask()
self.drawBoundingBox(rect: rect)
}
}
request.minimumAspectRatio = 0.0
request.maximumAspectRatio = 1.0
request.maximumObservations = 0
let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: image, options: [:])
try? imageRequestHandler.perform([request])
}
Это мой результат. Красный прямоугольник должен следовать за границами карты, но он слишком короткий, а начало координат даже не находится в верхней части карты.
Я пробовал изменить значения в функции drawBoundingBox
, но, похоже, ничего не помогает. Я также попытался преобразовать границы другим способом, как показано ниже, но это тот же результат, и изменение этих значений становится хакерским.
let scaledHeight: CGFloat = originalFrame.width / finalFrame.width * finalFrame.height
let boundingBox = rect.boundingBox
let x = finalFrame.width * boundingBox.origin.x
let height = scaledHeight * boundingBox.height
let y = scaledHeight * (1 - boundingBox.origin.y) - height
let width = finalFrame.width * boundingBox.width
let bounds = CGRect(x: x, y: y, width: width, height: height)
createLayer(in: bounds)
Был бы признателен за любую помощь. Может быть, поскольку я встраиваю его как дочерний VC, мне нужно преобразовать координаты во второй раз? Я пробовал что-то подобное безрезультатно, но, возможно, я сделал что-то не так или что-то упустил