gpt4 book ai didi

python - 快速计算由 connectedComponents 生成的所有簇的平均颜色

转载 作者:行者123 更新时间:2023-12-02 15:40:21 25 4
gpt4 key购买 nike

我使用 cv2.connectedComponentWithStats 将图像分成簇。现在我想观察每个集群的颜色变化。

目前我的代码是这样的:

#...Calculation of the mask

res,labels,stats,centroids = cv2.connectedComponentsWithStats(im_mask)

def compute_average(frame,i):
data=frame[labels==i].mean(axis=0)
return (data[2]-data[1]) # difference between red and green channel is meaningful for me

while True:
frame=capture.read()
if(not frame[0]):
break
start_time=time.time()
measurements = [ compute_average(frame,i) for i in range(1,len(centroids))]
print("Computing took",time.time()-start_time

似乎每帧计算测量花费了将近 1.5 秒(我有大约 300 个 200-600 像素的集群)。这是无法接受的。

似乎通过巧妙地选择 numpy 算法来计算平均值,我可以获得更好的性能。特别是应该可以同时计算所有集群的平均值。但是,我被困在这里。

有没有办法根据标签对图像像素进行分组?

最佳答案

似乎是一个可以利用的完美用例 np.bincount 这是使用可选的第二个参数计算分箱求和和加权求和的非常有效的方法。在我们这里的例子中,我们将使用标签作为垃圾箱并获得总和作为计数,然后 frame作为权重作为可选权重 arg。

因此,我们将有一个矢量化的,希望更有效的方式,像这样 -

def bincount_method(frame, labels):
f = frame.reshape(-1,3)
cn1 = np.bincount(labels.ravel(), f[:,1])
cn2 = np.bincount(labels.ravel(), f[:,2])
return (cn2[1:]-cn1[1:])/stats[1:,-1]

基准测试

对于计时,我们将重复使用 @Dan Mašek's test-setup image .我们使用的是 Python 3.6.8。
import numpy as np
import cv2
import urllib.request as ur

# Setup
url = '/image/puxMo.png'
s = ur.urlopen(url)
url_response = ur.urlopen(url)
img_array = np.array(bytearray(url_response.read()), dtype=np.uint8)
img = cv2.imdecode(img_array, -1)
im_mask = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

res,labels,stats,centroids = cv2.connectedComponentsWithStats(im_mask)

np.random.seed(0)
frame = np.random.rand(im_mask.shape[0],im_mask.shape[1],3)

时间——
# Original soln by OP
In [5]: %timeit [compute_average(frame,i) for i in range(1,len(centroids))]
2.38 s ± 116 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# @Dan Mašek's soln
In [3]: %timeit rg_mean_diff_per_label(frame, labels)
92.5 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# Solution with bincount
In [4]: %timeit bincount_method(frame, labels)
30.1 ms ± 82.7 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

允许对标签进行预计算

那么 bincount one 有一个小的修改:
L = (labels.ravel()[:,None]+np.arange(2)*res).ravel()

def bincount_method_with_precompute(frame, L):
p = np.bincount(L,frame[...,1:].ravel())
return (p[res+1:]-p[1:res])/stats[1:,-1]

与@Dan Mašek 的解决方案相比,在相同的设置上进行预计算:
In [4]: %timeit bincount_method_with_precompute(frame, L)
25.1 ms ± 326 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [5]: %timeit rg_mean_diff_per_label(frame, label_indices)
20.3 ms ± 432 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

关于python - 快速计算由 connectedComponents 生成的所有簇的平均颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59579755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com