Я хочу сканировать документы и исправлять любые проблемы с перспективой телефона, как это делает приложение заметок.Все нормально, пока я не захочу использовать CIFilter(name: "CIPerspectiveCorrection")
, затем я испорчу изображение, и я пытаюсь понять, где я иду не так.
Я попытался переключить параметры и другие фильтры или повернутьизображение, но это не сработало для меня.
Вот небольшой проект, который я настроил для проверки всего этого: https://github.com/iViktor/scanner
В основном я запускаю VNDetectRectanglesRequest
на AVCaptureSession
и сохраняя прямоугольник, который я получаю private var targetRectangle = VNRectangleObservation()
Этот я использую, чтобы пересчитать точки внутри изображения и запустить фильтр на изображении.
extension DocumentScannerViewController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
guard let imageData = photo.fileDataRepresentation()
else { return }
guard let ciImage = CIImage(data: imageData, options: [.applyOrientationProperty : true]) else { return }
let image = UIImage(ciImage: ciImage)
let imageTopLeft: CGPoint = CGPoint(x: image.size.width * targetRectangle.bottomLeft.x, y: targetRectangle.bottomLeft.y * image.size.height)
let imageTopRight: CGPoint = CGPoint(x: image.size.width * targetRectangle.bottomRight.x, y: targetRectangle.bottomRight.y * image.size.height)
let imageBottomLeft: CGPoint = CGPoint(x: image.size.width * targetRectangle.topLeft.x, y: targetRectangle.topLeft.y * image.size.height)
let imageBottomRight: CGPoint = CGPoint(x: image.size.width * targetRectangle.topRight.x, y: targetRectangle.topRight.y * image.size.height)
let flattenedImage = image.flattenImage(topLeft: imageTopLeft, topRight: imageTopRight, bottomLeft: imageBottomLeft, bottomRight: imageBottomRight)
let finalImage = UIImage(ciImage: flattenedImage, scale: image.scale, orientation: image.imageOrientation)
//performSegue(withIdentifier: "showPhoto", sender: image)
//performSegue(withIdentifier: "showPhoto", sender: UIImage(ciImage: flattenedImage))
performSegue(withIdentifier: "showPhoto", sender: finalImage)
}
}
Этокод, который не работает, и я борюсь с:
extension UIImage {
func flattenImage(topLeft: CGPoint, topRight: CGPoint, bottomLeft: CGPoint, bottomRight: CGPoint) -> CIImage {
let docImage = self.ciImage!
let rect = CGRect(origin: CGPoint.zero, size: self.size)
let perspectiveCorrection = CIFilter(name: "CIPerspectiveCorrection")!
perspectiveCorrection.setValue(CIVector(cgPoint: self.cartesianForPoint(point: topLeft, extent: rect)), forKey: "inputTopLeft")
perspectiveCorrection.setValue(CIVector(cgPoint: self.cartesianForPoint(point: topRight, extent: rect)), forKey: "inputTopRight")
perspectiveCorrection.setValue(CIVector(cgPoint: self.cartesianForPoint(point: bottomLeft, extent: rect)), forKey: "inputBottomLeft")
perspectiveCorrection.setValue(CIVector(cgPoint: self.cartesianForPoint(point: bottomRight, extent: rect)), forKey: "inputBottomRight")
perspectiveCorrection.setValue(docImage, forKey: kCIInputImageKey)
return perspectiveCorrection.outputImage!
}
func cartesianForPoint(point:CGPoint,extent:CGRect) -> CGPoint {
return CGPoint(x: point.x,y: extent.height - point.y)
}
}
Итак, в конце я хочу отсканировать документ, например счет, и автоматически исправить любую ошибку пользователя, например, проблемы с перспективой.Прямо сейчас фильтр, который я добавляю к изображению, приводит к странному эффекту, похожему на веер.