0

假设我有一个 RGB 图像矩阵,我想在它上面应用一些空间过滤器。一般来说,我想应用元素操作(请注意,这是一项大学作业,我不允许使用图像处理工具箱中提供的任何内置函数)。我决定将过滤器编写为函数,然后将bsxfun这些函数应用于图像上。

一个简单的例子是:
我想将 50 添加到图像的所有灰度级,然后用 200 替换所有高于 200 的灰度级。这是我的代码:

a='C:\Users\sepideh\Desktop\IP_abadpour\S45C-113050518040.jpg';  
b=imread(a);  
b(:,:,1)=b(:,:,1)+50;  
b(:,:,2)=b(:,:,2)+50;  
b(:,:,3)=b(:,:,3)+50;  
c=reshape(b,[],1);  
d=bsxfun(@test,c,200);

test是这种形式的函数:

function Out = test(in,a)  
   if in>a
      in=200;
   end
   Out = in;
end  

此代码不起作用,因为在第二行“in > a”是一个具有 0 和 1 的矩阵(我的意思是所有元素都不是 1,也不应该是),因此调试器不会分支到if语句中。

你能指导我如何编写这个函数以及如何在图像上应用空间和傅立叶分析,而不影响性能和运行速度吗?

4

2 回答 2

1

因此,对于您发布的示例,您可以利用 matlab 中的大多数运算符本身在矩阵上工作的事实:

b=imread(a);
c = a + 50;
c(c > 200) = 200;

就这么简单。

对于过滤,如果你被允许,我会看看这个conv2功能。您可以通过这种方式进行空间滤波,而无需转换到频域(请记住,频域中滤波器的乘法与空间域中的卷积相同)。例如一个基本的低通滤波器:

lpf = ones(5)./25;
c(:,:,1) = conv2(b(:,:,1), lpf);
c(:,:,2) = conv2(b(:,:,2), lpf);
c(:,:,3) = conv2(b(:,:,3), lpf);
于 2013-06-24T09:42:29.030 回答
1

这里有几个建议:

  1. 首先,您不需要将 50 单独添加到 RGB 矩阵的每一层。你可以这样做:

    b = b + 50;
    
  2. 为什么b在传递给之前要重塑bsxfun?输出的大小和bsxfun你的图像一样,这里真的不需要重塑任何东西。

  3. 关于您的test功能,请注意状态的官方文档bsxfun

    形式为二进制元素的函数C = fun(A,B)接受任意但大小相等的数组AB并返回相同大小的输出。输出数组C中的每个元素都是对相应元素的操作的结果,A并且B仅。fun还必须支持标量扩展,这样如果AB是标量,C则将标量应用于另一个输入数组中的每个元素的结果。

    所以bsxfun执行单例扩展并将其两个输入数组“膨胀”到相同的大小,然后将指定的函数应用于膨胀的数组。实际上,逐元素函数fun作用于数组,而不是标量。我看不到在bsxfun这里就业有任何实际收益。

    也就是说,您可以按照Dan的建议简化代码,或者将其实现为函数:

    function out = test(in, a);
        out = in;
        out(in > a) = a;
    

    我假设如果您使用值 210 而不是 200,那么您也希望使用 210 来限制所有灰度级,因此您应该真正使用a而不是硬编码值 200。您还可以编写函数,如所以:

    function out = test(in, a)
        out = min(in, a);
    

    然后调用它:

    d = test(b, 200);
    

    而不是更复杂d = bsxfun(@test, b, 200)

    另一种选择是使用arrayfun

    d = arrayfun(@(x)test(x, 200), a);
    

    或者

    d = arrayfun(@test, a, 200 * ones(size(a)));
    

    其中arrayfun将按test元素应用,并且该test函数只需要对标量进行操作。但是,arrayfun通常运行速度比循环慢,更不用说矢量化操作了。

  4. 对于空间分析,请按照Danconv2的建议进行检查(或实施您自己的 2-D 卷积,以方便练习)。对于傅立叶分析,请考虑在频域中使用和函数。fft2ifft2

希望这可以帮助!

于 2013-06-24T09:53:45.677 回答