首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的照片拼贴输出使用numpy有奇怪的颜色配置?

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

Stack Overflow用户
提问于 2022-04-13 04:59:30
回答 1查看 84关注 0票数 0

经过很长一段时间的研究和提问,我已经制作了我的原型代码,它将照片列表拼贴成一个list of strs。

它根据图像在列表中的位置调整图像大小,然后随机旋转图像,并将它们随机排列在一个最小的边界区域。

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

这是我的密码:

代码语言:javascript
复制
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

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

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

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

代码语言:javascript
复制
libpng warning: iCCP: known incorrect sRGB profile

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-13 08:56:48

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

代码语言:javascript
复制
cv2.imwrite('D:/collages/' + random.randbytes(4).hex() + '.png', collage)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71852097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档