想要从深度神经网络获取正确的预测,首先需要预处理数据。 在深度学习、图像分类中,通常会用到:
OpenCV的新神经网络(DNN deep nerual network)模块包含两个功能,可用于预处理图像并通过预先接受训练的深度学习模型对它们进行分类。
这篇博客将使用并介绍OpenCV的 cv2.dnn.BlobFromImage 和 cv2.dnn.BlobFromImages 是如何工作的。
OpenCV提供了俩个方法,可以对图像预处理进行深度学习分类:
这两个功能包括
均值:
,
,
均值减法:
,
,
比例因子:
以促进归一化,
,
,
均值减法用于帮助对数据集中输入图像的照明变换进行均衡。因此可以将均值减法视为用于帮助卷积神经网络的技术。
预处理的方法不只均值减法、缩放,还有归一化等;
该方法返回一个blob,宽度高度深度的图像
blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size, mean, swapRB=True)
image: 想要预处理的输入图像
saclefactor: 比例因子,执行均值减法后,可通过某种因子来扩展图像。默认为“1.0”(即,不缩放),但也可以提供另一个值。标记Scalefactor也很重要应该是1
/ sigma,因为实际乘以Scalefactor的输入通道(平均减法)。size:卷积神经网络期望的空间尺寸。对于大多数最新的最先进的神经网络,这是224×224,227×227或299×299。
mean: 均值减法值。可以是RGB的3元组,也可以是单个值。在这种情况下,从图像的每个通道值中减去提供的值。当SwapRB = TRUE时,确保该值为“(R,G,B)” 3元组
swaprb:OpenCV假定图像处于BGR通道顺序;但是,“均值”假定正在使用RGB通道数据,要解决此差异,需要在图像中交换R和B通道。通过将此值设置为
true
。默认情况下,OpenCV会执行RB通道交换;
blob = cv2.dnn.blobFromImages(images, scalefactor=1.0, size, mean, swapRB=True) 差别只是入参可以是多个图片,多张图片的处理调用该方法可降低处理开销。
# 导入必要的包
from imutils import paths
import numpy as np
import cv2
# 从磁盘加载标签类
rows = open("synset_words.txt").read().strip().split("\n")
classes = [r[r.find(" ") + 1:].split(",")[0] for r in rows]
# 从磁盘加载序列化的模型
net = cv2.dnn.readNetFromCaffe("bvlc_googlenet.prototxt",
"bvlc_googlenet.caffemodel")
# 获取输入图片的路径
imagePaths = sorted(list(paths.list_images("images/")))
# 从磁盘加载第一张照片
# 预处理图片:缩放到224*224,通过预先训练的网络构造一个可以通过的斑点
image = cv2.imread(imagePaths[0])
resized = cv2.resize(image, (224, 224))
blob = cv2.dnn.blobFromImage(resized, 1, (224, 224), (104, 117, 123))
print("First Blob: {}".format(blob.shape))
# 设置blob为深度学习网络预训练的input
# 获取1000种类中,预测的可能输出结果及可能性
net.setInput(blob)
preds = net.forward()
# 倒序排序可能性,获取预测可能最高的类标签,绘制在输入图像上
idx = np.argsort(preds[0])[::-1][0]
text = "Label: {}, {:.2f}%".format(classes[idx],
preds[0][idx] * 100)
cv2.putText(image, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0, 0, 255), 2)
# 展示输出图像
cv2.imshow("Image", image)
cv2.waitKey(0)
# 初始化照片列表,之后会传给网络
images = []
# 遍历输入图像(过滤掉第一张,因为已经分类过),预处理每张图像,并更新图像列表
for p in imagePaths[1:]:
image = cv2.imread(p)
image = cv2.resize(image, (224, 224))
images.append(image)
# 转换图像list为opencv可编译的blob
blob = cv2.dnn.blobFromImages(images, 1, (224, 224), (104, 117, 123))
print("Second Blob: {}".format(blob.shape))
# 设置blob为深度学习网络预训练的input
# 获取1000种类中,预测的可能输出结果及可能性
net.setInput(blob)
preds = net.forward()
# 遍历输入图像
for (i, p) in enumerate(imagePaths[1:]):
# 从磁盘加载图像
image = cv2.imread(p)
# 寻找可能性最高的预测分类,并绘制标签到图像上
idx = np.argsort(preds[i])[::-1][0]
text = "Label: {}, {:.2f}%".format(classes[idx],
preds[i][idx] * 100)
cv2.putText(image, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0, 0, 255), 2)
# 展示输出图像
cv2.imshow("Image", image)
cv2.waitKey(0)