【问题标题】:Randomly shuffling pixels of images with Python is throwing a ValueError使用 Python 随机打乱图像的像素会引发 ValueError
【发布时间】:2021-12-29 15:34:57
【问题描述】:

按照this answer on SO,我构建了这个python脚本来打乱文件夹内每个图像的像素:

from PIL import Image
import numpy as np
import os

directory = "/my/path/images"
    
for file in os.listdir(directory):
    filename = os.fsdecode(file)
    if filename.endswith(".jpeg") or filename.endswith(".jpg"):
        orig = Image.open(os.path.join(directory, filename))
        orig_px = orig.getdata()
        orig_px = np.reshape(orig_px, (orig.height * orig.width, 3))
        np.random.shuffle(orig_px)
        orig_px = np.reshape(orig_px, (orig.height, orig.width, 3))
        res = Image.fromarray(orig_px.astype('uint8'))
        res.save(rf'images-scrambled/scr-{filename}')

        continue
    else:
        continue

上面的代码对某些图像非常有效,而对于其他图像则失败并显示此回溯消息:

Traceback (most recent call last):
  File "/Users/user1/image_scrambler/03-image_scrambler-v2.py", line 19, in <module>
    orig_px = np.reshape(orig_px, (orig.height * orig.width, 3))
  File "<__array_function__ internals>", line 5, in reshape
  File "/XYZ/site-packages/numpy/core/fromnumeric.py", line 298, in reshape
    return _wrapfunc(a, 'reshape', newshape, order=order)
  File "/XYZ/site-packages/numpy/core/fromnumeric.py", line 54, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "/XYZ/site-packages/numpy/core/fromnumeric.py", line 43, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
ValueError: cannot reshape array of size 800000 into shape (200000,3)

我不知道为什么会这样。所有图像均为 JPG 格式,分辨率为 500x400 像素。我正在使用 Python 3.10 版。是什么导致了这个问题?

【问题讨论】:

  • 仔细检查失败的文件之一。我敢打赌它不是 500x400。
  • 双重检查:文件为 500x400。分辨率不是原因,而是@aberry 建议的 RGBA 的 4 通道。
  • JPEG 不支持 RGBA,否则我会自己建议。但似乎它们可以是 CMYK,这是一种我从未遇到过的奇怪格式。您的文件的来源是什么?
  • 来源是科学图像集 OASIS osf.io/6pnd7 — 免费图像的集合。一张不合适的图片是该系列的猴子 3 (#502)。

标签: python numpy image-processing


【解决方案1】:

当您使用Image.open 时使用orig.mode 检查图像模式,您可能会得到4 个通道RGBA 而不是3 个通道作为RGB。所以要修复它,你必须在重塑时使用 4 :-

orig_px = np.reshape(orig_px, (orig.height * orig.width, 4))

orig_px = np.reshape(orig_px, (orig.height, orig.width, 4))

【讨论】:

  • 是的,你没看错,模式是RGBA。我按照建议更改了两条线,但没有成功。错误信息是:KeyError: 'RGBA' OSError: cannot write mode RGBA as JPEG
  • 很高兴看到您的重塑错误得到解决。我看到您正在保存 JPEF ,因为您需要将 JPEG 转换为 RGB。检查stackoverflow.com/questions/43258461/…的线程
  • @Madamadam 您可以做的另一件事是,您还可以在阅读图片之前将您的频道转换为RGB。这将使通道数 3 在所有地方保持一致。
  • 谢谢@aberry!转换图像有效,是一个很好的解决方案。将此建议添加到您的答案中可能是个好主意,这样我就可以投票了。
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
相关资源
最近更新 更多