为什么我使用 numpy 输出的照片拼贴有奇怪的颜色配置文件?

Why my photo collage output using numpy has strange color profile?

经过长时间的研究和提问,我制作了我的原型代码,该代码制作了照片列表的拼贴画,其中 list of strs。

根据图片在列表中的位置调整图片大小,然后随机旋转图片,随机排列在最小边界区域内。

它使用 cv2numpyPILrpack,老实说我完全不知道这些库是如何工作的,为什么我的代码能工作,我只知道如何让它们工作,我只知道如何将它们组合在一起。

所以这是我的代码:

import cv2
import numpy as np
import random
import rpack
from fractions import Fraction
from math import prod
from pathlib import Path
from PIL import Image
from typing import Tuple

folder = 'D:/test/'

images = [
    'Mass Effect.jpg',
    'Dragon Age Origins.jpg',
    'Life Is Strange.jpg',
    'Star Wars KOTOR.jpg',
    'Dragon Age 2.jpg',
    'Choice of Robots.jpg',  
    'Perfect Match.png',
    'Jade Empire.jpg',
    "Serafina's Saga.jpg",
    'Rising Angels Reborn.jpg',       
    'Across The Void.png',
    "Heart's Blight.png", 
    'The Gray Wolf And The Little Lamb.jpg',
    'Night of the Lesbian Vampires.png',                 
    'Tethered.png',
    'Contract Demon.jpg',
    "Yuki's 4P.png"
]                        

def resize_guide(image_size: Tuple[int, int], unit_shape: Tuple[int, int], target_ratio: float) -> Tuple[int, int]:
    aspect_ratio = Fraction(*image_size).limit_denominator()
    horizontal = aspect_ratio.numerator
    vertical = aspect_ratio.denominator
    target_area = prod(unit_shape) * target_ratio
    unit_length = (target_area/(horizontal*vertical))**.5
    return (int(horizontal*unit_length), int(vertical*unit_length))

images = [cv2.imread(folder+name) for name in images]
size_hint = [i**.75 for i in range(1, len(images)+1)][::-1]
resized_images = []

for image, hint in zip(images, size_hint):
    height, width = image.shape[:2]
    guide = resize_guide((width, height), (640,360), hint)
    resized = cv2.resize(image, guide, interpolation = cv2.INTER_AREA)
    resized_images.append(resized)

def make_border(image, value, border=16):
    return cv2.copyMakeBorder(
        image,
        top=border,
        bottom=border,
        left=border,
        right=border,
        borderType=cv2.BORDER_CONSTANT,
        value=value
    )

def rotate_image(image, angle):
    h, w = image.shape[:2]
    cX, cY = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY
    return cv2.warpAffine(image, M, (nW, nH))

rotated_images = []
sizes = []

for image in resized_images:
    image = make_border(image, (255, 255, 255))
    rotated = rotate_image(image, random.randrange(-15, 16))
    image = make_border(image, (0,0,0))
    rotated_images.append(rotated)
    height, width = rotated.shape[:2]
    sizes.append((width, height))

shapes = [(x, y, w, h) for (x, y), (w, h) in zip(rpack.pack(sizes), sizes)]

rightmost = sorted(shapes, key=lambda x: -x[0] - x[2])[0]
bound_width = rightmost[0] + rightmost[2]

downmost = sorted(shapes, key=lambda x: -x[1] - x[3])[0]
bound_height = downmost[1] + downmost[3]

collage = np.zeros([bound_height, bound_width, 3],dtype=np.uint8)

for image, (x, y, w, h) in zip(rotated_images, shapes):
    collage[y:y+h, x:x+w] = image

collage = Image.fromarray(collage, 'RGB')

collage.save('D:/collages/' + random.randbytes(4).hex() + '.png')

由于输出太大(超过 20 MiB),放不下,我已将其上传到 Google 驱动器:https://drive.google.com/file/d/16w4wsC_od4dh4QI7BYj8MM2gMngbSLV1/view?usp=sharing

到目前为止,结果看起来很有希望,我唯一的抱怨是颜色看起来很奇怪,我发誓原始图像的颜色是正常的。

有人可以告诉我我做错了什么吗?


好的,所以在执行代码时,解释器抱怨了很多:

libpng warning: iCCP: known incorrect sRGB profile

我用破解版的Adobe Photoshop CS6编辑图片,请问这是问题的根源还是其他原因?

你做的一切都很好。您犯的唯一错误是在存储图像时。只需删除最后两行并添加以下行。

cv2.imwrite('D:/collages/' + random.randbytes(4).hex() + '.png', collage)