Я пытаюсь загрузить 2-мерное изображение, хранящееся как NSMutableArray (полуслучайного размера), изменить размер массива до 512x512, а затем передать его в модель coreML в качестве изображения (Grayscale 512x512) для прогнозирования. Есть ли эффективный способ сделать это? Сначала преобразовать массив NsMutableArray в UIImage / NSImage / CVPixelBuffer, а затем изменить его размер? Может ли какой-либо из этих типов удовлетворять входу "Изображение (Оттенки серого 512x512)"?
Я попытался преобразовать в NSImage и изменить его размер, а затем передать полученное изображение непосредственно в модель:
NSSize newSize;
newSize.height = 512;
newSize.width = 512;
const NSImage* segImage = [Viewer1.imageView nsimage:YES];
[segImage setScalesWhenResized:YES];
int widthNSI = [segImage size].width;
int heightNSI = [segImage size].height;
NSLog(@"NSImage original width: %i", widthNSI);
NSLog(@"NSImage original height: %i", heightNSI);
NSImage *resized = [[NSImage alloc] initWithSize: newSize];
[resized lockFocus];
[segImage setSize: newSize];
[[NSGraphicsContext currentContext] setImageInterpolation: NSImageInterpolationHigh];
[segImage drawAtPoint:NSZeroPoint fromRect:CGRectMake(0, 0, newSize.width, newSize.height) operation:NSCompositeCopy fraction:1.0];
[resized unlockFocus];
int widthRES = [resized size].width;
int heightRES = [resized size].height;
NSLog(@"NSImage adjusted width: %i", widthRES);
NSLog(@"NSImage adjusted height: %i", heightRES);
coremodel_segment *model = nil;
model = [[coremodel_segment alloc] init];
Это, кажется, выплевывает измененное изображение (я не смог визуализировать, но по крайней мере размеры в порядке на основе журнала). Когда я пытаюсь сделать прогноз, я получаю:
-[MLNeuralNetworkEngine predictionFromInput:]: unrecognized selector sent to instance 0x7faf43c9a1c0
Итак, я предполагаю, что либо: 1. формат NSImage несовместим (это должен быть CVPixelFormat?), 2. я делаю что-то не так с изменением размера или 3. я вызываю функцию предиката неправильно.
Я также пытался преобразовать NSImage в CVPixel с помощью:
CVPixelBufferRef buffer = NULL;
size_t width = [resized size].width;
size_t height = [resized size].height;
size_t bitsPerComponent = 8; // *not* CGImageGetBitsPerComponent(image);
CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGBitmapInfo bi = kCGImageAlphaNoneSkipFirst; // *not* CGImageGetBitmapInfo(image);
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
CVPixelBufferCreate(kCFAllocatorDefault, width, height, k32ARGBPixelFormat, (CFDictionaryRef)d, &buffer);
CVPixelBufferLockBaseAddress(buffer, 0);
void *rasterData = CVPixelBufferGetBaseAddress(buffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(buffer);
CGContextRef ctxt = CGBitmapContextCreate(rasterData, width, height, bitsPerComponent, bytesPerRow, cs, bi);
if(ctxt == NULL){
NSLog(@"could not create context");
return NULL;
}
NSGraphicsContext *nsctxt = [NSGraphicsContext graphicsContextWithGraphicsPort:ctxt flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:nsctxt];
[resized compositeToPoint:NSMakePoint(0.0, 0.0) operation:NSCompositeCopy];
[NSGraphicsContext restoreGraphicsState];
CVPixelBufferUnlockBaseAddress(buffer, 0);
CFRelease(ctxt);
coremodel_segmentOutput *prediction = [model predictionFromData:buffer error:nil];
но я получаю ту же ошибку.
Я понимаю, что в CVPixelBufferConversionCode я перечисляю цветовое пространство как RBG, не уверенный, вызовет ли это какие-либо проблемы .. (GenericGray вызвал различные проблемы)
CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
Не уверен, поможет ли это, но вот заголовок модели: //
// coremodel_segment.h
//
// This file was automatically generated and should not be edited.
//
#import <Foundation/Foundation.h>
#import <CoreML/CoreML.h>
#include <stdint.h>
NS_ASSUME_NONNULL_BEGIN
/// Model Prediction Input Type
API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) __attribute__((visibility("hidden")))
@interface coremodel_segmentInput : NSObject<MLFeatureProvider>
/// data as grayscale (kCVPixelFormatType_OneComponent8) image buffer, 512 pixels wide by 512 pixels high
@property (readwrite, nonatomic) CVPixelBufferRef data;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithData:(CVPixelBufferRef)data;
@end
/// Model Prediction Output Type
API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) __attribute__((visibility("hidden")))
@interface coremodel_segmentOutput : NSObject<MLFeatureProvider>
/// image as 1 x 512 x 512 3-dimensional array of doubles
@property (readwrite, nonatomic, strong) MLMultiArray * image;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithImage:(MLMultiArray *)image;
@end
/// Class for model loading and prediction
API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) __attribute__((visibility("hidden")))
@interface coremodel_segment : NSObject
@property (readonly, nonatomic, nullable) MLModel * model;
- (nullable instancetype)init;
- (nullable instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError * _Nullable * _Nullable)error;
- (nullable instancetype)initWithConfiguration:(MLModelConfiguration *)configuration error:(NSError * _Nullable * _Nullable)error API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) __attribute__((visibility("hidden")));
- (nullable instancetype)initWithContentsOfURL:(NSURL *)url configuration:(MLModelConfiguration *)configuration error:(NSError * _Nullable * _Nullable)error API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) __attribute__((visibility("hidden")));
/**
Make a prediction using the standard interface
@param input an instance of coremodel_segmentInput to predict from
@param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL.
@return the prediction as coremodel_segmentOutput
*/
- (nullable coremodel_segmentOutput *)predictionFromFeatures:(coremodel_segmentInput *)input error:(NSError * _Nullable * _Nullable)error;
/**
Make a prediction using the standard interface
@param input an instance of coremodel_segmentInput to predict from
@param options prediction options
@param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL.
@return the prediction as coremodel_segmentOutput
*/
- (nullable coremodel_segmentOutput *)predictionFromFeatures:(coremodel_segmentInput *)input options:(MLPredictionOptions *)options error:(NSError * _Nullable * _Nullable)error;
/**
Make a prediction using the convenience interface
@param data as grayscale (kCVPixelFormatType_OneComponent8) image buffer, 512 pixels wide by 512 pixels high:
@param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL.
@return the prediction as coremodel_segmentOutput
*/
- (nullable coremodel_segmentOutput *)predictionFromData:(CVPixelBufferRef)data error:(NSError * _Nullable * _Nullable)error;
/**
Batch prediction
@param inputArray array of coremodel_segmentInput instances to obtain predictions from
@param options prediction options
@param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL.
@return the predictions as NSArray<coremodel_segmentOutput *>
*/
- (nullable NSArray<coremodel_segmentOutput *> *)predictionsFromInputs:(NSArray<coremodel_segmentInput*> *)inputArray options:(MLPredictionOptions *)options error:(NSError * _Nullable * _Nullable)error API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) __attribute__((visibility("hidden")));
@end
NS_ASSUME_NONNULL_END
Модель была сохранена с:
сегмент_модель =
coremltools.converters.keras.convert('/Users/.../Downloads/model_segment.h5', input_names='data', image_input_names='data', output_names='image');
segment_model.save('/Users/.../Downloads/coremodel_segment.mlmodel');
, где я добавил имена ввода, чтобы форма ввода была изображением вместо MultiArray. Я попытался изменить строку прогноза на «данные» вместо «ввода»:
coremodel_segmentOutput *вести прогноз = [модель прогнозированияFromData: ошибка буфера: ноль];
и теперь получите это в моей консоли:
Error Domain=com.apple.CoreML Code=1 UserInfo={NSLocalizedDescription=<private>, NSUnderlyingError=0x600003982340 {Error Domain=com.apple.CoreML Code=1 UserInfo={NSLocalizedDescription=<private>}}}
Failure verifying inputs.