我正在逐个像素地循环浏览这个图像,它真的很慢。我有 2 张我正在比较切片和展平的图像,因此每个元素都是一个名为 e1
的 3 维 rgb 值和 e2
.虽然它很慢。有没有使用opencv
的方法?或 numpy
那可以加快速度吗?
我在这里所做的是对具有分箱颜色(8 种颜色)的图像进行像素比较。
我正在阅读 jpeg,所以应该是 [255,0,0]
变成 [230,12,11]
那么clean_key
确实是将值设置为更清洁的值。然后我将这种组合出现的次数附加到字典中。例如 dict["255,0,0 0,0,255"]
在这张图片中可能会出现 300 次,这意味着有 300 个实例出现 im1
有一个红色像素和 im2
有一个蓝色像素。
for e1,e2 in itertools.izip(im1_slice.reshape(-1,3),im2_slice.reshape(-1,3)):
key = str(clean_key(e1_row)) + str(clean_key(e2_row))
if key in proportion_dict:
proportion_dict[key] += 1
else:
proportion_dict[key] = 1
return (proportion_dict,total)
最佳答案
您要执行此操作的方法是首先将每个图像与您希望在该图像中看到的颜色进行比较,这会生成一个 bool 掩码,其中该图像是给定的颜色。您无需拼合图像即可执行此操作。这可以通过说:
image == color
这适用于灰度图像,但如果
color
实际上是沿第三个维度,您要确保该维度上的所有内容都匹配(即,您希望所有 r、g 和 b 分量都匹配,因此您使用 np.all
沿最后一个轴( -1
给出最后一个轴):np.all(image == color, axis=-1)
这给出了一个二维 bool 数组,其中每个元素是
True
如果该像素匹配 color
和 False
如果不。对两个图像(和两种颜色)执行此操作,然后您将拥有一个颜色与两个图像匹配的蒙版:np.all(im1==c1, -1) & np.all(im2==c2, -1)
这不仅告诉你有多少像素匹配,还告诉你它们在哪里(你可以绘制上面的线并在它们匹配的点上看到点)。如果您只想要计数,只需使用
np.sum
在计数 True
的面具上如1
, 和 False
如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
的 key 在我看来,实际上是元组的元组,比字符串更容易处理。以下是访问示例 key 的方式:>>> col_dict[((0, 255, 255), (255, 0, 255))]
8
关于python - 如何避免使用opencv和numpy逐像素循环遍历图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20359192/