Im having an issue with template matching.
1 view (last 30 days)
Show older comments
Hello,
I am currently using an template matching algorithm to detect quail calls from a spectrogram.
This algorithm was originally written for spectrograms created from a 10 second audio segments. I am trying to use the same algorithm on a spectrogram created from a 25 minute audio segment. I am not getting the correct results. And I am not sure if the algorithm is giving me the problem. I persnoally don't have a good image processing knowledge yet, so I'd be happy if you could help out.
Here's the code:
function [CallA,CallB,CallC,CallD,Calls] = QCallDetection(app)
Calls = cell(1,4);
pos = cell(1,4);
curtime = app.curLoadInterval*app.loadIntervalRate;% this part is basically setting up the correct time for 25 mins
time = curtime:1:(curtime+app.loadIntervalRate); %changed for Parallel
%% Template Reading
value = app.QuailCallTemplateDropDown.Value;
if isempty(app.template) || strcmp(value,"Real Bird")
template=mat2gray(double(imread('template_combined_real_bird_2.jpg')));
else
template = app.template;
end
if strcmp(value,"Real Bird") || strcmp(value,"Import")
ceil_x = 30;
MinProm_x = 0.25;
temp_length_x = 0.5;
else
ceil_x = 10;
MinProm_x = 0.5;
temp_length_x = 2/3;
end
temp_width=size(template,1);
temp_length=size(template,2);
spec_duration = 10;
%figure;imshow(template,[])
%title('Template')
CallA = [];CallB = [];CallC = [];CallD = [];
%% Quail Call Detection
Spectrograms = app.Spectrograms;
parfor i = 1:4
Ispec= Spectrograms{i};
if ~isempty(Spectrograms{i})
spec_len=size(Ispec,2);
spec_width=size(Ispec,1);
figure();imshow(Ispec)
band=round((spec_width-temp_width)/3);
spec_seg_size=ceil(spec_len/ceil_x);
call_candidates=[];
%call_locations=[];
no_seg=ceil(spec_len/spec_seg_size)*2-1;
for s=1:no_seg
spec_seg=Ispec(band:end-band,(s-1)*ceil(spec_seg_size/2)+1:min((s-1)*ceil(spec_seg_size/2)+1+spec_seg_size,spec_len));
cc=xcorr2(spec_seg,template);
cc_signal=mat2gray(max(cc));
cc_signal=cc_signal(round(temp_length/2)-1:end-round(temp_length/2));
TF = islocalmax(cc_signal,'MinProminence',MinProm_x,'ProminenceWindow',temp_length/2);
locs=find(TF);
call=(((s-1)*ceil(spec_seg_size/2)+1)+locs)';
call_candidates=[call_candidates;call];
% figure;imshow(spec_seg)
% x=1:length(cc_signal);
% figure;plot(x,cc_signal,x(TF),cc_signal(TF),'r*')
% waitforbuttonpress;
end
if ~isempty(call_candidates)
if length(call_candidates)>1
[L,n]=bwlabel(squareform(pdist(call_candidates))<temp_length*temp_length_x,4);
for k=1:n
[rows,~]=find(L==k);
rows=unique(rows);
spec_seg=Ispec(band:end-band,max(call_candidates(min(rows))-...
round(temp_length/2),1):min(call_candidates(min(rows))+round(temp_length/2),spec_len));
cc=xcorr2(spec_seg,template);
cc_signal=mat2gray(max(cc));
cc_signal=cc_signal(round(temp_length/2)-1:end-round(temp_length/2));
TF = islocalmax(cc_signal,'MinProminence',MinProm_x,'ProminenceWindow',temp_length/2);
location=find(TF);
if call_candidates(min(rows)) <round(temp_length/2)
call=(time(1)+(spec_duration/spec_len)*location);
Calls{i}=[Calls{i};call'];
%call_locations=[call_locations;location'];
else
call=(time(1)+(spec_duration/spec_len)*(call_candidates(min(rows))+location-round(temp_length/2)));
Calls{i}=[Calls{i};call'];
%call_locations=[call_locations;call_candidates(min(rows))+location'-round(temp_length/2)];
end
% figure;imshow(spec_seg)
% x=1:length(cc_signal);
% figure;plot(x,cc_signal,x(TF),cc_signal(TF),'r*')
% waitforbuttonpress;
end
else
spec_seg=Ispec(band:end-band,max(call_candidates(1)-round(temp_length/2),1):min(call_candidates(1)+round(temp_length/2),spec_len));
cc=xcorr2(spec_seg,template);
cc_signal=mat2gray(max(cc));
cc_signal=cc_signal(round(temp_length/2)-1:end-round(temp_length/2));
TF = islocalmax(cc_signal,'MinProminence',MinProm_x,'ProminenceWindow',temp_length/2);
location=find(TF);
if call_candidates(1) <round(temp_length/2)
call=(time(1)+(spec_duration/spec_len)*location)';
Calls{i}=[Calls{i};call'];
%call_locations=[call_locations;location'];
else
call=(time(1)+(spec_duration/spec_len)*(call_candidates(1)+location-round(temp_length/2)));
Calls{i}=[Calls{i};call'];
%call_locations=[call_locations;max(call_candidates(1)+location'-round(temp_length/2),1)];
end
% figure;imshow(spec_seg)
% x=1:length(cc_signal);
% figure;plot(x,cc_signal,x(TF),cc_signal(TF),'r*')
% waitforbuttonpress;
end
end
% For Drawing Bounding Boxes
%pos{i} = [Calls{i} 1200*ones(length(Calls{i}),1) ...
% 0.5*ones(length(Calls{i}),1) 1900*ones(length(Calls{i}),1)];
end
end
1 Comment
Image Analyst
on 14 Jul 2020
You forgot to attach any data, like 'template_combined_real_bird_2.jpg' or other images.
Seems like you blew past all the posting guidelines, but you can review this link:
Answers (0)
See Also
Categories
Find more on Get Started with MATLAB in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!