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

时间:2018-05-24 06:00:40

标签: python-3.x opencv numpy-ndarray

我正在研究python,我需要从图像上的一组特定像素中提取最大值或最小值。让我说我的图像是一个40乘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)

如果有更快的方法,那就太棒了!

谢谢!

2 个答案:

答案 0 :(得分:1)

我同意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对象中检索这些值。

答案 1 :(得分:0)

我是Python的绝对初学者,但似乎我的评论是错误的,但我会" man up" 并承认并说出我的工作方式出去也许有人会知道为什么。在任何人说它不是答案之前,它是,因为它通过引入改进的loop()函数确实改进了原始代码(在函数loop2()中):

#!/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)

对切尔滕纳姆失望: - )