计算图像数据集RGB各通道的均值和方差

时间:2024-10-09 11:27:19

第一种写法,先读进来,再计算。比较耗内存。

  1. import cv2
  2. import numpy as np
  3. import torch
  4. startt = 700
  5. CNum = 100 # 挑选多少图片进行计算
  6. imgs=[]
  7. for i in range(startt, startt+CNum):
  8. img_path = (root_path, filename[i])
  9. img = (img_path)
  10. img = img[:, :, :, ]
  11. ((img))
  12. torch_imgs = (imgs, dim=3)
  13. means, stdevs = [], []
  14. for i in range(3):
  15. pixels = torch_imgs[:, :, i, :] # 拉成一行
  16. ((pixels))
  17. ((pixels))
  18. # cv2 读取的图像格式为BGR,PIL/Skimage读取到的都是RGB不用转
  19. () # BGR --> RGB
  20. ()
  21. print("normMean = {}".format(means))
  22. print("normStd = {}".format(stdevs))

第二种写法,读一张算一张,比较耗时:先过一遍计算出均值,再过一遍计算出方差。

  1. import os
  2. from PIL import Image
  3. import as plt
  4. import numpy as np
  5. from import imread
  6. startt = 4000
  7. CNum = 1000 # 挑选多少图片进行计算
  8. num = 1000 * 3200 * 1800 # 这里(3200,1800)是每幅图片的大小,所有图片尺寸都一样
  9. imgs=[]
  10. R_channel = 0
  11. G_channel = 0
  12. B_channel = 0
  13. for i in range(startt, startt+CNum):
  14. img = imread((root_path, filename[i]))
  15. R_channel = R_channel + np.sum(img[:, :, 0])
  16. G_channel = G_channel + np.sum(img[:, :, 1])
  17. B_channel = B_channel + np.sum(img[:, :, 2])
  18. R_mean = R_channel / num
  19. G_mean = G_channel / num
  20. B_mean = B_channel / num
  21. R_channel = 0
  22. G_channel = 0
  23. B_channel = 0
  24. for i in range(startt, startt+CNum):
  25. img = imread((root_path, filename[i]))
  26. R_channel = R_channel + np.sum((img[:, :, 0]-R_mean, 2) )
  27. G_channel = G_channel + np.sum((img[:, :, 1]-G_mean, 2) )
  28. B_channel = B_channel + np.sum((img[:, :, 2]-B_mean, 2) )
  29. R_std = (R_channel/num)
  30. G_std = (G_channel/num)
  31. B_std = (B_channel/num)
  32. # R:65.045966 G:70.3931815 B:78.0636285
  33. print("R_mean is %f, G_mean is %f, B_mean is %f" % (R_mean, G_mean, B_mean))
  34. print("R_std is %f, G_std is %f, B_std is %f" % (R_std, G_std, B_std))

第三种写法,只需要遍历一次:在一轮循环中计算出x,x^2;  然后x'=sum(x)/N ,又有sum(x^2),根据下式:

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   )

可以知道,只需要经过一次遍历,就可以计算出数据集的均值和方差。

  1. import os
  2. from PIL import Image
  3. import as plt
  4. import numpy as np
  5. from import imread
  6. startt = 5000
  7. CNum = 1000 # 挑选多少图片进行计算
  8. R_channel = 0
  9. G_channel = 0
  10. B_channel = 0
  11. R_channel_square = 0
  12. G_channel_square = 0
  13. B_channel_square = 0
  14. pixels_num = 0
  15. imgs = []
  16. for i in range(startt, startt+CNum):
  17. img = imread((root_path, filename[i]))
  18. h, w, _ =
  19. pixels_num += h*w # 统计单个通道的像素数量
  20. R_temp = img[:, :, 0]
  21. R_channel += np.sum(R_temp)
  22. R_channel_square += np.sum((R_temp, 2.0))
  23. G_temp = img[:, :, 1]
  24. G_channel += np.sum(G_temp)
  25. G_channel_square += np.sum((G_temp, 2.0))
  26. B_temp = img[:, :, 2]
  27. B_channel = B_channel + np.sum(B_temp)
  28. B_channel_square += np.sum((B_temp, 2.0))
  29. R_mean = R_channel / pixels_num
  30. G_mean = G_channel / pixels_num
  31. B_mean = B_channel / pixels_num
  32. """
  33. S^2
  34. = sum((x-x')^2 )/N = sum(x^2+x'^2-2xx')/N
  35. = {sum(x^2) + sum(x'^2) - 2x'*sum(x) }/N
  36. = {sum(x^2) + N*(x'^2) - 2x'*(N*x') }/N
  37. = {sum(x^2) - N*(x'^2) }/N
  38. = sum(x^2)/N - x'^2
  39. """
  40. R_std = (R_channel_square/pixels_num - R_mean*R_mean)
  41. G_std = (G_channel_square/pixels_num - G_mean*G_mean)
  42. B_std = (B_channel_square/pixels_num - B_mean*B_mean)
  43. print("R_mean is %f, G_mean is %f, B_mean is %f" % (R_mean, G_mean, B_mean))
  44. print("R_std is %f, G_std is %f, B_std is %f" % (R_std, G_std, B_std))