首页 > 编程问答 >有没有办法使用 NumPy.any() 函数查找 3xAny NumPy 数组中特定“列”的索引?

有没有办法使用 NumPy.any() 函数查找 3xAny NumPy 数组中特定“列”的索引?

时间:2024-07-28 08:03:15浏览次数:13  
标签:python numpy

我正在使用 3D“图像”,并试图找出如何更有效地绘制独特连接区域(在本例中为血管)。 我有 1 和 2 以及 0 的空格。 我当前创建这些船只所在位置的地图的解决方案是创建一个数组,其中

[1 2 0 2

1 2 0 2

1 1 2 2

0 1 0 2] (但是在3D中)

将变成:

[1 2 0 3

1 2 0 3

1 1 3 3

0 1 0 3]

我使用 np.nonzero(arr )收集所有非零元素的 x,y,z 坐标,然后遍历并找到所有具有相同值的相邻元素(前、后、左、右、上、下;无对角线),将这些元素添加到 np.zeroeslike(arr) 数组中。 在迭代此数组时,我希望能够从 np.nonzero 创建的数组中删除项目,因为我在“按数字绘制”解决方案中遇到它们(我使用该解决方案是因为该软件将按数字绘制解决方案作为输入)。

这是我当前的代码:

    def vesselFinder(self, inputVolumeAsArray, minVesselSize):
        import numpy as np
        nonZeroes = np.nonzero(inputVolumeAsArray != inputVolumeAsArray[0][0][0])  # Assume the origin corner is a null value
        visited = np.zeros_like(inputVolumeAsArray, dtype=int)
        nzLen = len(nonZeroes[0])
        v = 1
        for t in range(nzLen-1):
            if not visited[nonZeroes[0][t]][nonZeroes[1][t]][nonZeroes[2][t]]:
                currentVal = inputVolumeAsArray[nonZeroes[0][t]][nonZeroes[1][t]][nonZeroes[2][t]]
                currentPoint = [(nonZeroes[0][t], nonZeroes[1][t], nonZeroes[2][t])]
                while currentPoint:
                    depth, row, col = currentPoint.pop()
                    if (0 <= depth < len(inputVolumeAsArray) and
                        0 <= row < len(inputVolumeAsArray[0]) and 
                        0 <= col < len(inputVolumeAsArray[0][0]) and 
                        not (visited[depth][row][col] > 0) and
                        (inputVolumeAsArray[depth][row][col] == currentVal)):
                        visited[depth][row][col] = v
                        currentPoint.extend([(depth + dd, row + dr, col + dc) for dd, dr, dc in [(1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)]])
                cou = np.count_nonzero(visited == v)
                if (cou < minVesselSize):
                    visited[visited == v] = 0
                else:
                    v += 1
        return visited

现在,我只是检查“visited”数组中的值是否不是零,如果是,那么我只是跳过该项目。 我想避免一些等待时间,因为我注意到,对于更密集的患者扫描,我的程序需要更长的时间来运行(稀疏图像需要 2 分钟,密集图像需要 30 分钟)。


理解了。希望优化血管分割代码,该代码在 3D 图像中查找相连的组件(血管),并通过给每个血管分配唯一的 ID 来标记它们。当前的基于 flood-fill 算法的解决方案按顺序处理每个体素,这在处理大型密集图像时可能会变慢。

让我们探索一种使用 NumPy 更有效地实现的目标的方法:

使用 np.unique 和集合操作进行优化

  1. 标记唯一值: 不需要手动为每个相邻区域分配唯一的 ID。 np.unique 函数(使用 return_inverse=True )可以有效地为完成这项工作:
import numpy as np

def optimized_vessel_finder(input_volume, min_vessel_size):
    labeled_volume = np.zeros_like(input_volume, dtype=int)
    unique_vals, inverse_indices = np.unique(input_volume, return_inverse=True)
    labeled_volume = inverse_indices.reshape(input_volume.shape) + 1  # +1 以避免 0 冲突

    # ...(稍后处理小血管)...

    return labeled_volume 
  1. 高效计算邻域: 仍然可以遍历非零体素,但不必手动检查所有 6 个邻域,可以使用 NumPy 的索引技巧来实现:
    # ...(在上面的代码中)... 

    for current_label in range(1, len(unique_vals) + 1):
        vessel_coords = np.argwhere(labeled_volume == current_label)
        for coord in vessel_coords:
            neighbors = [(coord[0] + dd, coord[1] + dr, coord[2] + dc) for dd, dr, dc in 
                           [(1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)]]
            # ...(检查此血管标签的邻居,请参阅下面的说明)... 
  1. 删除小血管: 在标记体素并识别连接的组件后,可以有效地删除低于大小阈值的血管:
    # ...(在上面的代码中)...

    for current_label in range(1, len(unique_vals) + 1):
        # ...(计算邻居)...

        vessel_size = np.count_nonzero(labeled_volume == current_label)
        if vessel_size < min_vessel_size:
            labeled_volume[labeled_volume == current_label] = 0 

优化邻域检查

  • 可以通过维护“已访问”集来进一步优化邻域检查。对于每个唯一的血管标签,创建一个包含其坐标的集合。在检查邻居时,如果该邻居的坐标已经在集合中,则可以跳过它。

