Image 在二维阵列上查找亚像素最大值

Image 在二维阵列上查找亚像素最大值,image,opencv,sum,2d,convolution,Image,Opencv,Sum,2d,Convolution,假设我有一个图像,我想找到一个形状为3x3的子阵列,它包含与其他子阵列相比的最大和 如何在python中高效地(以尽可能快的速度运行)实现这一点?如果你能提供一个示例代码,那就太好了 我的具体问题是: 我想提取这个热图中水滴中心的位置 我不想得到最大点,因为这会导致坐标不太精确。水滴的真实中心实际上可能在2个像素之间。因此,最好在多个点之间进行加权平均,以获得亚像素精度。例如,如果有两个值分别为200和100的点(x1,y1)和(x2,y2)。然后平均坐标将为x=(200*x1+100*x2)

假设我有一个图像,我想找到一个形状为3x3的子阵列,它包含与其他子阵列相比的最大和

如何在python中高效地(以尽可能快的速度运行)实现这一点?如果你能提供一个示例代码,那就太好了

我的具体问题是: 我想提取这个热图中水滴中心的位置

我不想得到最大点,因为这会导致坐标不太精确。水滴的真实中心实际上可能在2个像素之间。因此,最好在多个点之间进行加权平均,以获得亚像素精度。例如,如果有两个值分别为200和100的点(x1,y1)和(x2,y2)。然后平均坐标将为
x=(200*x1+100*x2)/300
y=(200*y1+100*y2)/300

我的解决方案之一是做卷积运算。但是我认为它不够有效,因为它需要到内核的乘法(只包含一个)。我正在寻找一个快速的实现,所以我不能自己做循环,因为我不确定它是否会很快


我想每隔几毫秒对50张图像执行此算法。(图像以批处理的形式出现)。具体来说,可以将这些图像视为输出热图的机器学习模型的输出。为了从这些热图中获得坐标,我需要在高强度的坐标之间进行某种加权平均。我的想法是在图像上做一个3x3左右的加权平均。我也愿意接受其他更快或更优雅的方法。

很抱歉,我没有完全理解你最后一段的意思,所以我只是停在一个点上,在那里我得到了所有具有最大值的坐标。我使用了
cv2.filter2D
对阈值图像进行卷积,然后使用
np.amax
np。其中
找到了具有最大值的坐标

import cv2
import numpy as np
from timeit import default_timer as timer

img = cv2.imread('blob.png', 0)
start = timer()
_, thresh = cv2.threshold(img, 240, 1, cv2.THRESH_BINARY)
mask = np.ones((3, 3), np.uint8)
res = cv2.filter2D(thresh, -1, mask)
result = np.where(res == np.amax(res))
end = timer()
print(end - start)
我不知道它是否有您想要的效率,但输出是
0.001346199999435648 s


另外,您提供的图像有一个白色边框,我必须为这种方法裁剪出来。

一种方法是对图像进行次采样,并找到所需点的邻域。您可以通过不是在所有像素上循环,而是在每5个像素上循环(循环中的
row=row+5
col=col+5
)。在找到近位置之后,考虑该位置附近的特定邻域并对该特定作物的整个像素做一个循环以找到确切位置。< /P> < P>寻找“具有最大和的形状3x3的子阵列”。与使用非标准化的3x3长方体过滤器过滤后查找图像的最大值相同。因此,它归结为有效地找到图像的最大值,你假设它是一个(可能是“有噪声的”)基本连续平滑信号的离散样本,因此你希望找到一个亚像素位置

您确实需要将问题分为两部分:

  • 找到图像最大值的像素位置
    m=(xm,ym)
    。这只需要对图像中的每个像素进行一次访问,并对每个像素进行一次比较,因此它是O(N),因此只要您以本机图像分辨率操作,它就是最佳的。在OpenCv中,使用 功能
  • 应用您正在使用的图像的任何模型,以在m的邻域中找到其(亚像素插值)最大值 澄清第(2)点:你写

    我不想得到最大点,因为这会导致坐标不太精确。水滴的真实中心实际上可能在2个像素之间

    虽然从直觉上讲是合理的,但为了便于计算,这个断言需要更加精确。也就是说,您需要用数学方法表达您对图像所做的假设,这些假设使您能够搜索像素采样位置之间的“真实”最大值

    这种假设的一个简单例子是二次平滑。在这种情况下,您假设在“真实”最大位置的一个小(例如3x3,5x5)邻域中,图像信号
    z
    由二次曲线很好地近似:

    z = A00 dx^2 + A01 dx dy + A11 dy^2 + A02 dx + A12 dy + A22
    where:
    dx = x - xm; dy = y - ym
    
    由于泰勒级数定理,如果期望基础信号至少为三阶连续且可微,则该假设是有意义的。几何学上,这意味着你假设(希望?)信号看起来像一个二次曲面(抛物面或椭球体),接近其最大值

    然后,您可以为
    m
    邻域中的每个像素计算上述方程,替换
    z
    的实际图像值,从而获得未知Aij中的线性系统,方程数量与邻域像素数量相同(因此即使3x3邻域也会产生过度约束系统)。在最小二乘意义下求解系统会得到“最佳”系数Aij。该模型预测的理论最大值为一阶偏导数消失的位置:

    del z / del dx = 2 A00 dx + A01 dy = 0
    del z / del dy = A01 dx + 2 A11 dy = 0
    
    这是两个未知
    (dx,dy)
    中的一个线性系统,求解该系统可得出最大值的估计位置,并通过上述
    z
    方程得出最大值处的预测图像值


    就计算成本而言,与遍历中等大小的图像相比,所有此类模型估计速度都非常快。

    根据我对图像处理的了解,要获得适用于任何一个blob的可靠的结果,请执行以下步骤:

  • 使图像变灰如果图像尚未变灰(像素值0-255)
  • 使图像正常化,使像素强度覆盖0-255的整个范围
  • 将图像转换为二进制图像(像素为0或1)-这可以通过阈值化来实现,例如应用任何强度小于或等于127的像素均为零的规则