是否有人对如何计算一组图像(文件夹中的 .jpg 文件)的图像均值并为 ImageDeserializer 生成正确格式的 XML 文件有高级解释?
我已经看到 CNTK_201A_CIFAR-10_DataLoader 中的代码,它执行此操作。但是,那里的输入格式不同,因此不清楚如何将图像文件作为输入来处理。
是否有人对如何计算一组图像(文件夹中的 .jpg 文件)的图像均值并为 ImageDeserializer 生成正确格式的 XML 文件有高级解释?
我已经看到 CNTK_201A_CIFAR-10_DataLoader 中的代码,它执行此操作。但是,那里的输入格式不同,因此不清楚如何将图像文件作为输入来处理。
您可以按照计算 CIFAR 的平均输入的代码示例进行操作。基本上它会遍历所有训练图像并计算平均值。然后它以 OpenCV 可以理解的格式将其写入文件中。第一部分很容易,因为 numpy 和 PIL,第二部分很容易,因为 minidom。
下面是一个完整的解决方案,基于 Nikos 提供的链接,用于计算存储在 ZIP 文件中的所有图像(如果您使用的是 ZIP 图像阅读器)或图像文件列表的平均值。
关于您的问题:在 DataLoader 教程中,填充仅影响将图像保存到文件的代码路径,而不影响计算平均值。
import zipfile
import io
import numpy as np
from PIL import Image
from scipy.misc import imread, imresize, fromimage
import xml.etree.cElementTree as et
import xml.dom.minidom
# saveMean function taken from
# https://github.com/Microsoft/CNTK/blob/v2.0.beta7.0/Examples/Image/DataSets/CIFAR-10/cifar_utils.py#L84
def saveMean(fname, data, imgSize):
root = et.Element('opencv_storage')
et.SubElement(root, 'Channel').text = '3'
et.SubElement(root, 'Row').text = str(imgSize)
et.SubElement(root, 'Col').text = str(imgSize)
meanImg = et.SubElement(root, 'MeanImg', type_id='opencv-matrix')
et.SubElement(meanImg, 'rows').text = '1'
et.SubElement(meanImg, 'cols').text = str(imgSize * imgSize * 3)
et.SubElement(meanImg, 'dt').text = 'f'
et.SubElement(meanImg, 'data').text = ' '.join(['%e' % n for n in np.reshape(data, (imgSize * imgSize * 3))])
tree = et.ElementTree(root)
tree.write(fname)
x = xml.dom.minidom.parse(fname)
with open(fname, 'w') as f:
f.write(x.toprettyxml(indent = ' '))
def loadAndResize(f, networkSize):
im = Image.open(io.BytesIO(f))
n = fromimage(im).astype(np.float)
return imresize(n, (networkSize, networkSize))
然后在从 ZIP 文件或从原始文件中将图像作为字节读取的函数中使用这些构建块:
def meanFromZip(zipFile, networkSize):
imgSum = np.zeros((networkSize, networkSize, 3), np.float)
with zipfile.ZipFile(zipFile) as z:
allFiles = z.namelist()
for f in allFiles:
imgSum = imgSum + loadAndResize(z.read(f), networkSize)
return imgSum / len(allFiles)
def meanFromFiles(files, networkSize):
imgSum = np.zeros((networkSize, networkSize, 3), np.float)
for f in files:
with open(f, 'rb') as b:
imgSum = imgSum + loadAndResize(b.read(), networkSize)
return imgSum / len(files)
调用如下:
zipFile = "myImages.zip"
networkSize = 224
mean = meanFromZip(zipFile, networkSize)
saveMean("mean.xml", mean, networkSize)
files = ["c:/temp/Column0_Line16.jpg", "C:/temp/Column0_Line47.jpg"]
mean2 = meanFromFiles(files, networkSize)