【MXNet学习11】opencv实现mxnet均值归一化

    科技2022-07-13  110

    1、均值归一化

    在一般的图像预处理过程中都会对图像进行减去mean,除以std操作。

    需要注意的是:一定要用训练集计算出均值和方差,否则违背了深度学习的原则(即模型训练仅能从训练数据中获取信息)。对于得到的mean值,训练集、验证集和测试集都要分别减去均值。

    2、为什么要均值归一化

    在计算机视觉领域中,一定免不了的就是图像预处理中的 逐个样本减去mean值的过程,那么为什么一定要做这一步呢? 其主要的原因就是,对于自然图像,其是一种平稳的数据分布【即图像的每一维都服从相同的分布】。所以通过减去数据对应维度的统计平均值,来消除公共的部分,以凸显个体之间的特征和差异。下面就用一个图来直观的表示一下: 可以看到减去均值后的图b,天空的纹理被消除了,凸显出了图片中的车和高楼等主要特征

    3、计算均值与方差

    # 首先,你需要安装numpy和opencv模块。 # opencv 可以通过下面的命令来直接安装。 pip install opencv-python import os import numpy as np import cv2 # 该代码,只需修改文件路径即可。 # 这个是你图片的根目录,注意不要带中文路径,楼主就因为这个调试了很久。 image_path = '/train/image' file_names = os.listdir(image_path) count = 0 mean = np.zeros(3, np.int64) for i in file_names[1:]: print(i) img = cv2.imread(image_path + '/' + i) #print(img) count += 1 mean += np.sum(img, axis=(0, 1)).astype(int) h, w = img.shape[0:-1] print(h, w, count) means = mean / (1.0 * h * w * count) print('b, g, r = ', means)

    参考:https://blog.csdn.net/qq_19329785/article/details/84569604

    4、计算完均值之后,如何让测试集,训练集,验证集分别减去均值,除以方差

    GPU上面的环境变化太复杂,这里直接给出在笔记本的CPU上面运行的时间结果。由于方式3需要将tensor转换到GPU上面,这一过程很消耗时间,大概需要十秒,故而果断抛弃这样的做法。

    img (168, 300, 3) # 图像大小 sub div in numpy,time 0.0110 # 方式一 sub div in torch.tensor,time 0.0070 # 方式二 sub div in torch.tensor with torchvision.transforms,time 0.0050 # 方式四 tensor1=tensor2 tensor2=tensor3 img (1079, 1349, 3) # 图像大小 sub div in numpy,time 0.1899 # 方式一 sub div in torch.tensor,time 0.1469 # 方式二 sub div in torch.tensor with torchvision.transforms,time 0.1109 # 方式四 tensor1=tensor2 tensor2=tensor3 耗时最久的是numpy(方式一),其次是转换成torch.tensor(方式二),最快的是直接使用torchvision.transforms(方式三)。现在在GPU上面跑的程序,GPU的利用率特别低(大多数时间维持在2%左右,只有很少数的时间超过80%),设置打印点调试程序时发现,getitem()输出一张图像的时间在0.1秒的数量级,这对于GPU而言是非常慢的,因为GPU计算速度很快,CPU加载图像和预处理图像的速度赶不上GPU的计算速度,就会导致显卡大量时间处于空闲状态。经过对图像I/O部分代码的定位,发现是使用numpy减去图像均值除以方差这一操作浪费了太多时间,而且输入图像的分辨率越大,所消耗的时间就会更多,原则上,图像预处理每个阶段的时间需要维持在0.01秒的数量级。 import numpy as np import time import torch import torchvision.transforms as transforms import cv2 # 该部分代码的作用:输入的是文件路径,输出的是转换成torch.tensor的标准形式 img_path='F:\\2\\00004.jpg' PIXEL_MEANS =(0.485, 0.456, 0.406) #RGB format mean and variances PIXEL_STDS = (0.229, 0.224, 0.225)

    #输入文件路径,输出的应该是转换成torch.tensor的标准形式

    4.1、方式一 :在numpy中进行减去均值除以方差,最后转换成torch.tensor

    one_start=time.time()

    img=cv2.imread(img_path) img=img[:,:,::-1] img=img.astype(np.float32, copy=False) img/=255.0 img-=np.array(PIXEL_MEANS) img/=np.array(PIXEL_STDS) tensor1=torch.from_numpy(img.copy()) tensor1=tensor1.permute(2,0,1) one_end=time.time() print('sub div in numpy,time {:.4f}'.format(one_end-one_start)) del img

    4.2、方式二 :转换成torch.tensor,再减去均值除以方差

    two_start=time.time() img=cv2.imread(img_path) img=img[:,:,::-1] print('img',img.shape,np.min(img),np.min(img)) tensor2=torch.from_numpy(img.copy()).float() tensor2/=255.0 tensor2-=torch.tensor(PIXEL_MEANS) tensor2/=torch.tensor(PIXEL_STDS) tensor2=tensor2.permute(2,0,1) two_end=time.time() print('sub div in torch.tensor,time {:.4f}'.format(two_end-two_start)) del img

    4.3、方式三 :转换成torch.tensor,再放到GPU上面,最后减去均值除以方差

    # three_start=time.time() # img=cv2.imread(img_path) # img=img[:,:,::-1] # tensor3=torch.from_numpy(img.copy()).cuda().float() # tensor3-=torch.tensor(PIXEL_MEANS).cuda() # tensor3/=torch.tensor(PIXEL_STDS).cuda() # three_end=time.time() # print('sub div in torch.tensor on cuda,time {:.4f}'.format(three_end-three_start)) # del img

    4.4、方式四:转换成torch.tensor,使用transform方法减去均值除以方差

    four_start=time.time() img=cv2.imread(img_path) img=img[:,:,::-1] transform=transforms.Compose( [transforms.ToTensor(),transforms.Normalize(PIXEL_MEANS, PIXEL_STDS)] ) tensor4=transform(img.copy()) four_end=time.time() print('sub div in torch.tensor with torchvision.transforms,time {:.4f}'.format(four_end-four_start)) del img if torch.sum(tensor1-tensor2)<=1e-3: print('tensor1=tensor2') if torch.sum(tensor2-tensor4)==0: print('tensor2=tensor3') # if tensor3==tensor4: # print('tensor3=tensor4')

    https://blog.csdn.net/WYXHAHAHA123/article/details/87924745

    5、opencv 实现mxnet/pytorch 图像均值归一化

    https://blog.csdn.net/yangshaokangrushi/article/details/103279739

    Processed: 0.011, SQL: 8