Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab中一组图像滤波器的应用_Matlab_Image Processing_Filtering_Vectorization_Convolution - Fatal编程技术网

Matlab中一组图像滤波器的应用

Matlab中一组图像滤波器的应用,matlab,image-processing,filtering,vectorization,convolution,Matlab,Image Processing,Filtering,Vectorization,Convolution,我需要使用Matlab中的一组滤波器对图像进行滤波。我的第一次尝试是使用一个简单的for循环为银行中的每个过滤器重复调用“imfilter”函数 对于我的申请,我需要多次重复这个过程,所以我需要尽可能提高这个步骤的效率。因此,我想知道是否有任何方法可以将此操作矢量化以加快此过程。为了简化工作,我所有的过滤器内核都是相同大小的(9x9) 作为一个示例,我的过滤器设置在一个9x9x32元素块中,需要应用于我的图像。我曾考虑将图像复制到一个块中(例如100x100x32),但我不确定是否有一种方法可以

我需要使用Matlab中的一组滤波器对图像进行滤波。我的第一次尝试是使用一个简单的for循环为银行中的每个过滤器重复调用“imfilter”函数

对于我的申请,我需要多次重复这个过程,所以我需要尽可能提高这个步骤的效率。因此,我想知道是否有任何方法可以将此操作矢量化以加快此过程。为了简化工作,我所有的过滤器内核都是相同大小的(9x9)


作为一个示例,我的过滤器设置在一个9x9x32元素块中,需要应用于我的图像。我曾考虑将图像复制到一个块中(例如100x100x32),但我不确定是否有一种方法可以应用卷积之类的操作,而不必求助于循环。有人对解决这个问题的好方法有什么建议吗?

除了预先分配空间之外,没有更快的方法可以得出准确的解决方案。如果近似值是确定的,那么您可能能够将32个过滤器分解为一组数量较少的过滤器的线性组合,例如8个。例如,请参见Steerable筛选器

编辑:这里有一个工具可以帮助对图像应用过滤器

function FiltIm = ApplyFilterBank(im,filters)
%#function FiltIm = ApplyFilterBank(im,filters)
%#
%#assume im is a single layer image, and filters is a cell array

nFilt = length(filters);
maxsz = 0;
for i = 1:nFilt
  maxsz = max(maxsz,max(size(filters{i})));
end
FiltIm = zeros(size(im,1), size(im,2), nFilt);
im = padimage(im,maxsz,'symmetric');
for i = 1:nFilt
  FiltIm(:,:,i) = unpadimage(imfilter(im,filters{i}),maxsz);
end

function o = padimage(i,amnt,method)
%#function o = padimage(i,amnt,method)
%#
%#padarray which operates on only the first 2 dimensions of a 3 dimensional
%#image. (of arbitrary number of layers);
%#
%#String values for METHOD
%#        'circular'    Pads with circular repetion of elements.
%#        'replicate'   Repeats border elements of A.
%#        'symmetric'   Pads array with mirror reflections of itself. 
%#
%#if(amnt) is length 1, then pad all sides same amount
%#
%#if(amnt) is length 2, then pad y direction amnt(1), and x direction amnt(2)
%#
%#if(amnt) is length 4, then pad sides unequally with order LTRB, left top right bottom
if(nargin < 3)
   method = 'replicate';
end
if(length(amnt) == 1)
  o = zeros(size(i,1) + 2 * amnt, size(i,2) + 2* amnt, size(i,3));
  for n = 1:size(i,3)
    o(:,:,n) = padarray(i(:,:,n),[amnt,amnt],method,'both');
  end
end
if(length(amnt) == 2)
  o = zeros(size(i,1) + 2 * amnt(1), size(i,2) + 2* amnt(2), size(i,3));
  for n = 1:size(i,3)
    o(:,:,n) = padarray(i(:,:,n),amnt,method,'both');
  end
end
if(length(amnt) == 4)
  o = zeros(size(i,1) + amnt(2) + amnt(4), size(i,2) + amnt(1) + amnt(3), size(i,3));
  for n = 1:size(i,3)
    o(:,:,n) = padarray(padarray(i(:,:,n),[amnt(2), amnt(1)],method,'pre'),[amnt(4),     amnt(3)],method,'post');
  end
end

function o = unpadimage(i,amnt)
%#un does padimage
%#if length(amnt == 1), unpad equal on each side
%#if length(amnt == 2), first amnt is left right, second up down
%#if length(amnt == 4), then [left top right bottom];

switch(length(amnt))
case 1
  sx = size(i,2) - 2 * amnt;
  sy = size(i,1) - 2 * amnt;
  l = amnt + 1;
  r = size(i,2) - amnt;
  t = amnt + 1;
  b = size(i,1) - amnt;
case 2
  sx = size(i,2) - 2 * amnt(1);
  sy = size(i,1) - 2 * amnt(2);
  l = amnt(1) + 1;
  r = size(i,2) - amnt(1);
  t = amnt(2) + 1;
  b = size(i,1) - amnt(2);
case 4
  sx = size(i,2) - (amnt(1) + amnt(3));
  sy = size(i,1) - (amnt(2) + amnt(4));
  l = amnt(1) + 1;
  r = size(i,2) - amnt(3);
  t = amnt(2) + 1;
  b = size(i,1) - amnt(4);
otherwise
  error('illegal unpad amount\n');
end
if(any([sx,sy] < 1))
    fprintf('unpadimage newsize < 0, returning []\n');
    o = [];
    return;
end

