Calculate the mean and variance of each channel of RGB in the image dataset

The first way of writing is to read in first, and then calculate. It consumes more memory.

import cv2
import numpy as np
import torch 

startt = 700
CNum = 100   # 挑选多少图片进行计算
imgs=[]
for i in range(startt, startt+CNum):
    img_path = os.path.join(root_path, filename[i])
    img = cv2.imread(img_path)
    img = img[:, :, :, np.newaxis]
    imgs.append(torch.Tensor(img))

torch_imgs = torch.cat(imgs, dim=3)

means, stdevs = [], []
for i in range(3):
    pixels = torch_imgs[:, :, i, :]  # 拉成一行
    means.append(torch.mean(pixels))
    stdevs.append(torch.std(pixels))

# cv2 读取的图像格式为BGR,PIL/Skimage读取到的都是RGB不用转
means.reverse()  # BGR --> RGB
stdevs.reverse()

print("normMean = {}".format(means))
print("normStd = {}".format(stdevs))

  

The second way of writing is to read one and calculate one, which is more time-consuming: first calculate the mean, and then calculate the variance.

import os
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from scipy.misc import imread

startt = 4000
CNum = 1000   # 挑选多少图片进行计算
num = 1000 * 3200 * 1800  # 这里(3200,1800)是每幅图片的大小,所有图片尺寸都一样

imgs=[]
R_channel = 0
G_channel = 0
B_channel = 0
for i in range(startt, startt+CNum):
    img = imread(os.path.join(root_path, filename[i]))
    R_channel = R_channel + np.sum(img[:, :, 0])
    G_channel = G_channel + np.sum(img[:, :, 1])
    B_channel = B_channel + np.sum(img[:, :, 2])

R_mean = R_channel / num
G_mean = G_channel / num
B_mean = B_channel / num

R_channel = 0
G_channel = 0
B_channel = 0
for i in range(startt, startt+CNum):
    img = imread(os.path.join(root_path, filename[i]))
    R_channel = R_channel + np.sum(np.power(img[:, :, 0]-R_mean, 2) )
    G_channel = G_channel + np.sum(np.power(img[:, :, 1]-G_mean, 2) )
    B_channel = B_channel + np.sum(np.power(img[:, :, 2]-B_mean, 2) )

R_std = np.sqrt(R_channel/num)
G_std = np.sqrt(G_channel/num)
B_std = np.sqrt(B_channel/num)

# R:65.045966   G:70.3931815    B:78.0636285
print("R_mean is %f, G_mean is %f, B_mean is %f" % (R_mean, G_mean, B_mean))
print("R_std is %f, G_std is %f, B_std is %f" % (R_std, G_std, B_std))

  

The third way of writing, you only need to traverse once: calculate x, x^2 in one cycle; then x'=sum(x)/N, and sum(x^2), according to the following formula:

S^2
= sum((x-x')^2 )/N = sum(x^2+x'^2-2xx')/N
= {sum(x^2) + sum(x'^2) - 2x'*sum(x) }/N
= {sum(x^2) + N*(x'^2) - 2x'*(N*x') }/N
= {sum(x^2) - N*(x'^2) }/N
= sum(x^2)/N - x'^2

S = sqrt( sum(x^2)/N - (sum(x)/N )^2   )

It can be known that the mean and variance of the data set can be calculated with only one traversal.

import os
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from scipy.misc import imread

startt = 5000
CNum = 1000   # 挑选多少图片进行计算
R_channel = 0
G_channel = 0
B_channel = 0
R_channel_square = 0
G_channel_square = 0
B_channel_square = 0
pixels_num = 0

imgs = []
for i in range(startt, startt+CNum):
    img = imread(os.path.join(root_path, filename[i]))
    h, w, _ = img.shape
    pixels_num += h*w       # 统计单个通道的像素数量

    R_temp = img[:, :, 0]
    R_channel += np.sum(R_temp)
    R_channel_square += np.sum(np.power(R_temp, 2.0))
    G_temp = img[:, :, 1]
    G_channel += np.sum(G_temp)
    G_channel_square += np.sum(np.power(G_temp, 2.0))
    B_temp = img[:, :, 2]
    B_channel = B_channel + np.sum(B_temp)
    B_channel_square += np.sum(np.power(B_temp, 2.0))

R_mean = R_channel / pixels_num
G_mean = G_channel / pixels_num
B_mean = B_channel / pixels_num

"""   
S^2
= sum((x-x')^2 )/N = sum(x^2+x'^2-2xx')/N
= {sum(x^2) + sum(x'^2) - 2x'*sum(x) }/N
= {sum(x^2) + N*(x'^2) - 2x'*(N*x') }/N
= {sum(x^2) - N*(x'^2) }/N
= sum(x^2)/N - x'^2
"""

R_std = np.sqrt(R_channel_square/pixels_num - R_mean*R_mean)
G_std = np.sqrt(G_channel_square/pixels_num - G_mean*G_mean)
B_std = np.sqrt(B_channel_square/pixels_num - B_mean*B_mean)

print("R_mean is %f, G_mean is %f, B_mean is %f" % (R_mean, G_mean, B_mean))
print("R_std is %f, G_std is %f, B_std is %f" % (R_std, G_std, B_std))

  

Reprinted in: https://www.cnblogs.com/liugl7/p/10874958.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326490377&siteId=291194637