% biasedNcutDemo
% 
% code for computing Biased Normalized Cut of an Image
%
% Interactive segmentation
%
% Author : Subhransu Maji, March 2011.
% 
% Biased Normalized Cuts, 
% Subhransu Maji, Nisheeth Vishnoi, Jitendra Malik, CVPR 2011.

addpath lib;
image_file = 'baby.jpg';
nvec = 17;
[EigVal, EigVect, D] = im2evec(image_file,nvec);

%% biased normalized cut demo
I = imread(image_file);
[nr,nc,nb] = size(I);
%% display the image and the eigenvectors
figure;
imshow(I);

figure;
for i = 1:4 % display the top 4 eigenvectors
    subplot(4,1,i);
    imagesc(reshape(EigVect(:,i+1),nr,nc));axis image; axis off;
end
disp('displaying the top eigenvectors');
%% display biased ncuts for various values of gamma
ROIMODE    = 0; % input is ROI or a set of points
numinput   = 6; % number of input points
NUMDISPLAY = 9; % number of display panels


wts = zeros(length(EigVal),1);
m = round(sqrt(NUMDISPLAY)); n = ceil(NUMDISPLAY/m);

while(1),
    figure(1); clf;
    imshow(I); 
    hold on;
    if(ROIMODE)
        title('draw a pqolygon.');
    else
        title(sprintf('click %i points',numinput));
    end
    if(ROIMODE)
        [bw,xi,yi] = roipoly(I/255);
    else
        [cx,cy] = ginput(numinput);
        bw = zeros(nr,nc);
        cx = round(cx);
        cy = round(cy);

        for i = 1:length(cx),
            bw(cy(i),cx(i)) = 1;
        end
        plot(cx,cy,'b+');
        plot(cx,cy,'bo');
    end
    %make the normalized seed vector
    tic;
    s = D*bw(:);
    figure(2); clf;
    
    for j = 1:NUMDISPLAY, 
        gamma = (1 - 10^(j-1))*EigVal(2);
        for i = 2:length(EigVal) % ignore the all 1's vector
            wts(i) = (EigVect(:,i)'*s)/(EigVal(i) - gamma);
        end
        WEigVect = EigVect*wts;

        subplot(m,n,j);
        imagesc(reshape(WEigVect,nr,nc)); axis image; axis off;
        title(sprintf('\\gamma=%.2d', gamma)); colormap gray;
    end
    toc;
    fprintf('press: n next, t toggle-mode, <-,-> decrease,increase points\n');
    
    % process keypoint input
    [x,y,button] = ginput(1);
    
    switch(button)
        case 110      % space - next one
            continue; 
        case 27       % esc   -  stop the interactive segmentation
            break;    
        case 116      % t     - toggle 
            ROIMODE = ~ROIMODE;
        case 28       % <-   
            numinput = max(numinput-1,1);
        case 29       % -> 
            numinput = numinput+1;
    end
    
end
