当使用 OpenCV 完成图像加载和调整大小时,Resnet50 会产生不同的预测

我想使用 Keras Resnet50 模型和 OpenCV 来读取输入图像并调整其大小。我使用 Keras 中的相同预处理代码(对于 OpenCV,我需要转换为 RGB,因为这是 preprocess_input() 期望的格式)。我使用 OpenCV 和 Keras 图像加载得到的预测略有不同。我不明白为什么预测不一样。


这是我的代码:


import numpy as np

import json

from tensorflow.keras.applications.resnet50 import ResNet50

from tensorflow.keras.preprocessing import image

from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions

import cv2


model = ResNet50(weights='imagenet')


img_path = '/home/me/squirle.jpg'


# Keras prediction

img = image.load_img(img_path, target_size=(224, 224))

x = image.img_to_array(img)

x = np.expand_dims(x, axis=0)

x = preprocess_input(x)

preds = model.predict(x)

print('Predicted Keras:', decode_predictions(preds, top=3)[0])


# OpenCV prediction

imgcv = cv2.imread(img_path)

dim = (224, 224)

imgcv_resized = cv2.resize(imgcv, dim, interpolation=cv2.INTER_LINEAR)

x = cv2.cvtColor(imgcv_resized , cv2.COLOR_BGR2RGB)

x = np.expand_dims(x, axis=0)

x = preprocess_input(x)

preds = model.predict(x)

print('Predicted OpenCV:', decode_predictions(preds, top=3)[0])


Predicted Keras: [('n02490219', 'marmoset', 0.28250763), ('n02356798', 'fox_squirrel', 0.25657368), ('n02494079', 'squirrel_monkey', 0.19992349)]

Predicted OpenCV: [('n02356798', 'fox_squirrel', 0.5161952), ('n02490219', 'marmoset', 0.21953616), ('n02494079', 'squirrel_monkey', 0.1160824)]


如何使用 OpenCVimread()并resize()获得与 Keras 图像加载相同的预测?


素胚勾勒不出你
浏览 94回答 2
2回答

森栏

# Keras predictionimg = image.load_img(img_path, target_size=(224, 224))   # OpenCV predictionimgcv = cv2.imread(img_path)dim = (224, 224)imgcv_resized = cv2.resize(imgcv, dim, interpolation=cv2.INTER_LINEAR)如果你仔细看的话,你在cv2的情况下指定的插值是cv2.INTER_LINEAR(双线性插值);但是,默认情况下 image.load_img()使用INTER_NEAREST插值方法。img_to_array(img)。这里的参数dtype是:无默认为 None,在这种情况下使用全局设置 tf.keras.backend.floatx() (除非您更改它,否则它默认为“float32”)因此,img_to_array(img)您有一个由值组成的图像float32,而cv2.imread(img)返回一个值的 numpy 数组uint8。确保从 BGR 转换为 RGB,因为 OpenCV 直接加载为 BGR 格式。您可以使用image = image[:,:,::-1]或image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB); 否则,R 和 B 通道将会颠倒,导致比较不正确。由于您在这两种情况下应用的预处理是相同的,因此唯一的区别是我上面提到的那些;适应这些变化应确保可重复性。我想做一个观察:假设使用一个cv2自动(并且可以说仅加载整数)而不是浮点数的库(在本例中),唯一正确的方法是将第一个预测数组(Keras)转换为uint8因为通过将后者转换为float32,信息中可能存在的差异就会丢失。例如,通过cv2加载到uint8,并通过强制转换而不是233得到233.0。然而,也许初始像素值是233,3,但由于第一次转换而丢失了。

慕仙森

Keras 以RGB格式加载图像,而 OpenCV 以BGR格式加载图像。ResNet50的预处理函数使用caffe设置,它期望图像为RGB格式,并应用以下内容:反转通道(RGB -> BGR)从各自的值中减去 [103.939, 116.779, 123.68]由于每个通道要减去的值不同,因此通道顺序很重要。此外,预训练的ResNet50 模型的各层已经按照一定的顺序进行了训练。因此,使用 OpenCV 加载图像时,必须将通道顺序从BGR反转为RGBimgcv_resized =  imgcv_resized[:,:,::-1]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python