您想要执行此操作的方法是首先将每个图像与您想要在该图像中看到的颜色进行比较,这会生成一个布尔蒙版,其中该图像是给定的颜色。您不需要展平图像来执行此操作。这可以通过说:
image == color
这对于灰度图像来说效果很好,但是如果color
实际上是沿着第三个维度,您想要确保沿着该维度的所有内容都匹配(即,您希望所有 r、g 和 b 分量匹配,因此您使用np.all
沿着最后一个轴(-1
给出最后一个轴):
np.all(image == color, axis=-1)
它给出了一个二维布尔数组,其中每个元素是True
如果该像素匹配color
and False
如果不。对两个图像(以及两种颜色)执行此操作,然后您将得到一个颜色匹配的蒙版both images:
np.all(im1==c1, -1) & np.all(im2==c2, -1)
这不仅告诉您有多少像素匹配,还告诉您它们的位置(您可以绘制上面的线并在它们匹配的点处看到点)。如果您只想计数,只需使用np.sum
在重要的面具上True
as 1
, and False
as 0
。全部一起:
def compare_colors(im1, im2, c1, c2):
matches = np.all(im1==c1, -1) & np.all(im2==c2, -1)
return matches.sum()
并使用随机数据来使用/测试它:
>>> a = np.random.choice([0, 255], (20,20,3))
>>> b = np.random.choice([0, 255], (20,20,3))
>>> compare_colors(a, b, [255, 0, 255], [0, 255, 0])
12
但在此之前,根据您的真实输入,您需要按阈值“清理”颜色。你可以轻松做到这一点np.where
它查看数组的每个元素,如果满足条件,则给出一个值,如果不满足,则给出另一个值。这里,如果该值小于128
, 它用0
,否则使用255
:
np.where(a<128, 0, 255)
一般来说,您可以编写这样的函数,并使用上面的值作为默认值:
def clean(a, thresh=128, under=0, over=255):
return np.where(a<128, under, over)
当然,要建立计数字典,您仍然必须循环遍历每种颜色组合,但这是一个很短的循环(8*8
)。这是完整的运行过程:
# some fake data (has values between 0 and 255 for r, g, and b)
H, W = 20, 20
a = np.random.randint(0, 256, (H,W,3))
b = np.random.randint(0, 256, (H,W,3))
# clean the images:
ac = clean(a)
bc = clean(b)
# build a list of all pairs of all 8 colors using itertools.product:
col_combos = itertools.product(itertools.product((0,255), repeat=3), repeat=2)
# now apply the comparison to the images for each pair of colors
col_dict = { (c1,c2): compare_colors(ac, bc, c1, c2) for c1,c2 in col_combos }
然后,键为col_dict
在我看来,实际上是元组的元组,它们比字符串更容易处理。以下是访问示例密钥的方法:
>>> col_dict[((0, 255, 255), (255, 0, 255))]
8