Home  >  Article  >  Backend Development  >  How to use Python to modify image size in batches and unify the size?

How to use Python to modify image size in batches and unify the size?

WBOY
WBOYforward
2023-04-22 14:07:082354browse

    Batch change image size to uniform size

    import os
    from PIL import Image
    import glob
    def convertjpg(jpgfile,outdir,width=200,height=500):
        img=Image.open(jpgfile)
        new_img=img.resize((width,height),Image.BILINEAR)   
        new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
    
    for jpgfile in glob.glob(('/home/yangguide/Videos/images/*.png')):
        convertjpg(jpgfile,"/home/yangguide/Videos/image_2")

    Knowledge points

    Image library PIL (Python Image Library) is a third-party image of python processing library, but due to its powerful functions and large number of users, it is almost considered the official image processing library of python.

    The Image class is the core class in PIL. You have many ways to initialize it, such as loading an image from a file, processing other forms of images, or creating an image from scratch.

    The basic methods of Image module operations are included in this module. Such as open, save, convert, show... and other methods.

    1. To load the image, use the open() function of the Image class:

    Image.open(jpgfile)

    2. To save the image, use the save() function of the Image class:

    new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))

    3.os.path.basename() method:

    Returns the last file name of path. If path ends with ’/', then will return a null value, which is the second element of os.path.split(path).

    Example:

    >>> import os
    >>> path = '/Users/beazley/Data/data.csv'
    >>> os.path.basename(path) #Get the last component of the path
    'data.csv'

    4.img.resize((width,height),Image.BILINEAR):

    Use the resize function to specify the image Size and quality, the setting and meaning of the second parameter are as follows:


    How to use Python to modify image size in batches and unify the size?

    ##5. Usage of glob.glob() and glob.iglob() :

    glob.glob() can obtain all matching paths at the same time, while glob.iglob() can only obtain one matching path at a time.

    Scale images and xml tags of different sizes to the same size, and rename the storage

    Share a more practical function, just change the file path and zoom size to adapt it to your own .

    It is suitable for pictures that are originally different sizes and cannot be scaled uniformly. They can only be placed on a canvas of a uniform size.

    If the original image sizes are the same, please refer to my other blog to find it yourself.

    Running environment: python3.5

    You need to install opencv. If you have anaconda, execute

    conda install opencv-python

    # *_* coding : UTF-8 *_*
    # 开发人员   :csu·pan-_-||
    # 开发时间   :2020/11/09 16:40
    # 文件名称   :renameFile.py
    # 开发工具   :PyCharm
    # 功能描述   :将文件夹下的图片全部缩放,裁减,并按新文件名存储
    
    import os
    import cv2
    
    path = 'E:/Projects/images'        # 原文件夹路径
    newpath = 'E:/Projects/newimages'  # 新文件夹路径
    files = os.listdir(path)           # 获取文件名列表
    for i, file in enumerate(files):   # 展开文件名的列表和索引
        if file.endswith('.jpg'):
            imgName = os.path.join(path, file)      # 获取文件完整路径
            img = cv2.imread(imgName)                 # 读图
            imgNew = cv2.resize(img, (1200, 1200))  # 缩放
            # imgNew = imgNew[60:552,:]             # 截取一部分区域
            newName = os.path.join(newpath, 'img_%03d'%(0+i)+'.jpg')  # 设置新的文件名
            print(newName)
            cv2.imwrite(newName,imgNew)             # 存储按新文件名命令的图片

    News will come later As a programmer, needs must always be met. While scaling, it is necessary to maintain the original proportions and set everything to a completely black canvas of 800 * 800, which is a zero-fill operation and readjust the code. The core part is to determine whether the long side of the image is greater than 800 and greater than If it is 800, the ratio of 800 to the long side will be set as the scaling ratio. If it is less than 800, the size of the original image will remain unchanged. A new library numpy needs to be imported,

    conda install numpy: The xml file marked with

    # *_* coding : UTF-8 *_*
    # 开发人员   :csu·pan-_-||
    # 开发时间   :2020/11/09 18:15
    # 文件名称   :renameFile.py
    # 开发工具   :PyCharm
    # 功能描述   :将文件夹下的图片全部缩放(同时保持原有宽高比例),裁切,并按新文件名存储
    
    import os
    import cv2
    import numpy as np
    
    path = r'E:\Projects\images'          # 原文件夹路径
    newpath = r'E:\Projects\newimages'    # 新文件夹路径
    files = os.listdir(path)              # 获取文件名列表
    c_w ,c_h = 800,800                    # 全黑画布的大小
    
    for i, file in enumerate(files):
        img_zeros = np.zeros((c_w, c_h, 3), np.uint8) # 创建全黑的图像
        if file.endswith('.jpg'):
            imgName = os.path.join(path, file)        # 获取文件完整路径
            img = cv2.imread(imgName)                 # 读图
            h, w , _ = img.shape                      # 获取图像宽高
            # 缩放图像,宽高大于800的按长边等比例缩放,小于800的保持原图像大小:
            if max(w,h) > c_w:
                ratio = c_w / max(w,h)
                imgcrop = cv2.resize(img, (round(w * ratio) , round(h * ratio)))
                # 将裁切后的图像复制进全黑图像里
                img_zeros[0:round(h * ratio), 0:round(w * ratio)] = imgcrop
            else:
                img_zeros[0:h, 0:w] = img
            # imgNew = imgNew[60:552,:]               # 截取一部分
            # 设置新的文件名:
            newName = os.path.join(newpath, 'img_%03d'%(0+i)+'.jpg')
            print(newName)
            cv2.imwrite(newName,img_zeros)            # 存储按新文件名命令的图片

    needs to be modified simultaneously, so the code is adjusted:


    # *_* coding : UTF-8 *_*
    # 开发人员   :csu·pan-_-||
    # 开发时间   :2020/11/09 18:15
    # 文件名称   :renameFile.py
    # 开发工具   :PyCharm
    # 功能描述   :将文件夹下的图片全部缩放(同时保持原有宽高比例),裁切,并按新文件名存储
    #             同时调整xml里的坐标信息
    
    import os
    import cv2
    import numpy as np
    import xml.etree.ElementTree as ET
    
    path = r'C:\Users\Administrator\Desktop\test'          # 原文件夹路径
    newpath = r'C:\Users\Administrator\Desktop\newtest'    # 新文件夹路径
    c_w ,c_h = 800,800                    # 全黑画布的大小
    
    def edit_xml(xml_file,ratio,i):
        """
        修改xml文件
        :param xml_file:xml文件的路径
        :return:
        """
        all_xml_file = os.path.join(path, xml_file)
        tree = ET.parse(all_xml_file)
        objs = tree.findall('object')
        for ix, obj in enumerate(objs):
            type = obj.find('type').text
            if type == 'bndbox':
                obj_bnd = obj.find('bndbox')
                obj_xmin = obj_bnd.find('xmin')
                obj_ymin = obj_bnd.find('ymin')
                obj_xmax = obj_bnd.find('xmax')
                obj_ymax = obj_bnd.find('ymax')
                xmin = float(obj_xmin.text)
                ymin = float(obj_ymin.text)
                xmax = float(obj_xmax.text)
                ymax = float(obj_ymax.text)
                obj_xmin.text = str(round(xmin * ratio))
                obj_ymin.text = str(round(ymin * ratio))
                obj_xmax.text = str(round(xmax * ratio))
                obj_ymax.text = str(round(ymax * ratio))
    
            elif type == 'robndbox':
                obj_bnd = obj.find('robndbox')
                obj_cx = obj_bnd.find('cx')
                obj_cy = obj_bnd.find('cy')
                obj_w = obj_bnd.find('w')
                obj_h = obj_bnd.find('h')
                obj_angle = obj_bnd.find('angle')
                cx = float(obj_cx.text)
                cy = float(obj_cy.text)
                w = float(obj_w.text)
                h = float(obj_h.text)
                obj_cx.text = str(cx * ratio)
                obj_cy.text = str(cy * ratio)
                obj_w.text = str(w * ratio)
                obj_h.text = str(h * ratio)
    
        newfile = os.path.join(newpath, '%05d'%(0+i)+'.xml')
        tree.write(newfile, method='xml', encoding='utf-8')  # 更新xml文件
    
    if __name__ == '__main__':
        files = os.listdir(path)              # 获取文件名列表
        for i, file in enumerate(files):
            img_zeros = np.zeros((c_w, c_h, 3), np.uint8)  # 创建全黑的图像
            if file.endswith('.jpg'):
                imgName = os.path.join(path, file)         # 获取文件完整路径
                xml_file = file.replace('.jpg','.xml')
                img = cv2.imread(imgName)                  # 读图
                h, w , _ = img.shape                       # 获取图像宽高
                # 缩放图像,宽高大于800的按长边等比例缩放,小于800的保持原图像大小:
                if max(w,h) > c_w:
                    ratio = c_w / max(w,h)
                    imgcrop = cv2.resize(img, (round(w * ratio) , round(h * ratio)))
                    # 将裁切后的图像复制进全黑图像里
                    img_zeros[0:round(h * ratio), 0:round(w * ratio)] = imgcrop
                    edit_xml(xml_file, ratio, i)
                else:
                    img_zeros[0:h, 0:w] = img
                    edit_xml(xml_file, 1, i)
    
                # 设置新的文件名:
                newName = os.path.join(newpath, '%05d'%(0+i)+'.jpg')
                print(newName)
                cv2.imwrite(newName,img_zeros)            # 存储按新文件名命令的图片

    The above is the detailed content of How to use Python to modify image size in batches and unify the size?. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete