项目场景:
最近做语义分割相关的任务,不可避免地对数据进行一系列地处理,期间遇到多个错误。在此记录一下,一方面总结错误、积累经验;一方面做个笔记防止此类错误再次发生。
问题描述
主要遇到的问题有:
问题1、图像经backbone处理后的特征类型转换,具体为张量、数组、通道之间的转换;
问题2、图像格式转换,具体为RGB、灰度图、二值图等转换;
问题3、图像的特征图中不同像素值个数计算。
解决方案:
针对问题1:深度学习框架下图片输入到网络模型中以张量(Tensor)的形式进行计算,因此需要数组(ndarray)转张量的操作。pytorch中的操作为:
import torch import numpy as np xxx = torch.from_numpy(ndarray) # ndarray表示数组特征,"xxx"表示接受转变后的张量 xxx = Tensor.array() #把张量转换为数组的形式 xxx = Tensor.numpy() #把张量转换为数组的形式 #--------特征通道相关的转换------------# # 假设image张量特征图大小为[c, h, w] xxx = np.transpose(image.numpy(), (0,1,2)) # 把张量转为数组,shape不变,为[c, h, w] xxx = np.transpose(image.numpy(), (1,2,0)) # 把张量转为数组,shape变为[h, w, c] xxx = np.transpose(image.numpy(), (2,0,1)) # 把张量转为数组,shape变为[w, c, h] xxx = np.transpose(image.numpy(), (2,1,0)) # 把张量转为数组,shape变为[w, h, c] xxx = np.transpose(image.numpy(), (0,2,1)) # 把张量转为数组,shape变为[c, w, h] xxx = np.transpose(image.numpy(), (1,0,2)) # 把张量转为数组,shape变为[h, c, w]
针对问题2:图像转数组与数组转图像的函数如下:
import cv2 from PIL import Image #假设灰度图片名为image,计算各像素值个数并以字典格式返回打印 img = cv2.imread(r"path\name.png", 0) #Assuming the image is stored in a numpy array #Get the unique pixel values unique_pixels = np.unique(pic) #Loop through each pixel value and count its occurrence in the image pixel_counts = {} for pix in unique_pixels: pixel_counts[pix] = np.sum(pic == pix) #Print out the counts of each pixel value print("各像素值的个数:", pixel_counts) # 图片转数组 image = image.array() # 数组转图片 image = Image.fromarray(np.uint8(image)) # 此处用到PIL库中的Image函数,注意这里大写I # 转为灰度图 ,或者直接读取为灰度图格式 image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = cv2.imread('name.jpg', cv2.IMREAD_GRAYSCALE)
针对问题3:计算张量中的各像素值个数,首先把张量转为数组形式,然后遍历计数各像素值个数。例如二值图大小为[c,h,w]
import torch import numpy as np image = np.transpose(image.numpy(), (1,2,0)) # 此操作后image转换为数组,大小为[h,w,c] h, w, _ = image.shape # 获取图像的长和宽,便于遍历操作 a = 0 b = 0 # 假设图像只有a和b两种像素值 for row in range(h): for col in range(w): pix_value = image[row, col] if pix_value == 0: a = a+1 else: b = b+1 print('像素值a的个数:', a) print('像素值b的个数:', b)
总结:对pytorch框架中的很多函数都不了解,遇到问题的时候第一时间想的是自己编写函数。但是在编写过程种遇到很多问题,而且有些函数很容易地实现某些功能,所以还是要多看、多试、多积累。