很多时候我们需要对图像进行局部对比度归一化,比如分块CNN的预处理阶段。theano对此提供了一些比较方便的操作。
局部归一化的一种简单形式为:
其中μ和σ分别为局部(例如3x3的小块)的均值和标准差。
利用代码说明一下如何实现:
import theano import numpy from theano.sandbox import neighbours from theano import tensor as T from theano import function from skimage import io import time patch = io.imread('test.jpg', True) patch_batch = [] batch_size = 384 # 这里模拟批量处理多个图像块 for i in xrange(batch_size): patch_batch.append(patch) _input = T.tensor3('_input') norm_input = T.reshape(_input, T.concatenate([(batch_size,1),_input.shape[1:]]), ndim=4) # neighbours.images2neibs(ten4, neib_shape, neib_step=None, mode='valid'),其中neib_shap为邻域大小,这里设置为3x3, # neib_step指定步长,我们需要对每一个点进行归一化,因此设定为(1x1) # 该函数返回一个shape为(batch_size x patch_width x patch_height, 9)的数组,每一行代表每个点的9个邻居 neibs = neighbours.images2neibs(norm_input, (3, 3), (1, 1), 'wrap_centered') _means = T.mean(neibs, axis=1) _stds = T.std(neibs, axis=1) _flatten_input = _input.flatten() normed_result = (_flatten_input - _means) / (_stds + 1 / 255) # 将结果重新reshape为图像大小 reshpaed_normed_result = T.reshape(normed_result, _input.shape) shared_patch = theano.shared(numpy.asarray(patch_batch, dtype=theano.config.floatX), borrow=True) calc_norm = function([], reshpaed_normed_result, givens={_input:shared_patch}) start_time = time.clock() dd = calc_norm() end_time = time.clock() print end_time - start_time