0001 function FH = uiRot2( FH )
0002 state = newUiState;
0003 setappdata( state.FH, 'uiState', state );
0004 set( state.FH, 'KeyPressFcn', @keypress_CB );
0005 return
0006
0007
0008 function state = newUiState( ecgPath, nm )
0009 state.filePath = '/home/shrevz/noah';
0010 state.nm = 'shortrun.mat';
0011 state.FH = figure;
0012 state.AH = [];
0013 state.del2t = 0.005;
0014 state.idx = 1;
0015 state.mode = 0;
0016 state.dmax = 100;
0017 state.pIdx = 0;
0018 state.pthX = zeros(0,6);
0019 state.pthY = zeros(0,6);
0020 state.guess = zeros(6,2);
0021 state.refresh = false;
0022 return
0023
0024 function state = loadData( state )
0025
0026 fn = [ state.filePath, '/', state.nm ];
0027 fprintf('Checking file %s ...\n', fn );
0028
0029 lst = whos('-file',fn,'MM','dcr');
0030 nm = { lst.name };
0031 fprintf(' loading %s\n', lst.name );
0032 mb = msgbox('Loading....');
0033 drawnow;
0034
0035 dat = load( fn, nm{:} );
0036 close(mb);
0037
0038 if isfield(dat,'MM')
0039 state.fsrc = newFrameSourceMM( [], dat.MM );
0040 N = state.fsrc.N;
0041 if state.fsrc.N>size(state.pthX,1)
0042 state.pthX((1+size(state.pthX,1)):N,:) = nan;
0043 state.pthY((1+size(state.pthY,1)):N,:) = nan;
0044 end
0045 fprintf('Generated MM framesource\n');
0046 bg = bgFrameSource( state.fsrc );
0047 bg = (bg - min(bg(:))) ./ range(bg(:));
0048 bg = bg - median(bg(:));
0049 state.bg = bg;
0050 fprintf('Generated background image\n');
0051 bg = bg<-0.2;
0052 H = find(any(bg)); V = find(any(bg.'));
0053 elps = [ min(H) min(V); max(H) max(V) ];
0054 state.eli = ellipseDist( state.fsrc.sz, elps );
0055 imagesc( state.bg + (state.eli>1) );
0056 end
0057 fprintf( 'Done\n\n');
0058 return
0059
0060 function state = postLoad( state )
0061 state.rows = state.fsrc.sz(1);
0062 state.cols = state.fsrc.sz(2);
0063 [px,py] = meshgrid( 1-state.cols/2:state.cols/2,...
0064 1-state.rows/2:state.rows/2 );
0065 state.blr = fspecial( 'disk', 2 );
0066 state.rej = false(state.fsrc.sz);
0067 state.pts={};
0068 state.idx = 1;
0069 state.strel = strel('disk',4);
0070 state.FPS = 500;
0071 state.mode = 1;
0072 state.barrier = [];
0073 state.fullAx = [1 state.cols 1 state.rows];
0074 state.ax = state.fullAx;
0075 fprintf('Ready to start tracking\n');
0076 return
0077
0078 function D = ellipseDist( sz, elps )
0079
0080
0081 elc = mean(elps([1 3; 2 4]));
0082 [X,Y] = meshgrid( linspace(-sz(2)/2,sz(2)/2,sz(2)),...
0083 linspace(-sz(1)/2,sz(1)/2,sz(1)) );
0084 WH = diff( elps( [1 3; 2 4] ));
0085 D = sqrt( X.^2./WH(1).^2+Y.^2./WH(2).^2 )*sqrt(WH(1)*WH(2));
0086 return
0087
0088 function state = visualFor( state )
0089
0090 t = state.idx;
0091
0092 recent = [max([1,t-7]):min([size(state.pthX,1),t+7])];
0093
0094 tIdx = find(recent==t);
0095
0096 pts = state.pts{t};
0097 distal = state.distal;
0098 mk = state.mk;
0099 rej = state.rej;
0100 pIdx = state.pIdx;
0101
0102
0103 X = state.pthX(recent,:);
0104 X(end+1,:)=nan;
0105 Y = state.pthY(recent,:);
0106 Y(end+1,:)=nan;
0107
0108
0109 img = srcGetFr( state.fsrc, t );
0110
0111 luma = 0.8 .* (img-min(img(:)))./range(img(:));
0112
0113 R = luma;
0114 R(distal(:)~=0) = 0.8;
0115 if ~isempty(state.barrier)
0116 R(state.barrier)=1;
0117 end
0118
0119 G = luma + rej .* 0.2;
0120
0121 B = luma;
0122 B(mk(:)) = 0.8;
0123
0124
0125 figure( state.FH );
0126 cla;
0127
0128 image(cat(3,R,G,B));
0129 set( gca, 'Color', [R(1),G(1),B(1)], 'XTick',[], 'YTick',[]);
0130 hold on;
0131
0132 plot( X, Y, '.-b' );
0133
0134 if pIdx>0
0135 plot( X(:,pIdx),Y(:,pIdx),'-om');
0136 end
0137
0138 set( plot( state.guess(:,1), state.guess(:,2), '+y' ), ...
0139 'MarkerSize', 12 );
0140
0141 scatter( pts(:,5), pts(:,6), 10+100*(1-pts(:,8)./pts(:,4)),[1,0,0] );
0142 for k=1:size(state.pthX,2)
0143
0144 f = find(~isnan(X(:,k)));
0145 if ~isempty(f)
0146
0147 f = f(1);
0148 set( text( X(f,k), Y(f,k), sprintf('%d',k) ),...
0149 'Color', [1,.5,0], 'FontSize', 18 );
0150 end
0151
0152 h = plot( X(tIdx,k), Y(tIdx,k), 'oc' );
0153 if k==pIdx
0154 set( h, 'LineWidth', 3, 'MarkerSize', 10 );
0155 end
0156
0157 set( text( state.guess(k,1), state.guess(k,2), sprintf('%d',k ) ),...
0158 'Color', [.5,1,0], 'FontSize', 18 );
0159 end
0160 title(sprintf('Path %d --- mSec %03d', pIdx, state.idx * 1000/state.FPS));
0161 axis(state.ax);
0162
0163
0164 state.refresh = false;
0165 return
0166
0167 function nmap = nearestNext( prev, pts, DMax )
0168
0169 d = sum((repmat( permute( prev, [1 3 2] ), 1, size(pts,1) ) ...
0170 -repmat( permute( pts, [3 1 2] ), size(prev,1), 1 )).^2, 3);
0171
0172
0173 [cost, nearest] = min( d.', [], 1 );
0174 nmap = nearest;
0175
0176 set( plot( [prev(:,1).';pts(nearest,1).'], ...
0177 [prev(:,2).';pts(nearest,2).'], '-' ), ...
0178 'LineWidth', 3 );
0179 drawnow; pause(0.1);
0180
0181
0182 far = cost > DMax;
0183 if ~any(far)
0184 nFar = 0;
0185 else
0186 nFar = sum(far);
0187 nmap(far) = 0;
0188 fprintf('Too far:'); disp(find(far));
0189 end
0190
0191
0192 tmp = zeros( 1, 1+length(nmap) );
0193 tmp(1+nmap) = 1:length(nmap);
0194 hits = find(tmp(1+nmap) ~= 1:length(nmap));
0195 if ~isempty(hits)
0196 mix = false(size(nmap));
0197 for k=1:length(hits)
0198 mix = mix | (nmap == nmap(hits(k)));
0199 end
0200 mix = mix & ~(nmap==0);
0201 if any(mix)
0202 nMix = sum(mix);
0203 nmap(mix) = 0;
0204 fprintf('Collisions at:'); disp(nMix);
0205 end
0206 end
0207 return
0208
0209 function state = getDel2( state )
0210
0211 img = srcGetFr( state.fsrc, state.idx );
0212 cur = filter2( state.blr, img, 'same' );
0213 d2cur = del2(cur);
0214 figure(state.FH);
0215 imagesc(d2cur);
0216 colorbar;
0217 state.del2t = inputdlg( 'Del2 Threshold' );
0218 imagesc(((d2cur>state.del2t)+1).*cur);
0219 return
0220
0221 function state = updateFrame( state )
0222
0223 img = srcGetFr( state.fsrc, state.idx );
0224 cur = filter2( state.blr, img, 'same' );
0225 if ~isempty(state.barrier)
0226 img(state.barrier) = 1;
0227 end
0228 imfCur = imfill(img);
0229 ctrPx = round(size(imfCur)/2);
0230 mk = (imfCur==imfCur(ctrPx(1),ctrPx(2))) & (state.bg>-0.1);
0231 mk = mk & (del2(cur)>state.del2t);
0232
0233 lblRej = bwlabel( ~state.rej );
0234 if range(lblRej)>0
0235 gIdx = clipPts( state.guess, size(state.rej) );
0236 state.rej = true(size(state.rej));
0237 for k=1:size(state.guess,2)
0238 if gIdx(k)==0
0239 continue;
0240 end
0241 state.rej = state.rej & ~(lblRej == lblRej(gIdx(k)));
0242 end
0243 end
0244 mk = mk & ~state.rej;
0245
0246 bwl = bwlabel(mk);
0247 rp = regionprops( bwl, 'Centroid','Area','Image');
0248 state.pts{state.idx}=zeros(0,8);
0249 if ~isempty(rp)
0250 ar = [rp.Area].';
0251 goodMk = (ar>5);
0252 arId = find(goodMk);
0253 rp = rp(goodMk);
0254 ar = ar(goodMk);
0255
0256 ctr = vertcat( rp.Centroid );
0257 ctr = ctr( ~isnan(ctr(:,1)),: );
0258 ol = ar;
0259
0260 distal = zeros(size(bwl));
0261
0262 for rgi=1:length(ar)
0263 rgp = (bwl==arId(rgi));
0264 rg = rgp .* state.eli;
0265 rgm = max(rg(:));
0266 rgd = rg>(rgm-2);
0267 distal(rgp) = rgd(rgp) .* bwl(rgp);
0268 if ar(rgi)>3
0269 B = imOutline(rp(rgi).Image);
0270 ol(rgi) = sum(B(:));
0271 end
0272 end
0273
0274 distalrp =regionprops( distal, 'Centroid', 'Area' );
0275 disAr = [distalrp.Area].';
0276 mx = vertcat( distalrp.Centroid );
0277 mx = mx(disAr~=0,:);
0278 disAr = disAr(disAr~=0);
0279 state.pts{state.idx} =...
0280 [repmat(state.idx,size(ar)),ctr,ar,mx,ol,disAr];
0281 else
0282 distal = false(size(mk));
0283 end
0284 state.mk = mk;
0285 state.distal = distal;
0286 state.refresh = true;
0287 return
0288
0289
0290
0291 function keypress_CB( FH, evt )
0292 key = get( FH, 'CurrentCharacter' );
0293 set( FH, 'KeyPressFcn', '' );
0294 state = getappdata( FH, 'uiState' );
0295 state = doKey( state, key );
0296 setappdata( FH, 'uiState', state );
0297 set( FH, 'KeyPressFcn', @keypress_CB );
0298 return
0299
0300 function savePNG( state )
0301 fn = [state.filePath, '/snapshot.png'];
0302 fn = inputdlg( 'Save PNG as','Save PNG',1,{fn});
0303 if ~isempty(fn)
0304 print( '-noui', '-r300', sprintf('-f%d',state.FH), '-dpng', fn{1});
0305 end
0306 return
0307
0308 function b = zoomBox;
0309 k = waitforbuttonpress;
0310 p1 = get(gca,'CurrentPoint');
0311 finalRect = rbbox;
0312 p2 = get(gca,'CurrentPoint');
0313 tl = min([p1;p2]);
0314 br = max([p1;p2]);
0315 if any(tl(1:2)==br(1:2))
0316 ax = axis;
0317 sz = [ax(2)-ax(1), ax(4)-ax(3)]/4;
0318 axis( [tl(1)-sz(1), tl(1)+sz(1), tl(2)-sz(2), tl(2)+sz(2)] );
0319 else
0320 axis( [tl(1), br(1), tl(2), br(2)] );
0321 end
0322 if nargout>0
0323 b = [tl;br];
0324 end
0325 return
0326
0327 function state = doNearest( state )
0328 mx = state.pts{state.idx}(:,5:6);
0329 nmap = nearestNext( state.guess, mx, state.dmax );
0330 idx = find(nmap);
0331 state.guess(idx,:) = mx(nmap(idx),:);
0332 state.refresh = true;
0333 return
0334
0335 function state = doSaveGuess( state, sel )
0336 if nargin<2
0337 sel = true(size(state.guess,1),1);
0338 end
0339 state.pthX(state.idx,sel)=state.guess(sel,1).';
0340 state.pthY(state.idx,sel)=state.guess(sel,2).';
0341 state.refresh = true;
0342 return
0343
0344 function state = doNextFrame( state )
0345 state.idx = state.idx + 1;
0346 state = updateFrame( state );
0347 state.rej = ~imdilate( state.mk, state.strel );
0348 return
0349
0350 function state = doKey( state, key )
0351 switch key
0352 case 's'
0353
0354 state = doSaveGuess( state );
0355 case 'c'
0356 state.barrier = [];
0357 state.refresh=true;
0358 case 'n'
0359
0360 state = doNearest( state );
0361 case { '1','2','3','4','5','6','7','8','9' }
0362
0363 pt = ginput(1);
0364 state.pIdx = eval(key);
0365 state.guess(state.pIdx,:) = pt([1;2]);
0366 state = doSaveGuess( state, state.pIdx );
0367 case 'S'
0368 savePNG( state );
0369 case 'p'
0370 p = inputdlg( 'New path for files','Path',1,{state.filePath});
0371 if ~isempty(p)
0372 state.filePath = p{1};
0373 end
0374 case 'l'
0375 n = inputdlg( 'Load data from','name',1,{state.nm});
0376 if ~isempty(n)
0377 state.nm = n{1};
0378 state = loadData( state );
0379 state = postLoad( state );
0380 state = updateFrame( state );
0381 end
0382 case 't'
0383 state = getDel2( state );
0384 case 'b'
0385 p = ginput(1);
0386 [X,Y] = meshgrid( 1:state.cols, 1:state.rows );
0387 d = state.eli( ceil(p(2)), ceil(p(1)) );
0388 dmask = (state.eli > (d-1)) & (state.eli < (d+1));
0389 dmask = dmask & (((X-p(1)).^2+(Y-p(2)).^2)<25);
0390 if isempty(state.barrier)
0391 state.barrier = dmask;
0392 else
0393 state.barrier = state.barrier | dmask;
0394 end
0395 state = updateFrame( state );
0396 case 'B'
0397 if isempty(state.barrier)
0398 state.barrier = roipoly;
0399 else
0400 state.barrier = state.barrier | roipoly;
0401 end
0402 state = updateFrame( state );
0403 case 'M'
0404 state.rej = true(size(state.rej));
0405 state = updateFrame( state );
0406 case 'm'
0407 p = ginput(1);
0408 [X,Y] = meshgrid( 1:state.cols, 1:state.rows );
0409 state.rej = state.rej & ~ (((X-p(1)).^2+(Y-p(2)).^2)<25);
0410 state = updateFrame( state );
0411 case 'r'
0412 state.rej = state.rej | roipoly;
0413 state = updateFrame( state );
0414 case 'R'
0415 state.rej = state.rej & ~roipoly;
0416 state = updateFrame( state );
0417 case ']'
0418 state = doNextFrame( state );
0419 case ' '
0420 state = doSaveGuess(state);
0421 state = doNextFrame(state);
0422 state = doNearest(state);
0423 case '['
0424 if state.idx > 1
0425 state.idx = state.idx - 1;
0426 state = updateFrame( state );
0427 end
0428 case 'z'
0429 zoomBox;
0430 state.ax = axis;
0431 state.refresh = true;
0432 case 'x'
0433 state.ax = state.fullAx;
0434 state.refresh = true;
0435 case 'h'
0436 msgbox({...
0437 '----HELP----',...
0438 ' h - this help message',...
0439 ' S - save snapshot of GUI',...
0440 ' p - change file path',...
0441 ' l - load data from file',...
0442 ' a - set antenna region',...
0443 ' t - set Laplacian threshold' })
0444 end
0445 if state.refresh
0446 state = visualFor( state );
0447 drawnow;
0448 end
0449 return