numpy 如何用Python创建两种特定颜色的棋盘

kyvafyod  于 2023-04-30  发布在  Python
关注(0)|答案(1)|浏览(104)

我创建了一个像这样的白色棋盘:

import numpy as np
import cv2

checkers = np.tile( np.array([[0, 1], [1, 0]]), (16 // 2, 16 // 2))

但现在我正在努力把它变成一个蓝黄相间的棋盘。
我尝试了一个像这样的lambda转换:

f = lambda x: [0, 255, 0] if x else [255, 255, 255]

checkers = checkers.reshape((256))
checkers = f(checkers)

但我得到一个错误,它说:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

这让我觉得我还没有完全理解lambdas是如何应用于numpy数组的。
我也试过

np.where(checkers == 0, [0, 255, 0], [0, 0, 255])

但我得到了

ValueError: operands could not be broadcast together with shapes (16,16) (3,) (3,)

那么,我如何得到一个双色棋盘,而不是一个黑色和白色?

lmyy7pcs

lmyy7pcs1#

你的答案的最后一部分非常接近正确,但它给了你一个错误:操作数不能一起广播。操作数只是指函数参数checkers == 0,绿色和蓝色。所以这是一个广播问题。你应该通读一下broadcasting rules,它们会真正改变你对Numpy的理解,让它变得更有用。
你的问题是你有一个checkers数组,它是2D的,16x16,你希望它“神奇地”转换为3D数组,它是16x16x3。Numpy不做这种神奇的转换。如果数组的最后一个维度是1,Numpy会帮助你重复(广播)数组,让你可以将它与其他数组相乘(或者你想做的任何事情),所以你不必手动在所有三个颜色通道上平铺它。否则,它只会抛出一个错误。
解决方案是在checkers数组中添加1维。最简单的方法是

np.where(checkers[..., np.newaxis] == 0, [0, 255, 0], [0, 0, 255])

这会在数组的末尾添加另一个维度,因此可以用你的颜色进行广播。
编辑:关于为什么你的lambda方法不起作用,我不确定你是否期望lambda是一些特殊的东西,但它确实与常规函数没有什么不同。所以你所做的就是

checkers = [0, 255, 0] if checkers else [255, 255, 255]

也就是说,将整个checkers数组一次性传递给函数。然后,Python尝试检查checkers是否为真,而bool(checkers)是不明确的,因此它告诉您使用np.allnp.any将整个数组减少为一个值。但那不是你想做的。
有一些函数,如np.apply_along_axisnp.vectorize,允许您将函数应用于所有值,但您很少需要这样做。你的第二种方法要好得多,你只需要更好地理解广播。

相关问题