随机化图像中黑色像素的位置

randomizing location of black pixels in an image

假设我以这种方式生成图像:

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()

结果是一张半白半黑的图像。我怎样才能随机化黑白像素的位置?我试过使用 numpy permutationshuffle 函数,但这似乎对图像没有任何作用。变量 im 是一个 3D 数组,随机化像素的位置需要移动每个像素具有三个值 (R,G,B) 的对象,因此像素一是 im[0,0,:],像素二是 im[0,1,:]等等

一种简单的方法是重塑一长行像素并打乱这些像素:

>>> im2d = im.reshape(-1, im.shape[2])
>>> shuffle = np.random.permutation(im2d.shape[0])
>>> im2d[...] = im2d[shuffle]

这会准原地打乱 im 的像素(它实际上会创建一个新数组并将其复制回 im)。

您可能认为可以使用 numpy.random.shuffle,但它只会打乱第一个维度。对于您的图像,这会打乱行,而不是所有像素。

如果您将数组的形状从 (m, n, 3) 重塑为 (m*n, 3),您 可以 使用 numpy.random.shuffle。您可以创建具有此形状的数组的 "view",并将其传递给 numpy.random.shuffle。这也将洗牌你的数组,因为 numpy.random.shuffle 就地操作。所以在你写完cct = np.concatenate((zz,oo),1)之后,你可以做

np.random.shuffle(cct.reshape(-1, 3))

这在一般情况下是行不通的,因为reshape方法可以return一个副本,在这种情况下,上面的行将洗牌副本 就地,但它不会更改原始数组。在您的例子中,您刚刚使用 np.concatenate 构造了 cct,因此数组是 C 连续的,并且 cct.reshape(-1, 3) return 是一个视图。

生成半黑半白像素图像的简单方法是创建一个具有均匀分布随机值的图像(无论哪种方法和范围在您的平台上都很便宜),然后将该图像的阈值设置为一半范围。这将导致每个像素有 50% 的几率为黑色或白色。

如果您确实需要正好一半的像素是黑色或白色,则需要计算中值和阈值。在那种情况下,洗牌像素可能更便宜(如其他 3 个答案)。