Muy buenas, les saluda Miguel y aquí les traigo este nuevo tutorial.
Índice
Extraiga características destacadas utilizando el marco Visión actualizado
Apple introdujo muchas funciones nuevas en Vision Framework durante WWDC 2019. Además de proporcionar modelos de clasificación de imágenes incorporados para identificar animales de compañía y traer mejoras en el seguimiento de características faciales, una de las características que se destacó fue la relevancia.
La relevancia tiene muchas aplicaciones en la visión por computadora y el procesamiento de imágenes. Desde resaltar áreas de interés hasta la detección de desenfoque, detección de anomalías, recorte automático de imágenes y posprocesamiento de imágenes, la lista podría continuar.
¿Qué es la prominencia?
En términos simples, la prominencia implica las características más notables o importantes. La prominencia se divide en gran medida en dos tipos:
Prominencia basada en la atención : este algoritmo proporciona características de la imagen que captan el ojo humano a primera vista. El modelo para este algoritmo se entrenó en función de dónde miraban las personas en la imagen cuando se les mostraba un lote de imágenes.
Prominencia basada en el objeto : se entrenó en la segmentación de objetos para resaltar los objetos prominentes presentes en la imagen.
La prominencia basada en la atención es la más complicada, ya que se basa en una serie de cosas, como caras, contraste e iluminación en la imagen, para determinar las partes que llaman la atención.
Cada uno de estos tipos de prominencia devuelve un mapa de calor que es esencialmente búferes de 68×68 píxeles que contienen el valor de prominencia para cada región de la imagen.
Nuestra meta
Desarrollaremos una aplicación para iOS que recorta automáticamente una imagen para mostrar solo las regiones destacadas. Usaremos ambos tipos de prominencia y compararemos los resultados.
Implementación
Para simplificar las cosas, la interfaz de usuario consta de una imagen y un botón, ambos creados mediante programación en nuestro ViewController. El selector de botón es responsable de seleccionar las imágenes usando ImagePickerController como se muestra a continuación:
@objc func onButtonClick(sender: UIButton){ let imagePicker = UIImagePickerController() imagePicker.sourceType = .photoLibrary imagePicker.delegate = self present(imagePicker, animated: true, completion: nil) }
Para que esto funcione según lo previsto, asegúrese de haber implementado los protocolos UIImagePickerControllerDelegate
, UINavigationControllerDelegate
y también agregado los permisos de uso de privacidad para la biblioteca de fotos en su archivo info.plist
.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { dismiss(animated: true) { if let image = info [UIImagePickerController.InfoKey.originalImage] as? UIImage { self.imageView?.image = image self.processImage(image) } } }
Dentro de la processImage
función, nuestra API de visión maneja la solicitud de relevancia. Veremos eso en la siguiente sección.
Configuración de nuestra solicitud de visión
Usaremos el estándar VNImageRequestHandler
para manejar nuestra imagen y pasar el tipo de algoritmo en el controlador de solicitud de visión, como se muestra a continuación:
let requestHandler = VNImageRequestHandler(cgImage: originalImage, options: [:]) let saliencyRequest = VNGenerateAttentionBasedSaliencyImageRequest(completionHandler: nil) try requestHandler.perform([self.saliencyRequest]) guard let results = self.saliencyRequest.results?.first else{return} let observations = results as? VNSaliencyImageObservation let salientObjects = observation.salientObjects
Hay algunos términos bastante nuevos en el código anterior. Veamos cuáles son:
- La
salientObjects
propiedad es una matriz deVNRectangleObservation
todas las características destacadas detectadas por el algoritmo. Mantiene elboundingBox
para cada una de las características y los umbrales de confianza. Para recortar la imagen para mostrar solo las características destacadas, fusionaremos todas las regiones de cuadros delimitadores destacados. - Los cuadros delimitadores devueltos por el marco de visión utilizan un sistema de coordenadas normalizado de modo que el punto inferior izquierdo es el origen. Por lo tanto, pasaremos la unión de los cuadros delimitadores a a
VNImageRectForNormalizedRect
para proyectar la región saliente en el sistema de coordenadas UIKit. - En los casos en que la imagen no tiene resaltados, los
salientObjects
devueltos están vacíos.
El siguiente código contiene la implementación completa de la solicitud de visión que recorta la imagen según las características destacadas:
private let workQueue = DispatchQueue(label: "VisionRequest", qos: .userInitiated, attributes: [], autoreleaseFrequency: .workItem) private func processImage(_ image: UIImage) { guard let originalImage = image.cgImage else { return } workQueue.async { let requestHandler = VNImageRequestHandler(cgImage: originalImage, options: [:]) do { try requestHandler.perform([self.saliencyRequest]) guard let results = self.saliencyRequest.results?.first else{return} if let observation = results as? VNSaliencyImageObservation { var unionOfSalientRegions = CGRect(x: 0, y: 0, width: 0, height: 0) let salientObjects = observation.salientObjects let showAlert = (salientObjects?.isEmpty ?? false) for salientObject in salientObjects ?? [] { unionOfSalientRegions = unionOfSalientRegions.union(salientObject.boundingBox) } if let ciimage = CIImage(image: image) { let salientRect = VNImageRectForNormalizedRect(unionOfSalientRegions, Int(ciimage.extent.size.width), Int(ciimage.extent.size.height)) let croppedImage = ciimage.cropped(to: salientRect) let thumbnail = UIImage(ciImage:croppedImage) DispatchQueue.main.async { if showAlert{ let alertController = UIAlertController(title: "Oops!", message: "No highlights were found", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Dismiss", style: . default, handler: { _ in })) self.present(alertController, animated: false, completion: nil) } self.imageView?.image = thumbnail } } } } catch { print(error) } } }
Los tipos de prominencia basados en la atención devuelven solo un cuadro delimitador, mientras que el algoritmo basado en la objetividad puede devolver hasta tres cuadros delimitadores.
El resultado de la aplicación en acción se muestra a continuación:
Ahora comparemos los tipos basados en la objetividad y la atención en una imagen de paisaje como se muestra a continuación:
El algoritmo basado en la atención no tiene mucho impacto en las imágenes de paisajes. Puede utilizar cualquiera de los tipos de solicitud de relevancia según los casos de uso. Para mostrar la parte de interés en las miniaturas, generalmente se usa la prominencia basada en la atención.
Conclusión
Hemos examinado detenidamente la característica sobresaliente de la visión y hemos comparado los tipos basados en la atención y los basados en la objetividad. El marco de visión tiene muchos más avances este año, como la similitud de imágenes, la calidad de captura de caras, etc., ¡más sobre ellos pronto! El código fuente completo del ejemplo anterior está disponible en el repositorio de Github .
Eso es todo por hoy. Espero que hayas disfrutado leyendo.
Añadir comentario