微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

图像X轴的导数中位数

如何解决图像X轴的导数中位数

我使用不同的方法来计算导数,例如:

  1. 与数组[[-1,1]]进行卷积
  2. 使用傅立叶定理,通过计算上述图像和阵列的DFT,将它们相乘并执行IDFT。
  3. 直接通过导数公式(计算傅立叶,乘以索引和常数并计算逆数)。

所有方法似乎几乎相同,但有细微差别。

最好解释一下为什么它们最终会有不同的结果。

计算完这些后,我开始研究结果以了解它,然后发现一些令我困惑的东西:

让我感到困惑的主要是,当我尝试计算该导数的中位数时,其始终为0.0。

那是为什么?

添加了用于计算此代码代码(至少是第一种方法),因为可能是我做错了。

from scipy.signal import convolve2d

im = sl.read_image(r'C:\Users\ahhal\Desktop\Essentials\Uni\year3\Semestera\ImageProcessing\Exercises\Ex2\external\monkey.jpg',1)


b = [[-1,1]]

print(np.median(convolve2d(im,b)))

输出:0.0

read_image函数是我自己的,这是实现:

from imageio import imread
from skimage.color import rgb2gray
import numpy as np
def read_image(filename,representation):
    """
    Receives an image file and converts it into one of two given representations.
    :param filename: The file name of an image on disk (Could be grayscale or RGB).
    :param representation: representation code,either 1 or 2 defining wether the output
    should be a grayscale image (1) or an RGB image (2). If the input image is grayscale,we won't call it with representation = 2.
    :return: An image,represented by a matrix of type (np.float64) with intensities
    normalized to the range [0,1].
    """
    assert representation in [1,2]

    # reads the image
    im = imread(filename)
    if representation == 1:  # If the user specified they need grayscale image,if len(im.shape) == 3:  # AND the image is not grayscale yet
            im = rgb2gray(im)  # convert to grayscale (**Assuming its RGB and not a different format**)

    im_float = im.astype(np.float64)  # Convert the image type to one we can work with.

    if im_float.max() > 1:  # If image values are out of bound,normalize them.
        im_float = im_float / 255

    return im_float

修改2: 我在几个不同的图像上进行了尝试,所有图像都得到了0.0。 我在示例中使用的图像是:

enter image description here

解决方法

我使用不同的方法来计算导数,例如:

  1. 与数组[[-1,1]]进行卷积。
  2. 使用傅立叶定理,通过计算上述图像和阵列的DFT,将它们相乘并执行IDFT。
  3. 直接通过导数公式(计算傅立叶,乘以索引和常数并计算逆数)。

这些导数方法都是近似的,并且有不同的假设:

  1. [[-1,1]]的卷积计算相邻元素之间的差异,

    derivative ~= data[n+1] − data[n]
    

    您可以将其解释为类似于使用线段对数据进行插值,然后采用该插值的导数:

    I(x) = data[n] + (data[n+1] − data[n]) * (x − n)
    

    因此,近似值假设基础函数是局部线性的。您可以通过泰勒展开来分析错误,以发现错误来自被忽略的高阶项。换句话说,只要函数没有强非线性项,则近似值是准确的。这是finite differences的简单情况。

  2. 这与1相同,除了具有不同的边界处理以处理图像边缘附近的样本卷积。默认情况下,scipy.signal.convolve2d进行零填充(尽管您可以使用boundary选项来选择其他方法)。但是,当通过DFT计算卷积时,隐式地边界处理是周期性的,在图像边缘处回绕。因此,由于边界处理的不同,边缘附近像素边缘的1和2的结果也不同。

  3. 在DFT表示下通过乘以iω来计算导数可以解释为类似于评估数据sinc interpolation的导数。 Sinc插值假定数据为band limited。误差来自超出奈奎斯特频率的光谱。特别是,如果从对象边界开始存在硬跳跃不连续性,则图像将不会受到带宽限制,并且基于DFT的导数在跳跃附近将具有相当大的误差,表现为振铃伪影。

让我感到困惑的主要是,当我尝试计算该导数的中位数时,其始终为0.0。

我不知道为什么会在这里发生,但并非总是如此。例如,如果每个图像行都是单位坡度data[n] = n,则除[[-1,1]]的卷积在所有地方都等于1,除非取决于边界处理(可能不在边缘),所以中位数为1

,

Pascal already gave a wonderful explanation导数的各种近似之间的差异。因此,我将集中在“为什么总是0.0?”问题。

仅通过近似,导数的中位数为0.0。在计算时,基于有限差分近似(方法1),我得到-5.15e-5作为中位数。接近零,但不完全是零。

在图像的均匀(平坦)区域(例如散焦背景)中,导数为0。图像中的其他特征倾向于同时具有正边缘和负边缘,从而使导数图像的直方图非常对称:

histogram of the derivative of OP's example image

这种对称性导致此类图像的中值(以及均值)接近于零。然而,这并非总是如此。例如,如果图像的左边缘比右边缘(或相反方向)亮,则图像上必须存在净梯度,从而导致均值或中位数不同于零。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。