【问题标题】:Extract the max value of a set of pixels, from a vector list从向量列表中提取一组像素的最大值
【发布时间】:2023-03-20 18:23:01
【问题描述】:

我正在研究 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)

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

谢谢!

【问题讨论】:

  • 如果示例中的 for 循环对于构建数组是必需的,则可以使用它来获取最大值和最小值,例如 if (max1 is None or max1 > image[vectorlist[i][0],vectorlist[i][1]]):...if (min1 is None or min1 < image[vectorlist[i][0],vectorlist[i][1]]):...
  • 我还是一个 Python 菜鸟,但我认为你想要 "fancy indexing".... jakevdp.github.io/PythonDataScienceHandbook/… 或者也许是一个 "masked array"...docs.scipy.org/doc/numpy-1.13.0/reference/…

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


【解决方案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 对象中检索这些值时。

【讨论】:

  • 这完全消除了for循环的使用
【解决方案2】:

我是 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)

对切尔滕纳姆感到失望 :-)

【讨论】:

    猜你喜欢
    • 2019-04-04
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 2019-12-08
    相关资源
    最近更新 更多