从矢量列表中提取一组像素的最大值



我在python上工作,我需要从图像上的一组特定像素中提取最大值或最小值。 假设我的图像是 40 x 40 的图像。我有一个列表,其中包含一些给定的矢量坐标示例:vectorlist=[[10,15],[13,14],[15,23]].我需要提取列表中这些矢量的像素值并计算最小值和最大值。我正在寻找一些快速的方法来做到这一点,因为 FOR 循环会变慢。

a=[]
for i in range(0,len(vectorlist)):
a.append(image[vectorlist[i][0],vectorlist[i][1]])
max1=max(a)
min1=min(a)

如果有更快的方法可以做到这一点,那就太好了!

谢谢!

我同意 Mark 的观点,即创建掩码数组可能是一个好主意,因为您可以将此掩码重用于此数组的其他操作。

import numpy as np
#create test data with random but reproducible data
np.random.seed(54321)
arr = np.random.randint(0, 255, (40, 40), dtype = "uint8")
vectorlist = [[10, 15], [13, 14], [15, 23]]
#extracting rows and columns of the vectorlist
rows, cols = zip(*vectorlist)
#create mask at points defined by vectorlist 
mask = np.zeros(arr.shape, dtype = bool)
mask[rows, cols] = True
print(arr[mask])
#output
#[ 49 245 197]
print(np.max(arr[mask]))
#245
print(np.min(arr[mask]))
#49

请注意,索引从 0 开始,而不是 1 - 如果您vectorlist考虑到这一点,您的问题尚不清楚。并确保列表中的第一个值表示该行。如果没有,只需在脚本中切换rowscols,从zip对象检索这些值。

我是 Python 的绝对初学者,但似乎我的评论是错误的,但我会"站起来">并承认它并说我是如何解决的,也许有人会知道为什么。在有人说这不是答案之前,它是,因为它确实通过引入改进的loop2()函数改进了原始代码(在函数loop()中(:

#!/usr/local/bin/python3
import numpy as np
# Generate an array 40x40 of random integers <100
image=np.random.randint(100,size=(40,40))
# List of pixels we like
vectorlist=[[0,0],[1,1],[1,0],[39,39]]
# Boolean mask of elements we like
mask=np.reshape(np.zeros(1600,dtype=bool),(40,40))
mask[0,0]=mask[1,1]=mask[1,0]=mask[39,39]=True
# OP's suggested method
def loop():
a=[]
for i in range(0,len(vectorlist)):
a.append(image[vectorlist[i][0],vectorlist[i][1]])
mi=min(a)
ma=max(a)
return(mi,ma)
# Slight improvement on OP's method
def loop2():
# Don't add a bunch of items to a list we don't need
mi=ma=image[vectorlist[0][0],vectorlist[0][1]]
for i in range(1,len(vectorlist)):
this=image[vectorlist[i][0],vectorlist[i][1]]
if this>ma:
ma=this
elif this<mi:
mi=this
return (mi,ma)
# My very own slow method using a masked array
def masked():
selpix=image[mask]
mi=np.amin(selpix)
ma=np.amax(selpix)
return (mi,ma)
print(loop())
print(loop2())
print(masked())

示例输出

(22, 91)
(22, 91)
(22, 91)

我将上述所有内容粘贴到IPython中,然后运行以下计时测试:

In [178]: %timeit loop()
1.96 µs ± 6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [179]: %timeit loop2()
1.4 µs ± 2.21 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [180]: %timeit masked()
4.64 µs ± 32.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

对切尔滕纳姆失望:-(

最新更新