o = zeros(sy, sx, size(i,3));
for n = 1:size(i,3)
  o(:,:,n) = i(t:b,l:r,n);
end
函数filterm=ApplyFilterBank(im,过滤器)
%#函数FiltIm=ApplyFilterBank(im,过滤器)
%#
%#假设im是单层图像,而过滤器是单元阵列
nFilt=长度(过滤器);
maxsz=0;
对于i=1:nFilt
maxsz=max(maxsz,max(大小(过滤器{i}));
结束
FiltIm=零(大小(im,1),大小(im,2),nFilt);
im=padimage(im,maxsz,'symmetric');
对于i=1:nFilt
FiltIm(:,:,i)=unpadimage(imfilter(im,filters{i}),maxsz);
结束
函数o=padimage(i,amnt,方法)
%#函数o=padimage(i,amnt,方法)
%#
%#仅在三维阵列的前二维上运行的焊盘阵列
%#形象。(任意层数);
%#
%#方法的字符串值
%#“圆形”垫,具有圆形重复元素。
%#“复制”重复A的边界元素。
%#“对称”焊盘阵列具有自身的镜像反射。
%#
%#如果(amnt)长度为1,则所有边的填充量相同
%#
%#如果(amnt)长度为2,则焊盘y方向amnt(1)和x方向amnt(2)
%#
%#如果(amnt)长度为4,则焊盘两侧不相等,顺序为LTRB,左上右下
if(nargin<3)
方法='复制';
结束
如果(长度(amnt)=1)
o=零(大小(i,1)+2*amnt,大小(i,2)+2*amnt,大小(i,3));
对于n=1:尺寸(i,3)
o(:,:,n)=焊盘阵列(i(:,:,n),[amnt,amnt],方法,'both');
结束
结束
如果(长度(amnt)=2)
o=零(大小(i,1)+2*amnt(1),大小(i,2)+2*amnt(2),大小(i,3));
对于n=1:尺寸(i,3)
o(:,:,n)=padarray(i(:,:,n),amnt,method,'both');
结束
结束
如果(长度(amnt)=4)
o=零(大小(i,1)+amnt(2)+amnt(4),大小(i,2)+amnt(1)+amnt(3),大小(i,3));
对于n=1:尺寸(i,3)
o(:,:,n)=焊盘阵列(焊盘阵列(i(:,:,n),[amnt(2),amnt(1)],方法,'pre'),[amnt(4),amnt(3)],方法,'post');
结束
结束
函数o=取消复制图像(i,amnt)
%#联合国不支持这个形象
%#如果长度(amnt==1),则在每一侧取消加载相等
%#如果长度(amnt==2),则第一个amnt为左-右,第二个为上-下
%#如果长度(amnt==4),则为[左上右下];
开关(长度(amnt))
案例1
sx=尺寸(i,2)-2*amnt;
sy=尺寸(i,1)-2*amnt;
l=amnt+1;
r=尺寸(i,2)-amnt;
t=amnt+1;
b=尺寸(i,1)-amnt;
案例2
sx=尺寸(i,2)-2*amnt(1);
sy=尺寸(i,1)-2*amnt(2);
l=amnt(1)+1;
r=尺寸(i,2)-amnt(1);
t=amnt(2)+1;
b=尺寸(i,1)-amnt(2);
案例4
sx=尺寸(i,2)-(amnt(1)+amnt(3));
sy=尺寸(i,1)-(amnt(2)+amnt(4));
l=amnt(1)+1;
r=尺寸(i,2)-amnt(3);
t=amnt(2)+1;
b=尺寸(i,1)-amnt(4);
否则
错误('unpad amount非法\n');
结束
如果(任何([sx,sy]<1))
fprintf('unpadimagenewsize<0,返回[]\n');
o=[];
返回;
结束
o=零(sy,sx,大小(i,3));
对于n=1:尺寸(i,3)
o(:,:,n)=i(t:b,l:r,n);
结束
新答案:使用colfilt()或块过滤样式。Matlab可以将图像转换为大型矩阵,其中每个不同的9x9像素区域是一列(81个元素)。使用im2col()方法进行设置。如果图像是N乘M,则结果矩阵将是81 X(N-8)*(M-8)

然后,您可以将所有过滤器连接到单个矩阵(每个过滤器都是一行)并将这些巨大的矩阵相乘。这将为您提供所有过滤器的结果。现在,您必须从结果矩阵中重建32个结果图像。使用col2im()方法。 有关详细信息,请键入“doc colfilt”

此方法的工作速度几乎与mex文件一样快,并且不需要任何“for”循环

旧答案:

您希望为过滤器组合获得不同的32个结果还是单个结果? 如果这是一个太阳光的结果比有一个简单的方法。 如果使用线性滤波器(如卷积),则将滤波器逐个应用。最后在图像上应用结果过滤器。因此,图像将只卷积一次。 如果过滤器是对称的(x和y方向),则不应用9x9过滤器,而是在y方向应用9x1,在x方向应用1x9。工作快一点。
最后,您可以尝试使用Mex文件

看起来您提供的代码与我已经在做的基本相同,但是过滤器存储为单元格数组而不是3D块。我想我对没有更快的方法来做这个手术并不感到震惊,但我希望我可能遗漏了什么。目前,此操作占用了我程序中80%的处理时间。我应该澄清:我需要为每个过滤器分别输出图像,而不是简单地将所有过滤器依次应用于图像。谢谢!这正是我一直在寻找的答案。作为这个问题的补充:我意识到在频域滤波可能比在空域卷积更好。我还没有实际测试过这个,但我想我应该可以接受t