1 libpng warning: iccp: known incorrect srgb profile

今天在微调模型进行训练时,我的微调数据中有png数据,在数据加载每次读取png图片时都会报libpng warning: iccp: known incorrect srgb profile的warning,非常影响正常查看训练时的loss情况。

这个原因主要是因为libpng-1.6以上版本增强了ICC profiles检查,所以发出警告。此警告可以忽略,若要消除警告则要从原图像中去掉ICCP chunk。

所以我写了以下代码去除png图片的icc信息,

import shutil
from PIL import Image

def remove_image_icc_profile_info(input_image_path, output_image_path):
    if not os.path.exists(input_image_path):
        raise FileNotFoundError(f'{input_image_path} is not exist')

    with Image.open(input_image_path) as img:
        # Remove the ICC profile
        data = list(img.getdata())
        img_without_profile = Image.new(img.mode, img.size)
        img_without_profile.putdata(data)

        # Save the image without the ICC profile
        img_without_profile.save(output_image_path, format='PNG')

通过仅读取图片的图像数据另外存储到另一个图片文件中,就可以去除png图片多余的icc信息。

如果要批量处理一个文件夹下所有的png图片,可使用以下批量处理代码

'''
移除png的icc profile信息,避免opencv读取时出现错误
'''

import os
import shutil
from PIL import Image
import cv2
import glob
import numpy as np

def remove_image_icc_profile_info(input_image_path, output_image_path):
    if not os.path.exists(input_image_path):
        raise FileNotFoundError(f'{input_image_path} is not exist')

    with Image.open(input_image_path) as img:
        # Remove the ICC profile
        data = list(img.getdata())
        img_without_profile = Image.new(img.mode, img.size)
        img_without_profile.putdata(data)

        # Save the image without the ICC profile
        img_without_profile.save(output_image_path, format='PNG')

        #cv2_img = cv2.imdecode(np.fromfile(output_image_path, dtype=np.uint8), cv2.IMREAD_COLOR)


def remove_dir_all_image_icc_profile_info(input_image_dir, output_image_dir):
    if not os.path.exists(input_image_dir):
        raise FileNotFoundError(f'{input_image_dir} is not exist')

    if not os.path.exists(output_image_dir):
        os.makedirs(output_image_dir)
    else:
        shutil.rmtree(output_image_dir)
        os.makedirs(output_image_dir)

    image_extensions = ('*.jpg', '*.jpeg', '*.png', '*.gif')
    input_image_dir_image_list = sorted([img for ext in image_extensions for img in glob.glob(f'{input_image_dir}/{ext}')])

    for i, image_path in enumerate(input_image_dir_image_list):
        print(f'process image {i}/{len(input_image_dir_image_list)}')
        image_name = os.path.basename(image_path)
        output_image_path = os.path.join(output_image_dir, image_name)

        remove_image_icc_profile_info(image_path, output_image_path)

if __name__ == '__main__':
    input_image_dir = './input_images'
    output_image_dir = './input_images_no_icc_profile_info'
    remove_dir_all_image_icc_profile_info(input_image_dir, output_image_dir)