Python 如何使用opencv&;避免图像逐像素循环;努比

Python 如何使用opencv&;避免图像逐像素循环;努比,python,opencv,numpy,Python,Opencv,Numpy,我一个像素一个像素地循环浏览这张图片,速度非常慢。我有两张比较切片和展平的图像,因此每个元素都是一个名为e1和e2的三维rgb值。不过速度很慢。是否有一些使用opencv或numpy的方法可以加快速度 我在这里所做的是对具有装箱颜色(8种颜色)的图像执行像素比较。 我是从jpeg中读取的,所以应该是[255,0,0]变成[230,12,11],所以clean_key所做的是将值设置为更干净的阈值。然后我将这种组合出现的次数附加到字典中。因此,例如,dict[“255,0,0,0255”]可能在该

我一个像素一个像素地循环浏览这张图片,速度非常慢。我有两张比较切片和展平的图像,因此每个元素都是一个名为
e1
e2
的三维rgb值。不过速度很慢。是否有一些使用
opencv
numpy
的方法可以加快速度

我在这里所做的是对具有装箱颜色(8种颜色)的图像执行像素比较。
我是从jpeg中读取的,所以应该是
[255,0,0]
变成
[230,12,11]
,所以
clean_key
所做的是将值设置为更干净的阈值。然后我将这种组合出现的次数附加到字典中。因此,例如,
dict[“255,0,0,0255”]
可能在该图像中出现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)

这样做的方法是首先将每个图像与您希望在该图像中看到的颜色进行比较,这将生成一个布尔掩码,其中该图像是给定的颜色。您不需要展平图像即可执行此操作。可以这样做:

image == color
这适用于灰度图像,但如果
color
实际上是沿着第三维的,则需要确保沿着该维度的所有内容都匹配(即,您希望所有的r、g和b分量都匹配,因此使用
np。沿着最后一个轴的所有
-1
给出最后一个轴):

它给出了一个二维布尔数组,其中每个元素都是
True
,如果该像素匹配
color
,如果不匹配
False
。对两个图像(以及两种颜色)执行此操作,然后您将拥有一个颜色匹配两个图像的遮罩:

这不仅可以告诉你匹配的像素数量,还可以告诉你它们在哪里(你可以画出上面的线,在它们匹配的点上看到点)。如果你只需要计数,只需在掩码上使用
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轻松实现这一点。其中
查看数组的每个元素,如果满足条件,则给出一个值,如果不满足,则给出另一个值。在这里,如果值小于
128
,则使用
0
,否则使用
255

np.where(a<128, 0, 255)
然后,
col\u dict
的键实际上是元组的元组,在我看来,这比字符串更容易处理。下面是访问示例键的方法:

>>> col_dict[((0, 255, 255), (255, 0, 255))]
8

我想我们需要更多的信息。要对这个循环进行矢量化,至少还需要对
clean_key
函数进行矢量化。另外,还要更好地解释您想要什么(您的原始目的)可能很有用,因为您当前的方法可能并不理想。例如,您可能希望将图像从彩色图像转换为8位灰度图像,如果您真的要将图像分为8种颜色,那么您不必有这个令人困惑的关键点列表。好的,我想我明白了。我希望有一种快速的方法来循环像素s,瓶颈是在访问像素。看起来我必须考虑这个问题从地面上考虑向量运算。谢谢!非常详细,它确实是有用的习惯于麻木,我的荣幸!只要问任何东西都没有意义。只是想补充说,我得到了7倍的增加。速度
np.where(a<128, 0, 255)
def clean(a, thresh=128, under=0, over=255):
    return np.where(a<128, under, over)
# 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[((0, 255, 255), (255, 0, 255))]
8