【问题标题】:Matrix operations, scaling and nearest neighbor (no loops)矩阵运算、缩放和最近邻(无循环)
【发布时间】:2017-11-24 20:06:39
【问题描述】:

我正在尝试在 Matlab 上实现用于缩放图片的最近邻算法。我试图在不使用任何循环的情况下实现它——因为从我收集到的信息来看,使用矩阵可以极大地提高性能。 我真的很难找到如何做到这一点。我认为这应该是正确的程序:

  1. 求缩放后图片的宽高比
  2. 计算包含每个单元格最近邻索引的维度矩阵(width*scaleheight*scale
  3. 将此矩阵应用于起始图片(的矩阵)以获得缩放的图片

我对矩阵及其运算在 Matlab 中的工作方式感到非常困惑。

这就是我使用循环的方式:

x_ratio = width/(width*scale);
y_ratio = height/(height*scale);

for i=1:1:width
  for j=1:1:height
    x=i*x_ratio;
    y=j*y_ratio;
    out_image(i, j) = image(x, y);
  end
end

到目前为止,我已经设法发现它也应该适用于矩阵:

q =
  2×2 char array

    'ab'
    'cd'

>> q([1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4])

ans =

  4×4 char array

    'aabb'
    'aabb'
    'ccdd'
    'ccdd'

我的第一个问题是:为什么[1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4] 会产生正确的结果,而它表示为:

>> [1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4]

ans =

     1     1     3     3
     1     1     3     3
     2     2     4     4
     2     2     4     4

我认为传递给q 的正确矩阵是:

>> [1 1 2 2; 1 1 2 2; 3 3 4 4; 3 3 4 4]

ans =

     1     1     2     2
     1     1     2     2
     3     3     4     4
     3     3     4     4

其中,所有索引都表示来自q 矩阵的正确索引。但如果我这样做,我会得到一个矩阵,其中 cb 是倒置的,并且是错误的:

>> q([1 1 2 2; 1 1 2 2; 3 3 4 4; 3 3 4 4])

ans =

  4×4 char array

    'aacc'
    'aacc'
    'bbdd'
    'bbdd'

这似乎……违反直觉。据我了解,[1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4] 中的每个分号都表示一行或一个水平向量。那么为什么当传递给另一个矩阵时,它似乎确实表示垂直向量或列? (如果我不是完全失明,这似乎是它在这种情况下的行为方式,考虑到我传递给较小矩阵的向量作为列的索引)。

其次,如何计算[1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4] 矩阵?或者更一般地说,我需要按照最近邻规则计算线性索引的矩阵,这就是我在第一个带有嵌套循环的代码块中所做的。我认为这将是关键点,但我对如何概括使用矩阵的过程一无所知。使用循环,我将传入缩放矩阵的每个单元格并计算原始矩阵的哪个对应单元格去哪里。因此,例如,如果我在哪里检查scaled_matrix(i, j),我会知道在那个单元格中我必须输入orig_matrix(i*x_ratio, j*y_ratio),等等。我的想法是计算包含所有正确索引的scaled_matrix,然后继续。

【问题讨论】:

  • 您可以使用两个向量进行索引,一个用于所有行,一个用于所有列。您将分别计算行/列索引,例如在 Y 和 X 中,然后执行 image(Y,X)

标签: image matlab matrix


【解决方案1】:

question 讨论了您的第一个问题的答案。 Matlab 以column-major 的顺序存储它的矩阵。所以对于你的字符数组q

q(1) = 'a'
q(2) = 'c'
q(3) = 'b'
q(4) = 'd'

这就是为什么将q 缩放到 4x4 的正确矩阵确实是 [1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4] 而不是其他矩阵。

您的第二个问题已经在"Nearest-neighbor interpolation algorithm in MATLAB" 帖子中有答案。该帖子中接受的答案没有使用您想要的任何循环。

【讨论】:

  • 谢谢,我不知道主要的专栏。但是为什么当我打印[1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4] 时,它没有打印为[1 1 3 3] 是一列,而是一行(就像我提供的示例中一样)?另外,查看内存中的变量,我看到[1 1 3 3] 是一行,而不是一列。这是否意味着[1 1 3 3] 仅在涉及线性索引计算时才被视为列?
  • 对于第二个问题,我在 OP 中添加了更多详细信息。我会更好地了解克罗内克张量积 - 我不知道那个!
  • 你是对的。只有在处理线性索引时,我们才需要注意以列为主的内存布局。
  • 谢谢,我终于明白它是如何工作的了!最后一个问题:如果我将一个更大的矩阵传递给一个矩阵(例如在我的示例中使用q[1 1 3 3; 1 1 3 3; 2 2 4 4; 2 2 4 4]),得到的矩阵是否等于两者之间的克罗内克张量积?
  • 您可以在this 页面上查看有关 Kronecker-Delta 产品的示例。它将矩阵的每个元素与另一个矩阵相乘。传递一个较大的矩阵 B,其元素在较小矩阵 A 的索引的适当范围内,作为矩阵 A 的索引返回一个与 B 大小相同的矩阵,使得 B 的每个元素 B(i) 被相应的元素替换的A( B(i) )。这比 Kronecker 张量积更通用。
猜你喜欢
  • 2017-08-06
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 2017-12-18
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多