【问题标题】:Matlab: trouble with taking derivative of image?Matlab:获取图像导数的麻烦?
【发布时间】:2016-06-14 19:01:41
【问题描述】:

因此,我需要对图像在 x 方向上的导数进行此分配,目的是获得某种形式的渐变。我的想法是在图像的每一行上使用 diff(command),然后应用高斯滤波器。我还没有开始第二部分,因为第一部分给我带来了麻烦。在尝试获得 x 导数时,我有:

origImage = imread('TightRope.png');

for h = 1:3 %%h represents color channel
    for i = size(origImage,1)
        newImage(i,:,h) = diff(origImage(i,:,h));  %%take derivative of row and translate to new row 
    end
end

问题出在我得到错误“下标分配维度不匹配”的过程中。

Error in Untitled2 (line 14)
    newImage(i,:,h) = diff(origImage(i,:,h));

有没有人知道为什么会发生这种情况以及我的方法对于获得梯度/高斯导数是否正确?

【问题讨论】:

    标签: matlab image-processing filtering gaussian


    【解决方案1】:

    为什么不将fspecialimfilter 一起使用?

    figure;
    
    I = imread('cameraman.tif');
    
    subplot 131; imshow(I); title('original')
    
    h = fspecial('prewitt');
    derivative = imfilter(I,h','replicate'); %'
    
    subplot 132; imshow(derivative); title('derivative')
    
    hsize = 5;
    sigma = 1;
    
    h = fspecial('gaussian', hsize, sigma) ;
    gaussian = imfilter(derivative,h','replicate'); %'
    
    subplot 133; imshow(gaussian); title('derivative + gaussian')
    

    结果如下:

    【讨论】:

    • 应该提到分配指令我不允许,我需要自己制作过滤器和卷积循环。
    • 看看“索贝尔变换”。为该算法编写代码很容易。
    【解决方案2】:

    如果您的目标是使用diff 生成导数而不是创建循环,您可以告诉diff 为您提供x 方向(沿维度2)的导数:

    newImage = diff(double(origImage), 1, 2);
    

    1 用于一阶导数,2 用于沿第二维的导数。见diff

    正如@rayryeng 在他的回答中提到的那样,将图像投射为double 很重要。

    【讨论】:

      【解决方案3】:

      给定一个 N 元素向量,diff 返回一个 N-1 长度向量,所以你得到对齐不匹配的原因是因为你试图将 diff 的输出分配到不正确的数量插槽。具体来说,假设N 是总列数,您在1 X N 向量上使用diff,从而返回1 x (N - 1) 向量,并且您尝试将此输出作为单行分配到输出图像中预计为1 x N。缺少的元素导致对齐不匹配。 diff 的工作原理是将向量中的元素对相减以产生新元素,这就是最终输出中缺少一个元素的原因。

      如果您想让您的代码正常工作,一种方法是在图像或信号向量的每一行中填充一个额外的零(例如)作为diff 的输入。像这样的东西可以工作。请注意,我会将您的图像转换为 double 以允许导数采用负值:

      origImage = imread('...'); %// Place path to image here and read in
      origImage = im2double(origImage); %// Change - Convert to double precision
      newImage = zeros(size(origImage)); %// Change - Create blank new image and populate each row per channel manually
      
      for h = 1:3 %%h represents color channel
          for ii = 1:size(origImage,1) %// Change - fixed for loop iteration
              newImage(ii,:,h) = diff([0 origImage(ii,:,h)]); %// Change
          end
      end
      

      请注意,您的 for 循环不正确,因为它没有遍历每一行...只是最后一行。

      当我使用图像处理工具箱中的onion.png 图像时:

      ...当我运行此代码时,我使用imshow(newImage,[]); 获取此图像:

      请注意,差异过滤器是单独应用于每个通道的,我更改了每个通道的强度,以便将最小值映射到 0,将最大值映射到 1。如何解释此图像是任何区域具有非黑色具有一些非零差异,因此这些区域正在进行一些活动,任何具有深色/黑色的区域都意味着这些区域没有活动。请注意,我们应用了水平过滤器,因此如果您想垂直执行此操作,您只需重复该行为,但按列应用此操作,而不是像上面那样按行应用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-05
        • 2011-07-10
        • 1970-01-01
        • 2019-08-08
        相关资源
        最近更新 更多