Как рандомизировать пиксели изображения в питоне

1

Я новичок в вычислительном видении и питоне, и я не мог понять, что пошло не так. Я попытался рандомизировать все пиксели изображения в изображении RGB, но мое изображение оказалось совершенно неправильным, как показано ниже. Может кто-то пролить свет?

from scipy import misc

import numpy as np
import matplotlib.pyplot as plt

#Loads an arbitrary RGB image from the misc library
rgbImg = misc.face()     

%matplotlib inline

#Display out the original RGB image 
plt.figure(1,figsize = (6, 4))
plt.imshow(rgbImg)
plt.show()

#Initialise a new array of zeros with the same shape as the selected RGB image 
rdmImg = np.zeros((rgbImg.shape[0], rgbImg.shape[1], rgbImg.shape[2]))
#Convert 2D matrix of RGB image to 1D matrix
oneDImg = np.ravel(rgbImg)

#Randomly shuffle all image pixels
np.random.shuffle(oneDImg)

#Place shuffled pixel values into the new array
i = 0 
for r in range (len(rgbImg)):
    for c in range(len(rgbImg[0])):
        for z in range (0,3):
            rdmImg[r][c][z] = oneDImg[i] 
            i = i + 1

print rdmImg
plt.imshow(rdmImg) 
plt.show()

оригинальное изображение
Изображение 174551

изображение моей попытки рандомизации пикселя изображения
Изображение 174551

Теги:
image-processing
image

2 ответа

1
Лучший ответ

Вы не перетасовываете пиксели, вы перетасовываете все, когда используете np.ravel() и np.shuffle().

Когда вы перетасовываете пиксели, вы должны убедиться, что цвет, кортежи RGB, остаются неизменными.

from scipy import misc

import numpy as np
import matplotlib.pyplot as plt

#Loads an arbitrary RGB image from the misc library
rgbImg = misc.face()

#Display out the original RGB image
plt.figure(1,figsize = (6, 4))
plt.imshow(rgbImg)
plt.show()

# doc on shuffle: multi-dimensional arrays are only shuffled along the first axis
# so let make the image an array of (N,3) instead of (m,n,3)

rndImg2 = np.reshape(rgbImg, (rgbImg.shape[0] * rgbImg.shape[1], rgbImg.shape[2]))
# this like could also be written using -1 in the shape tuple
# this will calculate one dimension automatically
# rndImg2 = np.reshape(rgbImg, (-1, rgbImg.shape[2]))



#now shuffle
np.random.shuffle(rndImg2)

#and reshape to original shape
rdmImg = np.reshape(rndImg2, rgbImg.shape)

plt.imshow(rdmImg)
plt.show()

Это случайный racoon, обратите внимание на цвета. Там нет красного или синего. Только оригинальные, белые, серые, зеленые, черные.

Изображение 174551

Есть и другие проблемы с удаленным мной кодом:

  • Не используйте вложенные для петель, медленно.

  • np.zeros с помощью np.zeros не требуется (если вам когда-либо понадобится, просто передайте rgbImg.shape качестве аргумента, нет необходимости распаковывать отдельные значения)

  • 0
    Спасибо за ваш вклад! Вы имеете в виду, что я могу просто использовать np.zeros (rgbImg.shape)? И не могли бы вы предложить сценарии, когда мне нужно использовать np.zeros?
  • 0
    Да, вы можете использовать np.zeros(rgbImg.shape) , но есть еще более удобный способ: np.zeros_like(rgbImg) . Ваша общая идея была в порядке, np.zeros часто используется для предварительного np.zeros массива и его последующего заполнения. Но обычно вы не добавляете отдельные элементы один за другим. Вы можете иметь цикл for и вставлять целые строки или столбцы.
1

Измените plt.imshow(rdmImg) на plt.imshow(rdmImg.astype(np.uint8))
Это может быть связано с этой проблемой https://github.com/matplotlib/matplotlib/issues/9391/

  • 0
    Ваш оригинальный код должен напечатать это сообщение в консоли Python. Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). , Google, и вы найдете ответ на это проблема.
  • 0
    Спасибо за ваш вклад! Я попытался добавить в строке, как вы предложили, и изображение действительно меняется, однако, у меня может быть проблема с перетасовкой пикселей, поскольку изображение не содержит только цвета исходного изображения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню