美文网首页
iOS调用CoreML模型

iOS调用CoreML模型

作者: QYiZHong | 来源:发表于2018-01-17 23:03 被阅读161次

首先我是用到了apple提供的MobilNet模型
这里放上链接https://developer.apple.com/machine-learning/
这是一个对物品进行分类的模型,介绍里写的是能分类1000种

首先是下下来导入到xcode


QQ20180117-224509@2x.png

点击上图这里可以进入model生成的类

QQ20180117-224551@2x.png

像上图这样

模型里都有初始化方法、input和output方法

调用的时候input对应output,要注意input上面的注释,比如说这个模型里的input上面有一行注释: Input image to be classified as color (kCVPixelFormatType_32BGRA) image buffer, 224 pixels wide by 224 pixels high
要的是一个CVPixelBufferRef类型的图片,然后图片还要按照224高和224宽的像素点缩放,一定要在input里设置好图片,不然output只会输出null
附上缩放的代码以及UIImage转换为CVPixelBufferRef的代码(找来的)

- (UIImage *)scaleToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}

- (CVPixelBufferRef)pixelBufferFromCGImage:(UIImage *)originImage {
CGImageRef image = originImage.CGImage;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                         nil];

CVPixelBufferRef pxbuffer = NULL;

CGFloat frameWidth = CGImageGetWidth(image);
CGFloat frameHeight = CGImageGetHeight(image);

CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
                                      frameWidth,
                                      frameHeight,
                                      kCVPixelFormatType_32ARGB,
                                      (__bridge CFDictionaryRef) options,
                                      &pxbuffer);

NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);

CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef context = CGBitmapContextCreate(pxdata,
                                             frameWidth,
                                             frameHeight,
                                             8,
                                             CVPixelBufferGetBytesPerRow(pxbuffer),
                                             rgbColorSpace,
                                             (CGBitmapInfo)kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context);
CGContextConcatCTM(context, CGAffineTransformIdentity);
CGContextDrawImage(context, CGRectMake(0,
                                       0,
                                       frameWidth,
                                       frameHeight),
                   image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);

CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

return pxbuffer;
}

+ (CGImageRef) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer {
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);        // Lock the image buffer

uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);   // Get information of the image
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef newImage = CGBitmapContextCreateImage(newContext);
CGContextRelease(newContext);

CGColorSpaceRelease(colorSpace);
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
/* CVBufferRelease(imageBuffer); */
return newImage;
}

使用的时候

CGImageRef cgImage = [UIImage imageFromSampleBuffer:sampleBuffer];
UIImage image = [UIImage imageWithCGImage:cgImage];
MobileNet *mobileNet = [[MobileNet alloc] init];
NSError *error;
UIImage *scaledImage = [image scaleToSize:CGSizeMake(224, 224)];
CVPixelBufferRef buffer = [image pixelBufferFromCGImage:scaledImage];
MobileNetInput *input = [[MobileNetInput alloc] initWithImage:buffer];
MobileNetOutput *output = [mobileNet predictionFromFeatures:input error:&error];
NSLog(@"%@",output.classLabel);

这个output.classLabel就是这个模型的输出
不同的模型输出的方式是不同的,但是本质上都是用output类输出

相关文章

网友评论

      本文标题:iOS调用CoreML模型

      本文链接:https://www.haomeiwen.com/subject/hcjpoxtx.html