Hay dos formas de integrar modelos entrenados desde AutoML Vision Edge. Puede agrupar el modelo copiando los archivos del modelo en su proyecto Xcode, o puede 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 de ML Kit en su Podfile:
Para agrupar un modelo con su aplicación:
pod 'GoogleMLKit/ImageLabelingCustom'
Para descargar dinámicamente un modelo de Firebase, agregue la dependencia de
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 empaqueta 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 la consola Firebase 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 del 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 usar el modelo alojado de forma remota, cree un objeto CustomRemoteModel
y especifique el nombre que 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 disponible una versión más reciente del modelo, la tarea descargará el modelo de forma asíncrona 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 que necesite usar el modelo.
Cree un etiquetador de imágenes a partir de su 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á verificar que se haya descargado antes de ejecutarlo. Puede comprobar el estado de la tarea de descarga del modelo mediante 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 desde el modelo remoto si es sido 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 deshabilitar 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 usar una referencia débil a self
en el bloque del observador, ya que las descargas pueden llevar 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. Prepara la imagen de entrada
Cree un objeto VisionImage
usando UIImage
o CMSampleBufferRef
.
Si usa 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 usa un CMSampleBufferRef
, siga estos pasos:
Especifique la orientación de los datos de 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)
C objetivo
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Ejecute el etiquetador de imágenes
Asíncronamente:
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 deImageLabel
. 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 del 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;
}
Sugerencias 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 tasas de cuadros:
- Llamadas del acelerador al detector. Si un nuevo cuadro de video está disponible mientras el detector está funcionando, 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 superponga en un solo paso. Al hacerlo, renderiza en la superficie de visualización solo una vez para cada cuadro de entrada. Consulte las clases previewOverlayView y FIRDetectionOverlayView en la aplicación de ejemplo de presentación para ver un ejemplo.