查看原文
其他

【Python进阶】实战Python图形文件操作基本编程

汤兴旺 有三AI 2020-09-08

欢迎来到专栏《Python进阶》。在这个专栏中,我们会讲述Python的各种进阶操作,包括Python对文件、数据的处理,Python各种好用的库如NumPy、Scipy、Matplotlib、Pandas的使用等等。我们的初心就是带大家更好的掌握Python这门语言,让它能为我所用。


今天是《Python进阶》专栏的第二期,在本期中,我们将主要介绍如何利用Python对图像文件进行一些处理。


作者&编辑 | 汤兴旺


我们应该都明白数据处理对于CV来说至关重要,今天我们不说数据增强等高大上的操作,我们来聊聊当我们拿到图片数据时如何对图片数据进行整理,如更改图片文件格式和文件名等等。


1 遍历图片文件/文件夹

当提到文件/文件夹遍历时我们就不得不提python中的os.walk这个简单易用的文件、目录遍历器。它可以帮助我们高效的处理文件、目录方面的事情。话不多说,我们直接看代码和具体用法。


现在我们有如下的文件结构:

我们看看如何通过os.walk来遍历上面的这些图片按和目录。

import os
rootDir = r"D:\file\kobe"
for root, dirs, files in os.walk(rootDir):

通过上面代码如果我们输出root即print(root),会得到下面的结果。

D:\file\kobe

D:\file\kobe\a

D:\file\kobe\b

D:\file\kobe\b\c

我们对照的看下输出结果和文件结构,应该明白了root实际上就是各个目录(文件夹)的路径,当然这里是包括顶级目录的,如我们这里的kobe文件夹。


我们再看看输出dirs后的结果。

['a', 'b']

[]

['c']

[]

['a','b']实际上是root中第一个路径(D:\file\kobe)中包含的文件夹,即kobe文件夹中的文件夹。第二行的输出[]和第四行的输出[]依次就是a文件夹和c文件夹中的包含的文件夹。由于a和c中都没有文件夹,所以输出都是[],第三行的['c']实际上是root中第三个路径(D:\file\kobe\b)中包含的文件夹c文件夹。综上分析我们知道dirs实际上就是root中的各个文件夹。


最后我们再看看files,顾名思义,这个files的输出就是各个文件了,如下:

['kobe1.jpg', 'kobe2.jpg', 'kobe3.jpg', 'kobe4.jpg']

['kobe5.jpg']

[]

[]

参照root的输出结果,上面的输出依次就是kobe文件夹中的文件、a文件夹中的文件、b文件夹中的文件和c文件夹的文件。


通过上面的介绍,我相信你已经明白了os.walk的具体用法和使用Python来遍历图片文件/文件夹了。


2 更改文件名字和格式

现在我们有个kobe文件夹,里面图片如下:

现在我们需要将这五张图片统一更改名称和格式,更改后的格式如下KOBE_i.jpg,其中i为1-5。

import os
rootDir = r"D:\file\kobe"
i = 1
for root, dirs, files in os.walk(rootDir):
    for f in files:
        srcname = os.path.join(root, f)
        srcformat = srcname.split('.')[-1]
        if srcformat is not "png":
            new_item = "KOBE"+str(i)+ '.png'
            os.rename(srcname, os.path.join(rootDir, new_item))
            i+=1

现在我们分析下上面的代码。通过1.1的讲解我相信你应该知道root,dirs和files这三个变量里面的内容了。那么srcname即os.path.join(root,f)又是什么呢?我先输出下secname。结果如下:

D:\file\kobe\KOBE_1.png

D:\file\kobe\KOBE_2.png

D:\file\kobe\KOBE_3.png

D:\file\kobe\KOBE_4.png

D:\file\kobe\KOBE_5.png

很显然,srcname就是每个图片文件的名字。而root=D:\file\kobe,files=['KOBE_1.png', 'KOBE_2.png', 'KOBE_3.png', 'KOBE_4.png', 'KOBE_5.png']。相信你应该知道os.path.join()的作用了,它实际上就是将join()里面参数拼接成一个完整的路径。


