Después de entrenar tu propio modelo con AutoML Vision Edge , puedes usarlo en tu aplicación para etiquetar imágenes.
Hay dos formas de integrar modelos entrenados desde AutoML Vision Edge. Puedes agrupar el modelo copiando los archivos del modelo en tu proyecto Xcode, o puedes descargarlo dinámicamente desde Firebase.
Opciones de agrupación de modelos | |
---|---|
Incluido en su aplicación |
|
Alojado con Firebase |
|
Antes de que empieces
Incluya las bibliotecas del kit ML en su Podfile:
Para agrupar un modelo con su aplicación:
pod 'GoogleMLKit/ImageLabelingCustom'
Para descargar dinámicamente un modelo desde Firebase, agregue la dependencia
LinkFirebase
:pod 'GoogleMLKit/ImageLabelingCustom' pod 'GoogleMLKit/LinkFirebase'
Después de instalar o actualizar los Pods de su proyecto, abra su proyecto Xcode usando su
.xcworkspace
. ML Kit es compatible con Xcode versión 12.2 o superior.Si desea descargar un modelo , asegúrese de agregar Firebase a su proyecto de Android , si aún no lo ha hecho. Esto no es necesario cuando agrupa el modelo.
1. Cargue el modelo
Configurar una fuente de modelo local
Para agrupar el modelo con su aplicación:
Extraiga el modelo y sus metadatos del archivo zip que descargó de Firebase console en una carpeta:
your_model_directory |____dict.txt |____manifest.json |____model.tflite
Los tres archivos deben estar en la misma carpeta. Le recomendamos que utilice los archivos tal como los descargó, sin modificaciones (incluidos los nombres de los archivos).
Copie la carpeta a su proyecto Xcode, teniendo cuidado de seleccionar Crear referencias de carpeta cuando lo haga. El archivo de modelo y los metadatos se incluirán en el paquete de la aplicación y estarán disponibles para ML Kit.
Cree el objeto
LocalModel
, especificando la ruta al archivo de manifiesto del modelo:Rápido
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return true } let localModel = LocalModel(manifestPath: manifestPath)
C objetivo
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithManifestPath:manifestPath];
Configurar una fuente de modelo alojada en Firebase
Para utilizar el modelo alojado de forma remota, cree un objeto CustomRemoteModel
, especificando el nombre que le asignó al modelo cuando lo publicó:
Rápido
// Initialize the model source with the name you assigned in
// the Firebase console.
let remoteModelSource = FirebaseModelSource(name: "your_remote_model")
let remoteModel = CustomRemoteModel(remoteModelSource: remoteModelSource)
C objetivo
// Initialize the model source with the name you assigned in
// the Firebase console.
MLKFirebaseModelSource *firebaseModelSource =
[[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"];
MLKCustomRemoteModel *remoteModel =
[[MLKCustomRemoteModel alloc] initWithRemoteModelSource:firebaseModelSource];
Luego, inicie la tarea de descarga del modelo, especificando las condiciones bajo las cuales desea permitir la descarga. Si el modelo no está en el dispositivo, o si hay una versión más reciente del modelo disponible, la tarea descargará el modelo de forma asincrónica desde Firebase:
Rápido
let downloadConditions = ModelDownloadConditions(
allowsCellularAccess: true,
allowsBackgroundDownloading: true
)
let downloadProgress = ModelManager.modelManager().download(
remoteModel,
conditions: downloadConditions
)
C objetivo
MLKModelDownloadConditions *downloadConditions =
[[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
allowsBackgroundDownloading:YES];
NSProgress *downloadProgress =
[[MLKModelManager modelManager] downloadRemoteModel:remoteModel
conditions:downloadConditions];
Muchas aplicaciones inician la tarea de descarga en su código de inicialización, pero puede hacerlo en cualquier momento antes de necesitar usar el modelo.
Crea un etiquetador de imágenes a partir de tu modelo.
Después de configurar las fuentes de su modelo, cree un objeto ImageLabeler
a partir de una de ellas.
Si solo tiene un modelo empaquetado localmente, simplemente cree un etiquetador a partir de su objeto LocalModel
y configure el umbral de puntuación de confianza que desea solicitar (consulte Evaluar su modelo ):
Rápido
let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Cloud console
// to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options)
C objetivo
CustomImageLabelerOptions *options =
[[CustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0f); // Evaluate your model in the Cloud console
// to determine an appropriate value.
MLKImageLabeler *imageLabeler =
[MLKImageLabeler imageLabelerWithOptions:options];
Si tiene un modelo alojado de forma remota, deberá comprobar que se haya descargado antes de ejecutarlo. Puede verificar el estado de la tarea de descarga del modelo utilizando el método isModelDownloaded(remoteModel:)
del administrador de modelos.
Aunque solo tiene que confirmar esto antes de ejecutar el etiquetador, si tiene un modelo alojado de forma remota y un modelo empaquetado localmente, podría tener sentido realizar esta verificación al crear una instancia de ImageLabeler
: cree un etiquetador a partir del modelo remoto si es descargado, y del modelo local en caso contrario.
Rápido
var options: CustomImageLabelerOptions
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
options = CustomImageLabelerOptions(remoteModel: remoteModel)
} else {
options = CustomImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Firebase console
// to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options: options)
C objetivo
MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0f); // Evaluate your model in the Firebase console
// to determine an appropriate value.
MLKImageLabeler *imageLabeler =
[MLKImageLabeler imageLabelerWithOptions:options];
Si solo tiene un modelo alojado de forma remota, debe desactivar la funcionalidad relacionada con el modelo (por ejemplo, atenuar u ocultar parte de su interfaz de usuario) hasta que confirme que el modelo se ha descargado.
Puede obtener el estado de descarga del modelo adjuntando observadores al Centro de notificaciones predeterminado. Asegúrese de utilizar una referencia débil a self
en el bloque de observador, ya que las descargas pueden tardar algún tiempo y el objeto de origen puede liberarse cuando finaliza la descarga. Por ejemplo:
Rápido
NotificationCenter.default.addObserver(
forName: .mlkitMLModelDownloadDidSucceed,
object: nil,
queue: nil
) { [weak self] notification in
guard let strongSelf = self,
let userInfo = notification.userInfo,
let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
as? RemoteModel,
model.name == "your_remote_model"
else { return }
// The model was downloaded and is available on the device
}
NotificationCenter.default.addObserver(
forName: .mlkitMLModelDownloadDidFail,
object: nil,
queue: nil
) { [weak self] notification in
guard let strongSelf = self,
let userInfo = notification.userInfo,
let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
as? RemoteModel
else { return }
let error = userInfo[ModelDownloadUserInfoKey.error.rawValue]
// ...
}
C objetivo
__weak typeof(self) weakSelf = self;
[NSNotificationCenter.defaultCenter
addObserverForName:MLKModelDownloadDidSucceedNotification
object:nil
queue:nil
usingBlock:^(NSNotification *_Nonnull note) {
if (weakSelf == nil | note.userInfo == nil) {
return;
}
__strong typeof(self) strongSelf = weakSelf;
MLKRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel];
if ([model.name isEqualToString:@"your_remote_model"]) {
// The model was downloaded and is available on the device
}
}];
[NSNotificationCenter.defaultCenter
addObserverForName:MLKModelDownloadDidFailNotification
object:nil
queue:nil
usingBlock:^(NSNotification *_Nonnull note) {
if (weakSelf == nil | note.userInfo == nil) {
return;
}
__strong typeof(self) strongSelf = weakSelf;
NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError];
}];
2. Prepare la imagen de entrada
Cree un objeto VisionImage
utilizando UIImage
o CMSampleBufferRef
.
Si utiliza una UIImage
, siga estos pasos:
- Cree un objeto
VisionImage
conUIImage
. Asegúrese de especificar la.orientation
correcta.Rápido
let image = VisionImage(image: uiImage) visionImage.orientation = image.imageOrientation
C objetivo
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Si utiliza CMSampleBufferRef
, siga estos pasos:
Especifique la orientación de los datos de la imagen contenidos en el búfer
CMSampleBufferRef
.Para obtener la orientación de la imagen:
Rápido
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
C objetivo
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return position == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return position == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return position == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return position == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- Cree un objeto
VisionImage
utilizando el objetoCMSampleBufferRef
y la orientación:Rápido
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objetivo-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Ejecute el etiquetador de imágenes.
Asincrónicamente:
Rápido
imageLabeler.process(image) { labels, error in
guard error == nil, let labels = labels, !labels.isEmpty else {
// Handle the error.
return
}
// Show results.
}
C objetivo
[imageLabeler
processImage:image
completion:^(NSArray<MLKImageLabel *> *_Nullable labels,
NSError *_Nullable error) {
if (label.count == 0) {
// Handle the error.
return;
}
// Show results.
}];
Sincrónicamente:
Rápido
var labels: [ImageLabel]
do {
labels = try imageLabeler.results(in: image)
} catch let error {
// Handle the error.
return
}
// Show results.
C objetivo
NSError *error;
NSArray<MLKImageLabel *> *labels =
[imageLabeler resultsInImage:image error:&error];
// Show results or handle the error.
4. Obtener información sobre objetos etiquetados.
Si la operación de etiquetado de imágenes tiene éxito, devuelve una matriz de ImageLabel
. Cada ImageLabel
representa algo que fue etiquetado en la imagen. Puede obtener la descripción de texto de cada etiqueta (si está disponible en los metadatos del archivo de modelo de TensorFlow Lite), la puntuación de confianza y el índice. Por ejemplo:
Rápido
for label in labels {
let labelText = label.text
let confidence = label.confidence
let index = label.index
}
C objetivo
for (MLKImageLabel *label in labels) {
NSString *labelText = label.text;
float confidence = label.confidence;
NSInteger index = label.index;
}
Consejos para mejorar el rendimiento en tiempo real
Si desea etiquetar imágenes en una aplicación en tiempo real, siga estas pautas para lograr las mejores velocidades de fotogramas:
- Llamadas del acelerador al detector. Si hay un nuevo cuadro de video disponible mientras el detector está en ejecución, suelte el cuadro.
- Si está utilizando la salida del detector para superponer gráficos en la imagen de entrada, primero obtenga el resultado, luego renderice la imagen y superpóngala en un solo paso. Al hacerlo, renderiza en la superficie de visualización solo una vez por cada cuadro de entrada. Consulte las clases previaOverlayView y FIRDetectionOverlayView en la aplicación de muestra de presentación para ver un ejemplo.