创建滤波器的拉普拉斯矩阵并求解图像滤波的线性方程

时间:2014-06-03 13:41:12

标签: matlab image-processing optimization mathematical-optimization

我有一个要解决的优化问题,以便过滤图像 我创建了一个处理稀疏矩阵的问题的线性方程。

首先我会说明问题 首先,问题的拉普拉斯(Adjracncy)矩阵:

enter image description here

矩阵Dx / Dy是前向差分算子 - >因此,它的转置是向后差分算子 矩阵Ax / Ay是对角矩阵,其权重是图像梯度的函数(点的方式,即值仅取决于该像素自身的梯度)。
权重是:
enter image description here
其中Ix(i)是第i个像素处输入图像的水平渐变(当您对输入图像进行矢量化时)。

假设输入图像G - > g = vec(G)= G(:)。
我想找到并形象U - > u = vec(U)= U(:) s.t。:

enter image description here

我的问题是:

  1. 如何有效地构建矩阵Dx / Dy / Ax / Ay(它们都是稀疏的)?
  2. 通过设置M =(I + \ lambda * {L} _ {g}),是否有直接创建M的优化方法?
  3. 在MATLAB中解决这个线性问题的最佳方法是什么?有没有办法通过内存限制(即,处理大图像,仍然能够解决它)?
  4. 是否有一个开源库可以在有限的内存资源下解决它?任何带有MATLAB API的库?
  5. 谢谢。

1 个答案:

答案 0 :(得分:1)

鉴于您的意见,让我们在概要中回答每个问题并从那里开始:

  1. 我将使用sparse和其他相关功能
  2. 回答下面的问题
  3. 使用(1),我们绝对可以以优化的方式构建M
  4. 简单地说,在解决逆操作时,\ operator是最好的选择。 MathWorks花了很多时间来尝试优化它,它几乎使用了LAPACK和BLAS,你不会使用它。在(4)中回答了你无法使用它的唯一时间。
  5. 有一些MATLAB脚本可以处理矩阵迭代,就像连续过度放松技术一样,但是你应该只在内存不足的情况下使用它们(例如,如果没有#n给你一个答案)。由于矩阵的稀疏表示,这不应该(希望)发生,所以现在让我们避免使用这些函数。
  6. 回到你的问题,我们可以很好地产生L_g的稀疏表示。根据{{​​1}}和Dx的定义,我们可以使用名为Dy的{​​{1}}命令的稀疏版本。因此,eyespeye可以通过Dx来计算。例如,如果您尝试在7 x 5图像上执行此操作,则会生成此内容。

    Dy

    如您所见,我们仅引用非零条目。第1行,第1列的系数为-1,第1行,第2列的系数为1,依此类推。对于您的Dx = diff(speye(size(inputImage)));>> diff(speye(7,5)) ans = (1,1) -1 (1,2) 1 (2,2) -1 (2,3) 1 (3,3) -1 (3,4) 1 (4,4) -1 (4,5) 1 (5,5) -1 ,这也非常容易。我们有一个对角矩阵,我们可以手动设置每个条目。我们要做的就是指定一组行索引,列索引以及每个点的值。因此,我们可以通过以下方式实现:

    Ax

    第一次调用的原因是因为我们要确保像素具有双精度,因为在MATLAB中查找反转需要您执行此操作。它还确保我们不会溢出类型,因为我们正在调整0到1之间的强度。您可能需要调整标准偏差来反映这一点。现在我们只需要构建我们的AyinputImage = im2double(inputImage); %//Important rows = 1 : numel(inputImage); %// Assuming a 2D matrix cols = rows; % // Row and column indices are the same valuesDx = exp(-(gradX(rows).^2 / 2*sigma*sigma )); valuesDy = exp(-(gradY(rows).^2 / 2*sigma*sigma )); 矩阵,并让我们将其与AxAy放在一起:

    Dx

    我将Dy转置为numberElements = numel(inputImage); Ax = sparse(rows, cols, valuesDx, numberElements, numberElements); Ay = sparse(rows, cols, valuesDy, numberElements, numberElements); identity = speye(numberElements, numberElements); Dx = diff(identity); Dy = Dx.'; %// Transpose 的原因是因为垂直方向上的差值运算符应该只是转置(对我来说很有意义)。这些都应该是您想要的每个矩阵的稀疏表示。矩阵运算也可以在稀疏矩阵上执行,包括乘法和逆运算。就这样:

    Dx

    您现在可以通过以下方式解决Dy

    Lg = Dx.' * Ax * Dx + Dy.' * Ay * Dy;
    

    这假定u以图像中的像素构成 column-major 格式。我对构建u = (identity + lambda*Lg) \ g; g的像素进行采样的方式自然就是这样。因此,请Ax,假设我们已经转换为double并在0和1之间归一化。

    当您最终解决Ay时,您可以通过执行以下操作将其重塑为图像:

    g = inputImage(:);

    u也可能是稀疏的,因此如果您想要恢复原始图片,请使用u = reshape(u, size(inputImage, 1), size(inputImage, 2)); 进行投射:

    u

    希望这有帮助!