Python:获取数组所有掩码的最快方法

标签 python numpy opencv array-broadcasting

有没有比遍历二维数组的所有组件更快的方法来获取特定范围内的所有可能的掩码,例如:

import numpy as np
numOfLabels = 80
array2D = np.random.choice(255,(512,512))
for i in range(1,numOfLabels):
    mask = array2D==i

也许是广播和创建一个带有所有面具的 3d 数组

编辑:

感谢您已经写好的答案。
为了更好的解释。我想做什么:

我有一个带有组件的二维标签矩阵。组件标有数字,比如说 1 到 80。我有两个图像。现在我想为所有 80 个组件计算这两个图像的平均值、最大值、最小值。也许我的想法完全错误。

EDIT2:

根据评论,我找到了一种使用以下代码的方法:
from scipy import ndimage
import numpy as np

def calculateMeanMaxMin(val):
    return np.array([np.mean(val),np.max(val),np.min(val)])

def getTheStatsForComponents(array1,array2):
    ret, thresholded= cv2.threshold(array2, 50, 255, cv2.THRESH_BINARY)
    thresholded= thresholded.astype(np.uint8)
    numLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresholded, 8, cv2.CV_8UC1)
    allComponentStats=[]
    meanmaxminArray2 = ndimage.labeled_comprehension(array2, labels, np.arange(1, numLabels+1), calculateMeanMaxMin, np.ndarray, 0)
    meanmaxminArray1 = ndimage.labeled_comprehension(array1, labels, np.arange(1, numLabels+1), calculateMeanMaxMin, np.ndarray, 0)
    for position, label in enumerate(range(1, numLabels)):
        currentLabel = np.uint8(labels== label)
        _, contour, _ = cv2.findContours(currentLabel, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
        (side1,side2)=cv2.minAreaRect(contour[0])[1]
        componentStat = stats[label]
        allstats = {'position':centroids[label,:],'area':componentStat[4],'height':componentStat[3],
                              'width':componentStat[2],'meanArray1':meanmaxminArray1[position][0],'maxArray1':meanmaxminArray1[position][1],
                              'minArray1':meanmaxminArray1[position][2],'meanArray2':meanmaxminArray2[position][0],'maxArray2':meanmaxminArray2[position][1],
                              'minArray2':meanmaxminArray2[position][2]}
        allComponentStats.append(allstats)
    return allComponentStats

但我想知道是否有一种更快的方法可以将所有组件的所有统计信息写入字典,因为我不知道 ndimage.measurements.labeled_comprehension 是否很快,以及我是否能以某种方式避免这个循环?

最佳答案

您可以使用 np.put_along_axis一次创建所有蒙版。所有未标记的点都到平面零:

all_masks = np.zeros((numOfLabels, *array2D.shape), bool)
np.put_along_axis(all_masks, array2D*(array2D<numOfLabels)[None], True, axis=0)

# check
for i in range(1,numOfLabels):
    assert (all_masks[i] == (array2D==i)).all()

关于Python:获取数组所有掩码的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57486251/

相关文章:

python - Kivy 文本输入换行

python - 通过无循环的 bool 索引数组的 bool 索引数组

python - 开放式 CV 轮廓面积计算错误

c++ - 鸟瞰opencv

python - Numpy 数组函数返回不一致的形状

python - Pandas 使用 UTC 时间创建日期范围

python - 为什么 pandas read_csv 发出此警告? (元素比较失败)

c++ - cmake 如何知道包含文件和库在哪里?

python - Tkinter 奇怪的框架大小

python 、 Pandas : join dataframes on timestamp and offset