首先我是用到了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类输出
网友评论