当前位置: 首页 > 面试题库 >

Python-二维阵列中的峰值检测

谯嘉懿
2023-03-14
问题内容

我正在帮助兽医诊所测量狗爪下的压力。我使用Python进行数据分析,现在我被困在试图将爪子分成(解剖)子区域。

我制作了每个爪子的2D数组,其中包含爪子随时间推移已加载的每个传感器的最大值。这是一个爪子的示例,我使用Excel绘制了要“检测”的区域。这些是传感器周围具有最大最大值的2 x 2框,它们的总和最大。

因此,我尝试了一些实验,并决定只寻找每一列和每一行的最大值(由于爪子的形状而无法朝一个方向看)。这似乎可以很好地“检测”到各个脚趾的位置,但是它也标记了相邻的传感器。

那么,告诉Python我想要的最大最大值是什么?

注意:2x2的正方形不能重叠,因为它们必须是单独的脚趾!

同样我以2x2为方便,欢迎使用任何更高级的解决方案,但我只是人类运动的科学家,所以我既不是真正的程序员也不是数学家,所以请保持“简单”。

这是可以加载的版本np.loadtxt

结果
因此,我尝试了@jextee的解决方案(请参见下面的结果)。如您所见,它在前爪上非常有效,但在后腿上效果较差。

更具体地说,它无法识别出第四脚趾的小峰。显然,这是回路从上向下朝着最低值而不考虑这在哪里的事实所固有的。

谁会知道如何调整@jextee的算法,以便它也能够找到第四个脚趾?

由于我尚未处理其他任何试验,因此无法提供任何其他样品。但是我之前提供的数据是每只爪子的平均值。该文件是一个数组,其中最大9爪的数据按它们与板接触的顺序排列。

此图显示了它们如何在空间上分布在板上。

新更新:
因此,在获得有关爪子检测和爪子分类的问题的帮助后,我终于能够检查每个爪子的脚趾检测!事实证明,除了爪子大小像我自己的示例中的爪子一样,它在任何情况下都无法正常工作。事后看来,如此随意地选择2x2是我自己的错。

这是一个出问题的好例子:指甲被识别为脚趾,而“脚跟”是如此之宽,被识别两次!

脚掌太大,因此采用2x2大小且没有重叠的脚掌会使两次脚趾被检测到两次。相反,在小型犬中,它通常找不到第5个脚趾,我怀疑这是2x2区域太大造成的。

在尝试了所有解决方案的最新解决方案后,我得出了一个惊人的结论:几乎对我所有的小型犬来说,它都找不到第五个脚趾,而在大型犬的50%以上的撞击中,它会发现更多!

所以很明显我需要更改它。我自己的猜测是将大小更改neighborhood为小型犬较小,大型犬较大。但是generate_binary_structure不允许我更改数组的大小。

因此,我希望其他人对脚趾的定位有更好的建议,也许脚趾的面积与爪子的大小成正比?


问题答案:

我使用局部最大滤波器检测到峰值。这是第一个4个爪子的数据集的结果:

我还在9个爪子的第二个数据集上运行了它,效果也很好。

这是你的操作方式:

import numpy as np
from scipy.ndimage.filters import maximum_filter
from scipy.ndimage.morphology import generate_binary_structure, binary_erosion
import matplotlib.pyplot as pp

#for some reason I had to reshape. Numpy ignored the shape header.
paws_data = np.loadtxt("paws.txt").reshape(4,11,14)

#getting a list of images
paws = [p.squeeze() for p in np.vsplit(paws_data,4)]


def detect_peaks(image):
    """
    Takes an image and detect the peaks usingthe local maximum filter.
    Returns a boolean mask of the peaks (i.e. 1 when
    the pixel's value is the neighborhood maximum, 0 otherwise)
    """

    # define an 8-connected neighborhood
    neighborhood = generate_binary_structure(2,2)

    #apply the local maximum filter; all pixel of maximal value 
    #in their neighborhood are set to 1
    local_max = maximum_filter(image, footprint=neighborhood)==image
    #local_max is a mask that contains the peaks we are 
    #looking for, but also the background.
    #In order to isolate the peaks we must remove the background from the mask.

    #we create the mask of the background
    background = (image==0)

    #a little technicality: we must erode the background in order to 
    #successfully subtract it form local_max, otherwise a line will 
    #appear along the background border (artifact of the local maximum filter)
    eroded_background = binary_erosion(background, structure=neighborhood, border_value=1)

    #we obtain the final mask, containing only peaks, 
    #by removing the background from the local_max mask (xor operation)
    detected_peaks = local_max ^ eroded_background

    return detected_peaks


#applying the detection and plotting results
for i, paw in enumerate(paws):
    detected_peaks = detect_peaks(paw)
    pp.subplot(4,2,(2*i+1))
    pp.imshow(paw)
    pp.subplot(4,2,(2*i+2) )
    pp.imshow(detected_peaks)

pp.show()

你需要做的就是scipy.ndimage.measurements.label在蒙版上使用以标记所有不同的对象。这样你就可以分别与他们一起玩了。

请注意,该方法效果很好,因为背景不嘈杂。如果是这样,你将在背景中检测到许多其他不需要的峰。另一个重要因素是邻里的大小。如果峰大小发生变化,则需要对其进行调整(应保持大致成比例)。



 类似资料:
  • 我是编程新手,我有一个任务要求从一维数组创建二维数组。我想到了这一点(没有任何外部来源的帮助,因为这会剥夺学习经验)。它适用于我们教授的测试输入,我只是想知道这是一个丑陋/低效的解决方案。 测试输入:twoDArray([1,2,3,4,5],3)输出将是:[[1,2,3],[4,5]]

  • 为什么上面的代码不起作用,我应该如何纠正?

  • 问题内容: 我试图创建此代码以输入m x n矩阵。我打算输入,但是代码产生了。当我输入其他m×n矩阵时,也会发生相同的情况,代码会产生行数相同的m×n矩阵。 也许您可以帮助我找到我的代码有什么问题。 问题答案: 问题出在初始化步骤上。 这段代码实际上使您的每一行都引用相同的对象。如果任何列中的任何项目发生更改-其他所有列都将发生变化: 您可以在嵌套循环中初始化矩阵,如下所示: 或者,通过使用列表理

  • 试图实施更大规模的井字游戏 这个游戏可以有超过3行和3列 每当发现4个连续的模式(水平,垂直或交叉) 选手是赢家 我已经找到了水平和垂直匹配的实现方法 但是找不到一种方法来识别2d数组中某个字符的交叉模式 考虑下面的二维数组 ` ` 如何检查“*”字符在这个2d数组中是否有四个连续的交叉模式

  • 我试着做一个Loto游戏,我必须生成一张随机的卡,在第一个collum数字从1-9,第二个10-19一直到90。这张牌的另一个规则是,每行的随机位置上只能有5个数字,这就是我遇到的麻烦。 我从这个开始在每个collum中添加数字: 然后在数组的每一行的一个数字位置上放5个数字我试过这样做: 第三个也一样。 输出: 0 18 0 0 46 0 61 72 88 0 18 0 31 0 55 0 0

  • 我试图将一个2d数组中的特定元素添加到另一个数组中,添加的过程是在数组的第一行选择最小的元素,并将该元素添加到同一位置的另一个2d数组中,例如: 2 22 3 5 1 54 7 3 10 20 22 21 这里,第一行中的最小元素是2,所以应该在相同的位置将2添加到另一个2d数组中,对于第二行,1是最小元素,所以我们也将1添加到另一个2d数组中,第三行中的最小元素是3,最后一行,第四行,最小的元素