i performing whisker-tracking experiments. have high-speed videos (500fps) of rats whisking against objects. in each such video tracked shape of rat's snout , whiskers. since tracking noisy, number of whiskers in each frame may different (see 2 consecutive frames in attached image, notice yellow false-positive whisker appearing in left frame not right one).
see example 1: 
as end result of tracking, get, each frame, varying number of variable-length vectors; each vector corresponding single whisker. @ point match whiskers between frames. have tried using matlab's sample align this, works properly. results attached below (in attached image showing basepoint of whiskers on 227 frames).
see example 2: 
i run algorithm cluster whiskers correctly, such each whisker recognized , separated other on course of many frames. in other words, each sinusoidal trajectory in second image recognized 1 trajectory. whatever sorting algorithm use should take account whiskers may disappear , reappear between consecutive frames. unfortunately, i'm out of ideas...
any help?
once again, keep in mind each point in attached image 2, have many data points, since plot of whisker basepoint, while in actuality have data entire whisker length.
this how deal problem. assuming data vectors of different size in cell type called datavectors, , knowing number of whiskers (nsignals), try extend data second dimension derived original data , perform k-means on 2 dimensions.
so, first maximum size of vectors in order convert data matrix , nan-padding.
maxsize = -inf; k = 1:nsignals if length(datavectors{k}.data) > maxsize maxsize = length(datavectors{k}.data); end end now, make data 2d elevating power of 2 (or three, choice). simple transformation. alternatively use kernel methods here , project each vector against rest; however, don't think necessary, , if data big, inefficient. now, raising data power of 2 should trick. result stored in second dimension.
projdegree = 2; projdata = zeros(nsignals, maxsize, 2).*nan; k = 1:nsignals vecsize = length(datavectors{k}.data); projdata(k, 1:vecsize, 1) = datavectors{k}.data; projdata(k, 1:vecsize, 2) = datavectors{k}.data.*projdegree; end projdata = reshape(projdata, [], 2); here, projdata have in row 1 , column 1, original data of first whisker (or signal call here), , column 2 have new dimension. let's suppose have 8 whiskers in total, then, projdata have data of first whisker in row 1, 9, 17, , on. data of second whisker in row 2, 10, 18, , forth. important if want work way original data. also, can try different projdegrees doubt make lot of difference.
now perform k-means on 2d data; however, provide initial points instead of letting determine them k-means++. initial points, propose here, first data point of each vector each whisker. in manner, k-means depart there , move clusters means accordingly. save results in idxk.
idxk = kmeans(projdata,nsignals, 'start', projdata(1:nsignals, :)); and there have it. variable idxk tell data point belongs cluster.
below working example of proposed solution. first part trying produce data looks data, can skip it.
rng(9, 'twister') nsignals = 8; % number of whiskers n = 1000; % number of data points alldata = zeros(nsignals, n); % data stored here % loop generate data looks yours k = 1:nsignals x = sort(rand(1,n)); nperiods = round(rand*9)+1; % sin can have between 1-10 periods nshiftamount = round(randn*30); % shift between ~ -100 +100 y = sin(x*2*pi*nperiods) + (randn(1,n).*0.5); y = y + nshiftamount; alldata(k, :) = y; end nanidx = round(rand(1, round(n*0.05)*nsignals).*((n*nsignals)-1))+1; alldata(nanidx) = nan; % 5% of data missing figure(1); k = 1:nsignals nanidx = ~isnan(alldata(k, :)); datavectors{k}.data = alldata(k, nanidx); plot(datavectors{k}.data, 'kx'), hold on; end 
% determine max size maxsize = -inf; k = 1:nsignals if length(datavectors{k}.data) > maxsize maxsize = length(datavectors{k}.data); end end % making data 2 dimensions , nan pad projdegree = 2; projdata = zeros(nsignals, maxsize, 2).*nan; k = 1:nsignals vecsize = length(datavectors{k}.data); projdata(k, 1:vecsize, 1) = datavectors{k}.data; projdata(k, 1:vecsize, 2) = datavectors{k}.data.*projdegree; end projdata = reshape(projdata, [], 2); figure(2); plot(projdata(:,1), projdata(:,2), 'kx'); 
% run k-means using first points of measure initial points idxk = kmeans(projdata,nsignals, 'start', projdata(1:nsignals, :)); figure(3); licolors = [{'yx'},{'mx'},{'cx'},{'bx'},{'kx'},{'gx'},{'rx'},{'gd'}]; k = 1:nsignals plot(projdata(idxk==k,1), projdata(idxk==k,2), licolors{k}), hold on; end 
% plot results on original data figure(4); k = 1:nsignals plot(projdata(idxk==k,1), licolors{k}), hold on; end 
let me know if helps.
Comments
Post a Comment