如何使用 PIL 和 numpy 按行随机播放 .jpg 图像的像素
How to shuffle a .jpg image's pixels by rows using PIL and numpy
我想按行对 .jpg
图像中的像素重新排序。使用我在互联网上找到的各种答案,我写道:
from PIL import Image
import numpy as np
a = Image.open('donkey.jpg')
b = a.getdata()
b = np.reshape(b, (a.height, a.width, 3))
dic = []
for i in range(1, a.height):
element = np.reshape(b[:i], (i * a.width, 3))
dic.append(element)
dic
产生这样的东西:
[array([[205, 225, 232],
[201, 222, 227],
[203, 224, 227],
...,
[204, 222, 224],
[210, 226, 225],
[230, 222, 186]]),
array([[205, 225, 232],
[201, 222, 227],
[203, 224, 227],
...,
[188, 183, 154],
[180, 175, 146],
[181, 175, 143]]),
...,
array([[205, 225, 232],
[201, 222, 227],
[203, 224, 227],
...,
[249, 251, 240],
[249, 251, 240],
[249, 249, 241]])]
我想我成功地按行打乱了图像的像素。但是,我无法将其转换回图像。
我试过了:
Image.fromarray(dic.astype)
哪个,没用。这是错误消息:
AttributeError: 'list' object has no attribute 'astype'
请帮我把打乱的图片转回图片!
您可以使用下面的代码实现您想要的效果。新手理解起来有点复杂,掌握了窍门就会大有作为。
重新格式化的原因;
完全消除逐行操作:显着降低效率。使用 np.random.permutation
是一种更快更有效的方法。
将图像拆分为通道:在进行整形时避免通道之间的数据传输。
使用 dstack
来保持通道的顺序并且在整形时不会弄乱数据
添加了 channel_count
以能够处理 png 或灰度照片,使代码片段更加简单。
import numpy as np
from PIL import Image
img = Image.open("donkey.jpg")
# getting the number of channels
channel_count = len(img.getbands())
img_arr = np.reshape(img, (img.height, img.width, channel_count))
# splitting up channels
channels = [img_arr[:,:,x] for x in range(channel_count)]
# setting up a shuffling order for rows
random_perm = np.random.permutation(img.height)
# reordering the rows with respect to the permutation
shuffled_img_arr = np.dstack([x[random_perm, :] for x in channels]).astype(np.uint8)
# creating the Image from the shuffled array
shuffled_img = Image.fromarray(shuffled_img_arr)
# saving the shuffled file
shuffled_img.save("shuffled_donkey.jpg")
此代码会将您提供的图像保存为完全随机排列的行。
我想按行对 .jpg
图像中的像素重新排序。使用我在互联网上找到的各种答案,我写道:
from PIL import Image
import numpy as np
a = Image.open('donkey.jpg')
b = a.getdata()
b = np.reshape(b, (a.height, a.width, 3))
dic = []
for i in range(1, a.height):
element = np.reshape(b[:i], (i * a.width, 3))
dic.append(element)
dic
产生这样的东西:
[array([[205, 225, 232],
[201, 222, 227],
[203, 224, 227],
...,
[204, 222, 224],
[210, 226, 225],
[230, 222, 186]]),
array([[205, 225, 232],
[201, 222, 227],
[203, 224, 227],
...,
[188, 183, 154],
[180, 175, 146],
[181, 175, 143]]),
...,
array([[205, 225, 232],
[201, 222, 227],
[203, 224, 227],
...,
[249, 251, 240],
[249, 251, 240],
[249, 249, 241]])]
我想我成功地按行打乱了图像的像素。但是,我无法将其转换回图像。
我试过了:
Image.fromarray(dic.astype)
哪个,没用。这是错误消息:
AttributeError: 'list' object has no attribute 'astype'
请帮我把打乱的图片转回图片!
您可以使用下面的代码实现您想要的效果。新手理解起来有点复杂,掌握了窍门就会大有作为。
重新格式化的原因;
完全消除逐行操作:显着降低效率。使用
np.random.permutation
是一种更快更有效的方法。将图像拆分为通道:在进行整形时避免通道之间的数据传输。
使用
dstack
来保持通道的顺序并且在整形时不会弄乱数据添加了
channel_count
以能够处理 png 或灰度照片,使代码片段更加简单。
import numpy as np
from PIL import Image
img = Image.open("donkey.jpg")
# getting the number of channels
channel_count = len(img.getbands())
img_arr = np.reshape(img, (img.height, img.width, channel_count))
# splitting up channels
channels = [img_arr[:,:,x] for x in range(channel_count)]
# setting up a shuffling order for rows
random_perm = np.random.permutation(img.height)
# reordering the rows with respect to the permutation
shuffled_img_arr = np.dstack([x[random_perm, :] for x in channels]).astype(np.uint8)
# creating the Image from the shuffled array
shuffled_img = Image.fromarray(shuffled_img_arr)
# saving the shuffled file
shuffled_img.save("shuffled_donkey.jpg")
此代码会将您提供的图像保存为完全随机排列的行。