完整的优化代码:

import numpy as np

def optimized_vessel_finder(input_volume, min_vessel_size):
    labeled_volume = np.zeros_like(input_volume, dtype=int)
    unique_vals, inverse_indices = np.unique(input_volume, return_inverse=True)
    labeled_volume = inverse_indices.reshape(input_volume.shape) + 1

    for current_label in range(1, len(unique_vals) + 1):
        vessel_coords = set(map(tuple, np.argwhere(labeled_volume == current_label)))  # 使用集合进行更快的成员资格检查

        vessel_size = len(vessel_coords)
        if vessel_size < min_vessel_size:
            labeled_volume[labeled_volume == current_label] = 0
            continue  # 跳过进一步的邻居检查

        # ...(可以根据需要在此处添加邻域检查逻辑)... 

    return labeled_volume 

其他提示

  • 并行化: 研究使用 joblib multiprocessing 等库并行化唯一值循环。
  • 形态学操作: 如果需要更高级的连接组件分析(例如,考虑对角邻居),请探索 Scikit-image 库( skimage.measure.label )中的形态学操作和连接组件标记。

通过应用这些优化,应该可以显著减少血管分割代码的处理时间,尤其是在处理大型密集图像时。

标签:python,numpy
From: 78802649

相关文章

  • 标量添加中的 Python 溢出警告
    我想执行一个简单的操作:b+g+rb,g,r变量是整数并且值低于256。我收到溢出警告和错误的结果。问题是操作很简单(结果不高于765),我不应该收到溢出警告这是我的代码:importcv2ascvimportnumpyasnpimgname='r_hh_classic.png'img=cv.imread(imgname)h,w,_=......
  • 在 Python 中读取部分 MP3 文件时处理“对于可用位计数来说太大”错误
    我正在尝试读取MP3文件的特定部分,但遇到错误:[src/libmpg123/layer3.c:INT123_do_layer3():1771]error:part2_3_length(1376)toolargeforavailablebitcount(760)可以访问音频文件此处我的环境是使用此Docker映像设置的:pytorc......
  • Python SQLAlchemy 2.0 使用 dataclass_transform 非必需字段类型
    我刚刚在一个新项目上安装了SQLAlchemy2.0,我正在尝试使我的模型尽可能类型安全。通过使用@typing_extensions.dataclass_transform,我已经能够实现我想要实现的大部分目标类型检查,但是当前所有字段都被标记为不需要。例如:@typing_extensions.dataclass_tran......
  • 当读取字节时,Python 将 \n 解释为 0xd0
    换行符被解释为Ð(0xd0)而不是(0x0a),我真的不知道如何解决这个问题。我也不知道从哪里开始。当尝试使用此代码时,它将0x0a读为0xd0。withopen(path,"rb")asroot:b_arr=root.read()+b""print("Processing...")buffer=""b_arr......
  • 在Python 3中获取范围的特定形式
    当获取range(1,100)时,我得到:[1,2,3,4,5...99]我需要像这个范围的zip之类的东西:[50,49,51,48,52,47,53...99]如何获取它?背景:这都是关于比特币谜题66的。首先我做了对过去已知的私钥进行线性回归预测,直到第65题为止。我......
  • Python:如何使用pyaudio或sounddevice等库进行自动录音?
    我想做一个项目,需要满足以下录音要求:程序启动后,会在后台不断检测麦克风的声音,当声音分贝大于一定值时打开录音流级别,当分贝低于一定级别时关闭录音流并保存为wav文件。我知道原理,但我无法使用这些库来实现。我想实现以上结果使用Python实现自动录音以下代......
  • 当我们创建一个在 https 服务器上获取和发送数据的 python 应用程序时,我们应该如何处
    python脚本使用Urllib3,我的服务器是在Node.js上编写的脚本。我担心(并且不清楚)证书:我是否需要将我的python应用程序上的证书另存为变量?例如我这样做了,http=urllib3.PoolManager(cert_reqs="CERT_REQUIRED",ca_certs='client-cert.pem')并且我不知道......
  • 使用 Python 进行 Web 抓取以获取数据 NoneType ERROR
    我正在努力为我的学校项目获取美元和价格。所以我决定为此使用网络抓取,但我有一个问题。当我尝试在服务器上使用我的代码时,它给我NoneType错误。它可以在googlecolab上使用,但我无法在我的电脑或服务器上使用。我该如何解决这个问题?网页抓取代码;defdolar():he......
  • Python 请求 - response.json() 未按预期工作
    我正在尝试从Python的requests模块调用API。在邮递员上,返回的响应标头中的Content-Type是application/json;charset=utf-8,响应json数据是我期望的样子。但是,在python上的API的get方法之后运行response.json()会抛出错误simplejson.errors......
  • Python 中的“样板”代码?
    Google有一个Python教程,他们将样板代码描述为“不幸的”,并提供了以下示例:#!/usr/bin/python#importmodulesusedhere--sysisaverystandardoneimportsys#Gatherourcodeinamain()functiondefmain():print'Hellothere',sys.argv[1]#Command......