Как рассчитать среднее значение изображения для набора файлов изображений?

У кого-нибудь есть объяснение высокого уровня о том, как вычислить среднее значение изображения для набора изображений (файлы.jpg в папке) и сгенерировать XML-файл в правильном формате для ImageDeserializer?

Я видел код в CNTK_201A_CIFAR-10_DataLoader, который делает это. Но входные данные там в другом формате, поэтому неясно, как именно с этим справиться для файлов изображений в качестве входных данных.

2 ответа

Вы можете просто следовать примеру кода, который вычисляет среднее значение для CIFAR. В основном он проходит через все тренировочные образы и вычисляет среднее значение. Затем он записывает его в файл в формате, понятном OpenCV. Первая часть легка из-за numpy и PIL, а вторая часть легка из-за минидома.

Ниже представлено полное решение, основанное на предоставленных 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)
Другие вопросы по тегам