Алгоритм обработки изображений в MATLAB

Я пытаюсь реализовать алгоритм, описанный в этой статье:

Разложение изображений биосфелей во временных спектральных диапазонах

Вот объяснение алгоритма:

Мы записали последовательность N последовательных спекл-изображений с выборкой частота fs. Таким образом, можно было наблюдать, как пиксель развивается через изображения N. Эту эволюцию можно рассматривать как время серии и может обрабатываться следующим образом: каждый сигнал соответствующие эволюции каждого пикселя, использовались в качестве входных данных для банка фильтров. Значения интенсивности ранее были разделены их временное среднее значение для минимизации локальных различий в коэффициенте отражения или освещение объекта. Максимальная частота, которая может быть адекватно анализируемый, определяется теоремой выборки и с половиной частоты дискретизации fs. Последний установлен камерой CCD, размер изображения и граббер. Банк фильтров как показано на рисунке 1.

bank of filters

В нашем случае десять фильтров Баттерворта порядка 5 °, но это число можно варьировать в соответствии с требуемым дискриминация. Банк был реализован на компьютере с использованием MATLAB программного обеспечения. Мы выбрали фильтр с маслом, потому что, помимо его простота, она максимально плоская. Другие фильтры, бесконечный импульс ответ или конечный импульсный отклик.

С помощью этого банк фильтров, десять соответствующих сигналов каждого фильтра каждого временная эволюция пикселей была получена как выход. Средняя энергия Eb в каждом сигнале затем рассчитывали:

energy equation

где pb(n) - интенсивность отфильтрованного пикселя в n-м изображении для фильтра b, деленного на его среднее значение, а N - общее количество изображений. Таким образом, были получены значения энергии для каждого пикселя Enкаждый из краев, принадлежащих одной из полос частот на фиг .1.

С этими значениями можно построить десять изображений активного объекта, каждый из которых показывает, сколько энергии изменяющегося во времени спекл находится в определенной полосе частот. Ложное присвоение цвета серому уровни результатов будут способствовать дискриминации.

и вот моя база кода MATLAB:

for i=1:520
    for j=1:368
        ts = [];
        for k=1:600
            ts = [ts D{k}(i,j)]; %%% kth image pixel i,j --- ts is time series
        end
        ts = double(ts);
          temp = mean(ts);        
           if (temp==0)
                for l=1:10
                    filtImag1{l}(i,j)=0;
                end
                continue;
           end

         ts = ts-temp;          
         ts = ts/temp;    
        N = 5; % filter order
        W = [0.0 0.10;0.10 0.20;0.20 0.30;0.30 0.40;0.40 0.50;0.50 0.60 ;0.60 0.70;0.70 0.80 ;0.80 0.90;0.90 1.0];      
        [B,A]=butter(N,0.10,'low');
        ts_f(1,:) = filter(B,A,ts);         
        N1 = 5;                        
        for ind = 2:9           
            Wn = W(ind,:);
            [B,A] = butter(N1,Wn);            
            ts_f(ind,:) = filter(B,A,ts);            
        end        
        [B,A]=butter(N,0.90,'high');
        ts_f(10,:) = filter(B,A,ts); 

        for ind=1:10
          %Following Paper Suggestion          
           filtImag1{ind}(i,j) =sum(ts_f(ind,:).^2);
        end                 
    end
end

for i=1:10
  figure,imshow(filtImag1{i});  
  colorbar
end

pre_max = max(filtImag1{1}(:));
for i=1:10
   new_max = max(filtImag1{i}(:));
    if (pre_max<new_max)
        pre_max=max(filtImag1{i}(:));
    end
end
new_max = pre_max;

pre_min = min(filtImag1{1}(:));
for i=1:10
   new_min = min(filtImag1{i}(:));
    if (pre_min>new_min)
        pre_min = min(filtImag1{i}(:));
    end
end

new_min = pre_min;

%normalize
 for i=1:10
 temp_imag = filtImag1{i}(:,:);
 x=isnan(temp_imag);
 temp_imag(x)=0;
 t_max = max(max(temp_imag));
 t_min = min(min(temp_imag));
 temp_imag = (double(temp_imag-t_min)).*((double(new_max)-double(new_min))/double(t_max-t_min))+(double(new_min));

 %median filter
 %temp_imag = medfilt2(temp_imag);
 imag_test2{i}(:,:) = temp_imag;
 end

for i=1:10
  figure,imshow(imag_test2{i});
  colorbar
 end

