我想训练一些模型来处理灰度图像,例如对于显微镜应用很有用(来源)。因此,我想使用 pytorch 灰度转换(torchvision.transforms.Grayscale)在灰度 imagenet 上训练我的模型,将 RGB imagenet 转换为灰度 imagenet。 pytorch 内部将颜色空间从 RGB 旋转到 YPbPr,如下所示:
则Y'为灰度通道,因此变换后可以忽略Pb和Pr。其实pytorch甚至只是计算
grayscale = (0.2989 * r + 0.587 * g + 0.114 * b)
为了标准化图像数据,我需要知道grayscale-imagenet的平均像素值以及标准差。这些可以计算吗?
我成功地使用
计算了平均像素强度meanGrayscale = 0.2989 * r.mean() + 0.587 * g.mean() + 0.114 * b.mean()
变换图像然后计算灰度平均值,得到的结果与先计算 RGB 平均值然后将其转换为灰度平均值相同。
但是,我现在对计算方差或标准差一无所知。有人有任何想法,或者知道一些关于这个主题的好文献吗?这可能吗?
我找到了一本出版物《龚建新 - 澄清标准差椭圆》……他在二维中做到了这一点(据我所知)。我只是还不知道如何在 3D 中做到这一点。
好吧,我无法按计划计算标准差,但使用下面的代码进行了计算。灰度 imagenet 的训练数据集平均值和标准差是(根据需要舍入):
平均值:0.44531356896770125
标准偏差:0.2692461874154524
import multiprocessing
import os
def calcSTD(d):
meanValue = 0.44531356896770125
squaredError = 0
numberOfPixels = 0
for f in os.listdir("/home/imagenet/ILSVRC/Data/CLS-LOC/train/"+str(d)+"/"):
if f.endswith(".JPEG"):
image = imread("/home/imagenet/ILSVRC/Data/CLS-LOC/train/"+str(d)+"/"+str(f))
###Transform to gray if not already gray anyways
if np.array(image).ndim == 3:
matrix = np.array(image)
blue = matrix[:,:,0]/255
green = matrix[:,:,1]/255
red = matrix[:,:,2]/255
gray = (0.2989 * red + 0.587 * green + 0.114 * blue)
else:
gray = np.array(image)/255
###----------------------------------------------------
for line in gray:
for pixel in line:
squaredError += (pixel-meanValue)**2
numberOfPixels += 1
return (squaredError, numberOfPixels)
a_pool = multiprocessing.Pool()
folders = []
[folders.append(f.name) for f in os.scandir("/home/imagenet/ILSVRC/Data/CLS-LOC/train") if f.is_dir()]
resultStD = a_pool.map(calcSTD, folders)
StD = (sum([intensity[0] for intensity in resultStD])/sum([pixels[1] for pixels in resultStD]))**0.5
print(StD)
过程中出现了一些类似这样的错误:
/opt/conda/lib/python3.7/site-packages/PIL/TiffImagePlugin.py:771: 用户警告:EXIF 数据可能已损坏。 预计读取 8 个字节 但只得到 4。跳过标签 41486“可能损坏 EXIF 数据。”
跳过了 2019 版 ImageNet 中的相应图像。
要计算灰度 ImageNet 像素值的标准差,您确实可以使用您提到的转换公式。使用以下公式执行从 RGB 到灰度的转换:
{grayscale} = 0.2989 X R + 0.587 X G + 0.114 X B
您使用以下方法成功计算了平均灰度像素值:
meanGrayscale = 0.2989 * r.mean() + 0.587 * g.mean() + 0.114 * b.mean()
现在,为了计算标准差,我们可以使用方差的属性。标准差是方差的平方根,计算公式如下:
计算方差: 应用转换系数,可以从 RGB 通道的方差导出灰度值的方差。给定灰度公式,方差由下式给出:
其中R、G、B符号是各自RGB通道的方差。
计算标准差: 最后,灰度图像的标准差可以计算为:
以下是如何使用 PyTorch 在 Python 中实现此功能:
import torch
# Assuming r, g, b are your RGB channel tensors
r = torch.randn(1000) # Example tensor for red channel
g = torch.randn(1000) # Example tensor for green channel
b = torch.randn(1000) # Example tensor for blue channel
# Calculate means
mean_r = r.mean()
mean_g = g.mean()
mean_b = b.mean()
# Calculate variances
var_r = r.var(unbiased=False) # Population variance
var_g = g.var(unbiased=False)
var_b = b.var(unbiased=False)
# Calculate grayscale mean
meanGrayscale = 0.2989 * mean_r + 0.587 * mean_g + 0.114 * mean_b
# Calculate grayscale variance
var_gray = (0.2989**2 * var_r) + (0.587**2 * var_g) + (0.114**2 * var_b)
# Calculate grayscale standard deviation
std_gray = var_gray.sqrt()
print(f"Mean Grayscale Value: {meanGrayscale.item()}")
print(f"Standard Deviation of Grayscale Values: {std_gray.item()}")
这将为您提供灰度 ImageNet 像素值的平均值和标准差,您可以将其用于模型中的标准化。