使用python查看图片数据

使用python查看图像数据

在学习图像分割前,发现对如何查看图像数据完全不熟悉,在查看了Fast.ai框架的源码后,本文记录了在图像数据为Tensor类型的情况下,显示图像数据的过程。

参考资料:fast.ai源码

1. 查看文件路径

本篇使用了CAMVID数据集,下载后文件目录结构如下所示:
在这里插入图片描述
以images为例,打开该文件夹后,有701张图片
在这里插入图片描述

有了图片路径,可以将所有图片的绝对路径存为一个list,如下所示:

def getImageFiles(path:str):
    "递归地查找图片文件"
    result = []
    for rootDir, Dir, files in os.walk(path):
        for file in files:
            if '.png' in file or '.jpg' in file:
                result.append(Path(path)/file)
        break
    return result
img_path = 'C:/Users/ASUS/.fastai/data/camvid/images' #文件上级目录
imageFilesPath = getImageFiles(img_path)

此处rootDir代表文件夹路径,Dir代表下一级文件夹路径(如果在rootDir里之前创建过某个文件夹A,此处会保存A的路径字符串),这两个变量目前没啥用,files保存了rootDir下的所有文件的路径列表。
第二个loop用来做一个简单粗暴的过滤,过滤掉不是.PNG,.JPG格式的文件,并把.PNG,.JPG文件路径全部放入一个result列表里并return。

可以输出imageFilesPath[0]查看结果,如下所示:

WindowsPath('C:/Users/ASUS/.fastai/data/camvid/images/0001TP_006690.png')

标签图片文件在labels文件夹中,发现图片名有规律可循,如labels 中图片名字比images文件名字多一个‘_P’, 所以可以继续用上面的方式得到labels文件路径,也可以通过fast.ai教程里lambda来将图片文件名转换为标签图片名。


getLblPath = lambda x : path_lbl/f'{x:stem}'_P'{x.suffix}'
#测试用例
lbl_name = getLblPath(imageFilesPath[0])
imageFilesPath[0], lbl_name

运行结果为:

 WindowsPath('C:/Users/ASUS/.fastai/data/camvid/images/0001TP_006690.png'),
(WindowsPath('C:/Users/ASUS/.fastai/data/camvid/labels/0001TP_006690_P.png'))
2. 显示图片
2.1 读取图片

数据集,标签路径已知后,就可以显示图片了,这里参考fastai源码,在显示图片的同时,return torch的tensor类型数据,将第3维度转为第1维度,如下所示:

def openImage(path:Path, figsize:tuple = (3, 3)):
    img = PIL.Image.open(path).convert('RGB')
    img = Tensor(np.array(img))
    img = pil2tensor(img, np.float32)
    img = img/255
    return img

这里使用PIL库来加载一个图片数据,并转为Tensor数据,最后返回这个数据。

2.2 读取标签图片

首先读取标签图片,但标签图片是2维的,为了和数据图片匹配,要扩展一个维度,并将第三个维度转到第一个维度上,再返回成Tensor,如下所示

def openMask(path:Path):
    img = PIL.Image.open(path).convert('L')#灰度图像模式
    img = pil2tensor(img, np.float32)
    return img
def pil2tensor(image:np.ndarray,dtype:np.dtype):
    "Convert PIL style `image` array to torch style image tensor."
    a = np.asarray(image)
    print(a.shape)
    if a.ndim==2 : a = np.expand_dims(a,2)
    a = np.transpose(a, (1, 0, 2))
    a = np.transpose(a, (2, 1, 0))
    return torch.from_numpy(a.astype(dtype, copy=False) )
#测试用例
mask = openMask(get_y_fn(imageFilesPath[10]))
image = openImage(imageFilesPath[10])#openImage会返回浮点 torch.Size([720, 960, 3])
mask.shape, image.shape

运行结果如下所示:

torch.Size([1, 720, 960])
torch.Size([3, 720, 960])
2.3 显示图片

如果是普通的三通道图片(RGB等)可以用imshow方法输入numpy数据来显示图片,将一维度和三维度转换(如[3, 720, 960]->[720, 960, 3]),但是标签数据只有一个通道,所以额外转换成二维的numpy输入([1, 720, 960]->[720, 960, 1]->[720, 960]),再显示图片。代码如下所示(参考fast.ai 源码):

def ifnone(a:Any,b:Any)->Any:
    return b if a is None else a
def image2np(image:Tensor)->np.ndarray:
    "Convert from torch style `image` to numpy/matplotlib style."
    res = image.cpu().permute(1,2,0).numpy()#此处作用是调换原有维度位置
    return res[...,0] if res.shape[2]==1 else res #抽取最后一个维度的第0个数据

def show(img:Tensor, figsize:tuple=(3, 3), title:Optional[str]=None, hide_axis:bool=True,
        cmap:str=None, alpha:float=None):
    cmap = ifnone(cmap, 'viridis')
    fig, ax = plt.subplots(figsize=figsize)
    xtr = dict(cmap=cmap, alpha=alpha)
    ax.imshow(image2np(img.data), **xtr)
    if hide_axis: ax.axis('off')
    return ax
    if title is not None: ax.set_title(title)

将mask 和 image 都作为show方法的输入,可以显示如下结果:
在这里插入图片描述
以上就是显示图片的方法。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值