计算特定坐标下每个rgb通道平均值的fastet方法

2024-04-19 17:45:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我为此构建了很多函数,最快的是:

meanRGB[:] = sum([img[i,j,:] for i,j in args])/len(args)

但对于大型图像来说,这仍然很慢。 4700x3100映像大约需要40秒。(它在旧cpu(第四代)上运行,但这并不重要)

args包含特定x,y的二维坐标

[[0 0] [1 0] [2 1] ...]

更新

感谢你们所有的好心人,他们送来了这些很棒的方法。我认为乔斯布莱克的路是最快的。 您可以在此处模拟情况(简称):

clusterMap = [[1,4,2],[1,2,3],[3,1,4]]
np.random.seed(2)
img = np.random.randint(low = 0, high = 255, size = (4700, 3100, 3))
segments = np.unique(clusterMap)

meanRGB = np.zeros((len(segments),3))

for k, segment in enumerate(segments.ravel()):
    args = np.argwhere(clusterMap==segment)
    meanRGB[k,:] = sum([img[i,j,:] for i,j in args])/len(args)

    
print(f"\n{meanRGB}")    

Tags: 函数in图像imgforlennpsegment
3条回答

使用numba的一种方法:

import numpy as np
from numba import njit, prange

img = np.random.randint(0, 256, (4700, 3100, 3))
args = np.random.randint(0, 1000, (100000, 2))

@njit(parallel=True, fastmath=True)
def average(array, indices):
    n = len(indices)
    sum_ = np.zeros(3)
    for i in prange(n):
        sum_ += array[indices[i][0], indices[i][1], :]
    return sum_/n

验证:

op = sum(img[i,j,:] for i,j in args)/len(args)
numba_ = average(img, args) 
np.isclose(op, numba_)

# array([ True,  True,  True])

基准测试(大约快几百倍):

%%timeit
meanRGB = sum(img[i,j,:] for i,j in args)/len(args)

# 124 ms ± 704 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit average(img, args)

# 136 µs ± 12.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

按通道拆分,然后使用内置平均值

r = np.mean(img[:,:,0])
g = np.mean(img[:,:,1])
b = np.mean(img[:,:,2])

如果列表不是要使用的完整图像,请使用

mask = np.zeros_like(test[:,:,0])
x_coords = [c[0] for c in args]
y_coords = [c[1] for c in args]
mask[x_coords,y_coords] = 1
r = np.mean(test[mask==1][:,0])
g = np.mean(test[mask==1][:,1])
b = np.mean(test[mask==1][:,2])

我试了一下。我认为这更快,但我没有你的图像或args数组,所以我不确定

import numpy as np

# Trying to recreate your situation
img = np.random.rand(4700,3100,3)
args = np.array([[2,3],[0,1],[2,4],[5,5]])

# my attempt
meanRGB = np.mean(img[args[:,0],args[:,1],:],axis=0)
print(meanRGB)

(示例)输出:

[0.68078292 0.4485302  0.46863616]

相关问题 更多 >