我想将图像的像素值标准化为每个通道(R,G,B)的范围[0,1]。
import Ember from 'ember';
import ToriiFirebaseAdapter from 'emberfire/torii-adapters/firebase';
export default ToriiFirebaseAdapter.extend({
firebase: Ember.inject.service()
});
考虑https://commons.wikimedia.org/wiki/File:Crocodylus-johnsoni-3.jpg, 我得到以下"标准化"结果:
正如您所看到的,右侧有从上到下的线条。那里发生了什么?在我看来,规范化出错了。如果是这样:我该如何解决?
答案 0 :(得分:4)
在scikit-learn中,形状为(m,n)的二维数组通常被解释为 m 样本的集合,每个样本都有 n 功能。
MinMaxScaler.fit_transform()
会转换每个功能,因此您的数组的每一列都会独立于其他列进行转换。这导致图像中出现垂直“条纹”。
您似乎打算独立缩放每个颜色通道。要使用MinMaxScaler
执行此操作,请重新整形输入,以便每个通道都成为一列。也就是说,如果原始图像具有形状(m,n,3),则在将其传递给fit_transform()
方法之前将其重新整形为(m * n,3),然后恢复结果的形状以创建转换阵列。
例如,
ascolumns = original.reshape(-1, 3)
t = scaler.fit_transform(ascolumns)
transformed = t.reshape(original.shape)
有了这个,transformed
看起来像这样:
图像看起来与原始图像完全一样,因为事实证明在数组original
中,每个通道中的最小值和最大值分别为0和255:
In [41]: original.min(axis=(0, 1))
Out[41]: array([0, 0, 0], dtype=uint8)
In [42]: original.max(axis=(0, 1))
Out[42]: array([255, 255, 255], dtype=uint8)
因此,在这种情况下,所有fit_transform
都会将所有输入值均匀地转换为浮点范围[0.0,1.0]。如果其中一个通道的最小值或最大值不同,则转换后的图像看起来会有所不同。
顺便说一句,使用纯粹的numpy进行转换并不困难。 (我使用的是Python 3,所以在下面,除法会自动将结果转换为浮点数。如果你使用的是Python 2,你需要将其中一个参数转换为浮点数,或者使用{{1} }。)
from __future__ import division
(该方法的一个潜在问题是,如果其中一个通道是常量,它将产生错误,因为In [58]: omin = original.min(axis=(0, 1), keepdims=True)
In [59]: omax = original.max(axis=(0, 1), keepdims=True)
In [60]: xformed = (original - omin)/(omax - omin)
In [61]: np.allclose(xformed, transformed)
Out[61]: True
中的一个值将为0。)