簡體   English   中英

如何避免使用opencv和numpy逐像素循環遍歷圖像

[英]How do I avoid looping through an image pixel by pixel with opencv & numpy

我正在逐個像素循環瀏覽圖像,這確實很慢。 我將要比較的2張圖像進行了切片和展平,因此每個元素都是一個名為e1e2的3維rgb值。 但是,它非常慢。 是否有一些使用opencvnumpy方法可以加快速度?

我在這里所做的是對具有二進制顏色(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)

您要執行此操作的方法是,首先將每個圖像與要在該圖像中看到的顏色進行比較,這將生成一個布爾蒙版,其中該圖像是給定的顏色。 您無需展平圖像即可執行此操作。 可以這樣說:

image == color

這對於灰度圖像效果很好,但是如果color實際上是沿第三維,則要確保該維度上的所有內容都匹配(即,要使所有r,g和b分量都匹配,因此使用np.all沿最后軸( -1給出了最后的軸):

np.all(image == color, axis=-1)

這給出了一個二維布爾數組,其中每個元素如果像素與color匹配,則為True否則為False 對兩個圖像(和兩個顏色)都執行此操作,然后您將得到一個蒙版,其中顏色與兩個圖像匹配:

np.all(im1==c1, -1) & np.all(im2==c2, -1)

這不僅告訴您有多少像素匹配,還告訴了它們在哪里(您可以繪制上面的線,並在它們匹配的點上看到點)。 如果只需要計數, np.sum在掩碼上使用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的鍵實際上是元組的元組,在我看來,它比字符串更容易處理。 這是您訪問示例密鑰的方式:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM