Saltar al contenido

Implementar la clasificación de imágenes mediante el modelo capacitado ML Core y el marco de visión

Para clasificar una imagen, puede utilizar el Video marco para preparar la imagen para la clasificación.

Importe el marco de Vision colocando la declaración de importación justo debajo del UIKit importar por encima de la declaración de clase:


import Vision

Usarás algo llamado VNCoreMLRequest que utilizará un ejemplo del modelo Core ML para la clasificación de imágenes.

Aplicar el siguiente código debajo del viewDidLoad(:), lea los comentarios en línea con atención:


lazy var classificationRequest: VNCoreMLRequest = { do { // Instantiate the Core ML model let model = try VNCoreMLModel(for: ProductImageClassifier_1(configuration: MLModelConfiguration()).model) // Create a VNCoreMLRequest passing in the model and starting the classification process in the completionHandler. let request = VNCoreMLRequest(model: model, completionHandler: { [weak self] request, error in self?.processClassifications(for: request, error: error) }) // Crop and scale the image request.imageCropAndScaleOption = .centerCrop return request } catch { fatalError("Failed to load Vision ML model: (error)") } }()

Entonces desea aplicar un método para cumplir con las solicitudes.

Agrega un método llamado updateClassifications(for:):


/// - Tag: PerformRequests func updateClassifications(for image: UIImage) { // show the loading indicator self.showFioriLoadingIndicator("Finding similar products...") // make sure the orientation of the image is passed in the CGImagePropertyOrientation to set the orientation of the image let orientation = CGImagePropertyOrientation(image.imageOrientation) // Create a CIImage as needed by the model for classification. If that fails throw a fatalError. guard let ciImage = CIImage(image: image) else { fatalError("Unable to create (CIImage.self) from (image).") } // Dispatch to the Global queue to asynchronously perform the classification request. DispatchQueue.global(qos: .userInitiated).async { let handler = VNImageRequestHandler(ciImage: ciImage, orientation: orientation) do { try handler.perform([self.classificationRequest]) } catch { /* This handler catches general image processing errors. The `classificationRequest`'s completion handler `processClassifications(_:error:)` catches errors specific to processing that request. */ print("Failed to perform classification.n(error.localizedDescription)") } } }

En este momento, el código anterior sumará errores de tiempo. Necesitas una extensión CGImagePropertyOrientation para orientación UIImage hacia CGImagePropertyOrientation.

Crea una nueva clase Swift con el nombre CGImagePropertyOrientation+UIImageOrientation sa Navegador de proyectos.

Crear clase veloz

En esa clase de extensión, reemplace el código con las siguientes líneas:


import UIKit import ImageIO extension CGImagePropertyOrientation { init(_ orientation: UIImage.Orientation) { switch orientation { case .up: self = .up case .upMirrored: self = .upMirrored case .down: self = .down case .downMirrored: self = .downMirrored case .left: self = .left case .leftMirrored: self = .leftMirrored case .right: self = .right case .rightMirrored: self = .rightMirrored @unknown default: fatalError() } } }

Vuelve al ProductClassificationTableViewController.swift clasificación y aplicación de un método que procesa la clasificación de la imagen. Este método obtendrá los productos de acuerdo con el resultado de la clasificación.

Aplicar el siguiente método directamente debajo updateClassifications(for:) y lea los comentarios en línea con atención:


/// - Tag: ProcessClassifications func processClassifications(for request: VNRequest, error: Error?) { // Use the main dispatch queue DispatchQueue.main.async { // Check if the results are nil and display the error in an Alert Dialogue guard let results = request.results else { self.logger.error("Unable to classify image.", error: error) AlertHelper.displayAlert(with: "Unable to classify image.", error: error, viewController: self) return } // The `results` will always be `VNClassificationObservation`s, as specified by the Core ML model in this project. let classifications = results as! [VNClassificationObservation] if classifications.isEmpty { AlertHelper.displayAlert(with: "Couldn't recognize the image", error: nil, viewController: self) } else { // Retrieve top classifications ranked by confidence. let topClassifications = classifications.prefix(2) let categoryNames = topClassifications.map { classification in return String(classification.identifier) } // Safe unwrap the first classification, because that will be the category with the highest confidence. guard let category = categoryNames.first else { AlertHelper.displayAlert(with: "Unable to identify product category", error: nil, viewController: self) self.logger.error("Something went wrong. Please check the classification code.") return } // Set the Navigation Bar's title to the classified category self.navigationItem.title = category // Define a DataQuery to only fetch the products matching the classified product category let query = DataQuery().filter(Product.categoryName == category) // Fetch the products matching the defined query self.dataService?.fetchProducts(matching: query) { [weak self] result, error in if let error = error { AlertHelper.displayAlert(with: "Failed to load list of products!", error: error, viewController: self!) self?.logger.error("Failed to load list of products!", error: error) return } // Hide the loading indicator self?.hideFioriLoadingIndicator() self?.products = result! // You will display the product images as well, for that reason create a new array containing the picture urls. self?.productImageURLs = result!.map { $0.pictureUrl ?? "" } self?.tableView.reloadData() } } } }

Pon el productImageURLs propiedades debajo de las propiedades de la matriz de productos arriba en la clase:


private var productImageURLs = [String]()

El último paso sería llamar al updateClassifications(for:) método dentro del viewDidLoad(_:) método como la última línea de código:


override func viewDidLoad() { super.viewDidLoad() tableView.estimatedRowHeight = 80 tableView.rowHeight = UITableView.automaticDimension tableView.register(FUIObjectTableViewCell.self, forCellReuseIdentifier: FUIObjectTableViewCell.reuseIdentifier) updateClassifications(for: image) }

Eso es todo lo que tiene que hacer para clasificar una imagen con Vision y un modelo Core ML previamente entrenado.

Continúe con el tutorial para implementar la visualización de productos en la vista de tabla.

Hecho

Inicie sesión para responder la pregunta