3 将图片路径输出到文本文件中

话不多说,我们直接上代码,如下:

import os
rootDir = r"D:\file\kobe"
i = 1
ftxtfile = open(r"D:\file\a.txt",'w')
for root, dirs, files in os.walk(rootDir):
   print(root)
   print(files)
   for f in files:
        srcname = os.path.join(root, f)
        srcformat = srcname.split('.')[-1]
        if srcformat is not "png":
            new_item = "KOBE_"+str(i) + '.png'
            newname = os.rename(srcname, os.path.join(rootDir, new_item))
  ftxtfile.write(os.path.join(rootDir, new_item )+ '\n')
            i+=1

我们通过上面的代码就可以将图片路径输出到.txt文件中。其实很简单,首先通过open()打开txt文件,然后通过write()将需要写入的内容写进去就行了。下面就是写入后的结果:

4 批量复制图片文件

现在按照第三节中得到的txt文件中的内容将图片复制到另外一个文件夹中(D:\file\file\a),代码如下:

import shutil


def objFileName():
   local_file_name_list = r'D:\file\a.txt'
   # 指定名单
   obj_name_list = []
   for i in open(local_file_name_list, 'r'):

       obj_name_list.append(i.replace('\n', ''))
 print(obj_name_list)
   return obj_name_list
def copy_img():
   local_img_name = r"D:\file\kobe"
   path = r"D:\file\file\a"
   # 指定存放图片的目录
   for i in objFileName():
       print(i)
       shutil.copy(i, path )
if __name__ == '__main__':
   copy_img()

在这个代码中我们主要用到了shutil.copy()这个函数,它的具体用法如下:

shutil.copy(source, destination) ,其中source/destination 都是字符串形式的路径,source是原文件或者原文件夹的路径。destination是目标文件或者目标文件夹的路径 。


另外在这个代码中我们定义了一个函数objFileName(),它的作用是将.txt文件中的图像路径转化成一个list。你可以像上面代码的加粗部分那样进行验证。会得到如下结果。

['D:\\file\\kobe\\KOBE_1.png', 'D:\\file\\kobe\\KOBE_2.png', 'D:\\file\\kobe\\KOBE_3.png', 'D:\\file\\kobe\\KOBE_4.png', 'D:\\file\\kobe\\KOBE_5.png']

5 批量更改图片文件尺寸

我们知道通常训练网络结构模型的时候,图像的输入大小需要保持一个定值,如224X224等。下面这个代码就可以批量改变图片大小到指定尺寸。

from PIL import Image
import os.path
import glob

def convertpng(pngfile, outdir, width=48, height=48):
   img = Image.open(pngfile)
   try:
       basename = os.path.basename(pngfile)
       filename = os.path.splitext(basename)[0]
       filetype = os.path.splitext(basename)[1]  # 文件扩展名
       new_img = img.resize((width, height), Image.BILINEAR)
       new_img.save(os.path.join(outdir, filename+"_"+str(width)+"x"+str(height)+filetype))
   except Exception as e:
       print(e)
for pngfile in glob.glob(r"D:\file\kobe"+"/*.png"):
   convertpng(pngfile , r"D:\file\file\b",224,224)

更改图片大小前的样式如下:

我们先看下代码运行后的结果,如下:

上面的代码我们主要定义了一个将图片大小resize到指定大小的convertpng函数,这个函数总共有四个参数,分别是pngfile,outdir和图像需要更改的宽度和高度。其中pngfile就是需要更改大小的图片文件,outdir是图片更改大小后的保存路径。

总结


本期我们介绍了如何使用Python对文件进行处理,希望它对你在图像数据处理方面有些帮助。


下期预告:Python库NumPy的高级应用


有三AI编程微信公众号《三人行ToCode》

有三AI编程方面的微信公众号《三人行ToCode》创建了,欢迎加入,希望大家能借助这个平台,扎实自己的编程基础。


转载文章请后台联系

侵权必究

往期精选



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存