Python – Randomizes the position of black pixels in an image

Randomizes the position of black pixels in an image… here is a solution to the problem.

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.

Related Problems and Solutions