我有一个Keras模型,并已成功将其转换为Coreml。我将RGB格式的彩色50x50图像传递给模型,一切都在我的Keras模型中用Python编写。但是我真的很难从Coreml模型中获得相同的结果。我在我的iOS应用程序中使用OpenCV,需要将cv :: Mat转换为CVPixelBufferRef。我很肯定我的意见不对,但我无法弄清楚它是什么。我发送到Python模型的输入的预处理看起来像这样
image = cv2.resize(image, (50, 50))
image = image.astype("float") / 255.0
image = img_to_array(image)
image = np.expand_dims(image, axis=0)
任何帮助将不胜感激。下面是从Keras到Coreml的转换及其输出,以及将cv :: Mat转换为CVPixelBufferRef的功能(此处的图像已经调整为50x50)。
Keras to Coreml转换
coreml_model = coremltools.converters.keras.convert(model, input_names='image', image_input_names='image', output_names='output', class_labels=output_labels, image_scale=1/255.0)
OpenCV Mat to CVPixelBufferRef
int width = 50;//frame.cols;
int height = 50;//frame.rows;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
kCVPixelBufferCGBitmapContextCompatibilityKey,
[NSNumber numberWithInt:width], kCVPixelBufferWidthKey,
[NSNumber numberWithInt:height], kCVPixelBufferHeightKey,
nil];
CVPixelBufferRef imageBuffer;
CVReturn status = CVPixelBufferCreate(kCFAllocatorMalloc, width, height, kCVPixelFormatType_32BGRA, (CFDictionaryRef) CFBridgingRetain(options), &imageBuffer);
NSParameterAssert(status == kCVReturnSuccess && imageBuffer != NULL);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
void *base = CVPixelBufferGetBaseAddress(imageBuffer) ;
memcpy(base, frame.data, frame.total()*4);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
return imageBuffer;
答案 0 :(得分:1)
如果您尝试使用OpenCV加载图像并将其输入Keras模型,则需要格外小心,因为在训练时Keras默认使用PIL加载图像。问题是PIL将图像加载为RGB格式,而OpenCV将图像加载为BGR格式。因此,如果您将OpenCV映像直接提供给Keras,则不会出现任何错误,但结果将完全错误。
关于此问题的解决方案,在Python中,您可以简单地使用
img[...,[0,2]]=img[...,[2,0]]
在OpenCV格式和PIL格式之间转换3通道图像文件。