Алгоритм обработки изображений в 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 различных диапазонов:
![Band1]()
![Band2]()
![Band3]()
![Band4]()
![Band5]()
![Band6]()
![Band7]()
![BAnd8]()
![Band9]()
![Band10]()
Ответы
Ответ 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 один раз, начиная с последнего изображения.