Skip to content

Latest commit

 

History

History
84 lines (62 loc) · 3.04 KB

readme.md

File metadata and controls

84 lines (62 loc) · 3.04 KB

Deep Learning para BiciMAD. App para iOS

Swift 4.1 Xcode macOS

Ya tengo el modelo entrenado y lo único que queda es usarlo en una app para iOS y comprobar que funciona tal y como se espera.

Entorno

Para compilar el proyecto necesitas Xcode en su versión 9.3, y para llevar a cabo las pruebas debes tener un iPhone con iOS actualizado a la versión 11.0

Estructura del proyecto

He organizado el código en dos targets.

  1. El principal donde está el interfaz de usuario y la llamada a CoreML y Vision
  2. Un framework llamado IncidenceKit que tiene el modelo importado de Keras y se encarga de la clasificación de las imágenes y otras cosas

Todo lo relacionado con CoreML y el modelo está programado en dos archivos

  1. CaptureViewController (target principal)
  2. Visionary (framework IncidenceKit)

Este es el código donde capturo un número del identificador y los transformo para crear una imagen como las que espera el modelo.

// El rectángulo del número
let box_rect = box.boundingBox.scaled(to: ciBikeImage.extent.size)

// Calculamos los vértices del rectangulo...
let topLeft = box.topLeft.scaled(to: imageSize)
let topRight = box.topRight.scaled(to: imageSize)
let bottomLeft = box.bottomLeft.scaled(to: imageSize)
let bottomRight = box.bottomRight.scaled(to: imageSize)

// ...y cortamos la imagen, la ponemos en blanco y negro
// y por último invertimos los colores. De esta manera
// la nueva imagen es como las del modelo de predicción 
let correctedImage = ciBikeImage
    .cropped(to: box_rect)
    .applyingFilter("CIColorInvert")
    .applyingFilter("CIPerspectiveCorrection", parameters: [
        "inputTopLeft": CIVector(cgPoint: topLeft),
        "inputTopRight": CIVector(cgPoint: topRight),
        "inputBottomLeft": CIVector(cgPoint: bottomLeft),
        "inputBottomRight": CIVector(cgPoint: bottomRight)
    ])
    .applyingFilter("CIColorControls", parameters: [
        kCIInputSaturationKey: 0,
        kCIInputContrastKey: 32
    ])
             

Y aquí es donde le paso la imagen el modelo para que me de el resultado de su clasificación

public func prediction(image: CIImage) -> Int?
{
	guard let buffer = self.pixelBuffer(from: image),
		  let output = try? self.model.prediction(image: buffer)
	else
	{
		return nil
	}

	let digit = output.numero.enumerated()
		.filter({ $0.element.value > 0.90 && $0.element.value <= 1.0 })
		.map({ $0.element })
		.sorted(by: { $0.value < $1.value })
		.first

	if let digit = digit, let number = Int(digit.key)
	{
		return number
	}

	return nil
}

Contacto

Si tienes alguna duda o comentario que me quieras hacer lo mejor es que me busques en twitter, allí me encuentras en @fitomad