matlab parfor循环中的图像损坏

时间:2015-09-02 16:32:33

标签: matlab image-processing parallel-processing filtering parfor

我有一些自适应中值滤波器的代码(见下文),它完全有效,直到我尝试将其作为并行循环运行,在这种情况下,有值丢失或损坏,最后得到的图像不正确(见http://i.stack.imgur.com/Rt6dV.jpg)。

Matlab不会抛出任何错误,但似乎是丢弃随机数据或覆盖它们。我唯一能找到甚至模糊地匹配这个问题的是关于自定义类型定义和设置函数的信息,但是我的所有输入图像都是uint8所以我没有任何自定义集函数或类型定义。 (http://fluffynukeit.com/problems-with-matlab-parfor-data-disappearing/

当我尝试更改

时,错误发生在第63行和第86行之间
    for Index = 1:length(ss)

    parfor Index = 1:length(ss)

我无法为我的生活找出原因。

我通常使用uint8格式的图像调用该函数(虽然任何格式都可以使用),w_size是与过滤窗口大小相关的奇数,M可以设置为0到2,其中较小的数字通过增加当前块的标准偏差的权重来减少在中值滤波时考虑的像素量。因此,典型的函数调用将是:

I = imread('image.tif');
J =  Par_AMF(I, 5, 1);
figure;
imshow(J)

我应该说,通常我正在使用的图像大小使并行处理节省了大量时间,通常是非并行执行时间的一半,所以尽管对于较小的图像没有多少意义我正在使用的那些将真正受益于它。

function [FIm] = Par_AMF(Im, w_size, M)
% PAR_AMF Adaptive median filter
%   Performs a local adaptive median filtering operation
%   Inputs: Im - Image to be filtered
%           w_size - Window size for filter
%           M - Sigma weighting, range from 0 to 2
%
%   Output: FIm - Filtered image

tic;
sz_oldim = size(Im);
w_option = floor(w_size/2);

% ----------------------------------------------------------------------- %
% Padding edges of image matrix
Pad_im = padarray(Im,[w_option, w_option],0,'both');

% ----------------------------------------------------------------------- %
% Stage 1
% Calculate the local Mean and Standard Deviation for finding Speckle
% Pixels
% ----------------------------------------------------------------------- %
sz = size(Pad_im);
start_index = w_option+1;
end_index1=(sz(1)-w_option);
end_index2=(sz(2)-w_option);
LB = zeros(sz_oldim);
UB = LB;
first_loop1 = start_index:end_index1;
first_loop2 = start_index:end_index2;
ss = cell(numel(LB), 1);
Index = 1;

for c = first_loop2
    for r = first_loop1
        ss{Index} = Pad_im(r-w_option:r+w_option,c-w_option:c+w_option);
        Index = Index+1;
    end
end

% This parfor functions as expected:
parfor Index = 1:length(ss)
    ss1=ss{Index}(:);
    if any(ss1 > 0)
        local_mn = mean(ss1);
        local_sig = std(double([ss1;local_mn]));
        LB(Index) = local_mn - (M*local_sig);
        UB(Index) = local_mn + (M*local_sig);
    end
end


% ----------------------------------------------------------------------- %
% UB is the Upper Bound Limit; LB is the Lower Bound Limit
% ----------------------------------------------------------------------- %

% ----------------------------------------------------------------------- %
% Using UB and LB mark pixels as speckle or valid pixels and update only if
% central pixel of window is speckle pixels with median value calculated
% again with only speckle pixels with the window
% ----------------------------------------------------------------------- %
TempOut = Im;

% When this for loop is changed to a parfor (which should definitely work)
% the output is corrupted horribly:
% parfor Index = 1:length(ss)
for Index = 1:length(ss)
    ss1 = ss{Index}(:);
    ss2 = ss1;

    if any(ss1>0)
        zz = 0;
        for z = 1:length(ss1)
            if (ss1(z) < LB(Index) || ss1(z) > UB(Index))
                ss1(z) = 0;
                ss2(z) = 0;
            else
                ss1(z)=1;
                zz= zz+1;
            end
        end
        if zz > 0
            new_ss1 = ss2(ss2~=0);
            if(ss1(ceil(length(ss1)/2)) == 0)
                md = median(new_ss1);
                TempOut(Index) = md;
            end
        end
    end
end

looptime = toc;
disp(['Total processing time ', num2str(looptime./60), ' minutes'])
FIm = TempOut;
end

编辑:在Matlab版本R2015a

0 个答案:

没有答案