代码之家  ›  专栏  ›  技术社区  ›  Alex Feinman

在matlab中把函数分布在数组的一维上?

  •  7
  • Alex Feinman  · 技术社区  · 15 年前

    我经常发现自己想要用一个自定义函数在一个维度上折叠一个n维的矩阵,并且不知道是否有一个简明的咒语可以用来做这个。

    例如,在分析一个图像时,我经常想做这样的事情。(注意!仅举例说明。我知道 rgb2gray 针对这种特定情况。)

    img = imread('whatever.jpg');
    s = size(img);
    for i=1:s(1)
      for j=1:s(2)
        bw_img(i,j) = mean(img(i,j,:));
      end
    end
    

    我想表达如下:

    bw = on(color, 3, @mean);
    

    bw(:,:,1) = mean(color);
    

    有没有捷径?


    编辑:显然 mean 已经这样做了;我希望能够为我编写的任何函数这样做。例如。,
    ...
      filtered_img(i,j) = reddish_tint(img(i,j,:));
    ...
    

    哪里

    function out = reddish_tint(in)
      out = in(1) * 0.5 + in(2) * 0.25 + in(3) * 0.25;
    end
    
    5 回复  |  直到 8 年前
        1
  •  7
  •   gnovice    15 年前

    许多基本的matlab函数,比如 MEAN , MAX , MIN , SUM 等,设计用于在特定尺寸范围内操作:

    bw = mean(img,3);  %# Mean across dimension 3
    

    你也可以利用 MATLAB arithmetic operators 设计为在矩阵上以元素方式操作。例如,函数中的操作 reddish_tint 可以应用于图像的所有像素,使用此单行:

    filtered_img = 0.5.*img(:,:,1)+0.25.*img(:,:,2)+0.25.*img(:,:,3);
    

    要处理一个更一般的情况,即要将函数应用于n维矩阵的任意维,您可能需要编写函数,以便它接受一个额外的输入参数,该参数的维可以操作(如上述matlab函数),然后使用一些简单的逻辑(即,如果其他状态以及元素矩阵运算,将其计算应用于矩阵的适当维度。

    虽然我不建议使用它,但是 一个快速和肮脏的解决方案,但它相当丑陋和计算上更昂贵。你可以使用这个功能 NUM2CELL 要沿着数组的维度将值收集到单元格数组的单元格中,然后使用函数将函数应用于每个单元格 CELLFUN :

    cellArray = num2cell(img,3);  %# Collect values in dimension 3 into cells
    filtered_img = cellfun(@reddish_tint,cellArray);  %# Apply function to each cell
    
        2
  •  6
  •   Jav_Rock Rahul N    12 年前

    我写了一个名为“vecfun”的助手函数,如果这是你想要实现的,它可能对这个有用。

    link

        3
  •  4
  •   Jonas    15 年前

    你可以使用 BSXFUN 至少你的一些任务。它通过展开大小为1的维度来匹配另一个数组中的大小,从而在两个数组之间执行元素操作。“淡红色”功能将变为

    reddish_image = bsxfun(@times,img,cat(3,0.5,0.25,0.25));
    filtered_img = sum(reddish_image,3);
    

    以上所有的陈述都要求工作的第三个维度是 img 尺寸为1或3。其他尺寸的数量和尺寸可自由选择。

        4
  •  3
  •   BlessedKey    15 年前

    如果您一直试图将函数应用于由图像块中的三维组成的向量,我建议您使用一对重塑,例如:

    Img = rand(480,640,3);
    
    sz = size(Img);
    output = reshape(myFavoriteFunction(reshape(Img,[prod(sz(1:2)),sz(3)])'),sz);
    

    这样,您就可以交换在矩阵第一维上操作的任何函数。

    编辑。 如果输入只有一层的图像,上面的代码将崩溃:下面的函数可以修复它。

    function o = nLayerImage2MatrixOfPixels(i)
    %function o = nLayerImage2MatrixOfPixels(i)
    s = size(i);
    if(length(s) == 2)
      s3 = 1;
    else
      s3 = s(3);
    end
    o = reshape(i,[s(1)*s(2),s(3)])';
    
        5
  •  2
  •   High Performance Mark    15 年前

    好吧,如果你只关心向量相乘,你可以用点积,就像这样:

    bw(:,:,1)*[0.3;0.2;0.5]
    

    注意向量的形状要一致。