for i=1:10
    A=imag_test2{i}(:,:);
    B=A/max(max(A));
    B=histeq(A);
 figure,imshow(B); 
 colorbar
 imag_test2{i}(:,:)=B;
end

но я не получаю такой же результат, как бумага. кто-нибудь может понять, почему? или где я поступил неправильно?

ИЗМЕНИТЬ получая помощь от @Amro и используя его код, я получаю следующие изображения: вот мое оригинальное изображение из прорастающей чешуйки 72hrs (400 изображений с 5 кадрами в секунду): enter image description here

здесь представлены изображения результатов для 10 различных диапазонов:

Band1Band2Band3Band4Band5Band6Band7BAnd8Band9Band10

Ответы

Ответ 1

Несколько вопросов, которые я могу заметить:

  • когда вы делите сигнал по его среднему значению, вам нужно проверить, что он не равен нулю. В противном случае результат будет NaN.

  • авторы (я следую за в этой статье) использовал банк фильтров с полосами частот, охватывающих весь диапазон до Частота Найквиста. Вы делаете половину этого. Нормализованные частоты, которые вы переходите на butter, должны идти вплоть до 1 (соответствует fs/2)

  • При вычислении энергии каждого отфильтрованного сигнала я думаю, что вы не должны делиться своим средним значением (вы уже учли это раньше). Вместо этого просто выполните: E = sum(sig.^2); для каждого отфильтрованного сигнала

  • На последнем этапе последующей обработки вы должны нормализовать диапазон [0,1], а затем применить средний алгоритм фильтрации medfilt2. Вычисление не выглядит правильным, это должно быть примерно так:

    img = ( img - min(img(:)) ) ./ ( max(img(:)) - min(img(:)) );
    

EDIT:

С учетом вышеизложенных соображений я попытался переписать код в векторном виде. Поскольку вы не отправляли образцы входных изображений, я не могу проверить, соответствует ли результат... Предположим, я не уверен, как интерпретировать окончательные изображения:)

%# read biospeckle images
fnames = dir( fullfile('folder','myimages*.jpg') );
fnames = {fnames.name};
N = numel(fnames);                    %# number of images
Fs = 1;                               %# sampling frequency in Hz
sz = [209 278];                       %# image sizes
T = zeros([sz N],'uint8');            %# store all images
for i=1:N
    T(:,:,i) = imread( fullfile('folder',fnames{i}) );
end

%# timeseries corresponding to every pixel
T = reshape(T, [prod(sz) N])';        %# columns are the signals
T = double(T);                        %# work with double class

%# normalize signals before filtering (avoid division by zero)
mn = mean(T,1);
T = bsxfun(@rdivide, T, mn+(mn==0));  %# divide by temporal mean

%# bank of filters
numBanks = 10;
order = 5;                                       % butterworth filter order
fCutoff = linspace(0, Fs/2, numBanks+1)';        % lower/upper cutoff freqs
W = [fCutoff(1:end-1) fCutoff(2:end)] ./ (Fs/2); % normalized frequency bands
W(1,1) = W(1,1) + 1e-5;                          % adjust first freq
W(end,end) = W(end,end) - 1e-5;                  % adjust last freq

%# filter signals using the bank of filters
Tf = cell(numBanks,1);                %# filtered signals using each filter
for i=1:numBanks
    [b,a] = butter(order, W(i,:));    %# bandpass filter
    Tf{i} = filter(b,a,T);            %# apply filter to all signals
end
clear T                               %# cleanup unnecessary stuff

%# compute average energy in each signal across frequency bands
Tf = cellfun(@(x)sum(x.^2,1), Tf, 'Uniform',false);

%# normalize each to [0,1], and build corresponding images
Tf = cellfun(@(x)reshape((x-min(x))./range(x),sz), Tf, 'Uniform',false);

%# show images
for i=1:numBanks
    subplot(4,3,i), imshow(Tf{i})
    title( sprintf('%g - %g Hz',W(i,:).*Fs/2) )
end
colormap(gray)

screenshot

(я использовал изображение из здесь для указанного результата)

EDIT # 2

Сделал некоторые изменения и немного упростил приведенный выше код. Это уменьшит площадь памяти. Например, я использовал массив ячеек вместо одной многомерной матрицы для хранения результата. Таким образом, мы не выделяем один большой блок смежной памяти. Я также повторно использовал одинаковые переменные вместо того, чтобы вводить новые на каждом промежуточном этапе...

Ответ 2

В документе не упоминается вычитание среднего временного ряда, вы уверены, что это необходимо? Кроме того, вы только вычисляете new_max и new_min один раз, начиная с последнего изображения.