Randomizes the position of black pixels in an image
Let’s say I generate an image this way:
import cv2
import numpy as np
im = cv2.imread('target.jpg')
zzo = np.zeros(im.shape)
shp = (int(im.shape[0]),int(0.5*im.shape[1]),int(im.shape[2]))
zz = np.zeros(shp)
oo = 255*np.ones(shp)
cct = np.concatenate((zz,oo),1)
cv2.imshow('image',cct)
cv2.waitKey(0)
cv2.destroyAllWindows()
The result is a half-white, half-black image. How can I randomize the position of black and white pixels? I’ve tried using the numpy permutation
and shuffle
functions, but this doesn’t seem to do anything for the image. The variable im is a 3D array, and randomizing the position of the pixels requires moving an object with three values (R,G,B) per pixel, so pixel one is im[0, 0,:], pixel two is
im[0,1,:]
,
and so on
Solution
You might think you can use numpy.random.shuffle
, but it will only scramble the first dimension. For your image, this will shuffle the rows, not all the pixels.
If you reshape an array from shape (m, n, 3) to (m*n, 3), you can use numpy.random.shuffle.
You can create a “View” of an array with this shape and pass it to numpy.random.shuffle.
This will also shuffle your array, as numpy.random.shuffle
operates in place. So after you write cct = np.concatenate((zz,oo),1),
you can do it
np.random.shuffle(cct.reshape(-1, 3))
This usually doesn’t work, because the reshape
method can return a copy, in which case the above line will shuffle the copy in place but it won’t alter the original array. In your case, you just constructed cct using np.concatenate
, so the array is C contiguous, and cct.reshape(-1, 3)
returns a View.