
%Author : Vladimir Ouzienko , CIS9601

%read image, make it binary
objimage=imread('objects.jpg');
doubleimage = im2double(objimage);
blackandwhite = sum(doubleimage,3);
blackandwhite = blackandwhite/max(blackandwhite(:));
blackandwhite(blackandwhite<0.5)=0;
blackandwhite(blackandwhite>=0.5)=1;
s= size(blackandwhite);

%inverse it
for row = 1:s(1)
    for col = 1:s(2)
        if (blackandwhite(row,col)==1)
            blackandwhite(row,col)=0;
        else
            blackandwhite(row,col)=1;
        end
    end
end
%clean dots
blackandwhite=bwmorph(blackandwhite,'clean',100);

%dilate one time
blackandwhite=bwmorph(blackandwhite,'dilate',1);


%segment it 
[L n]=bwlabel(blackandwhite);

%iterate over segments
for i =1:n
    %get segment matrix
    [r,c] = find(bwlabel(blackandwhite)==i);
    r_range= max(r)-min(r);
    c_range= max(c)-min(c);
    %disregard small objects, could be random dots
    if(r_range <30 || c_range <30)
        continue;
    end
    
    %build matrix for the segment
    %with offset of 0
    fill_in =zeros(r_range,c_range);
    row_offset = min(r);
    col_offset = min(c);
    r= r-row_offset+1;
    c= c-col_offset+1;
    %rebuilding the image from the vector
    for j=1:size(r)
         fill_in(r(j),c(j))=1;
    end

    % now work with the image itself
    
    %first get the boundary
    boundary= bwtraceboundary(fill_in,[r(1) c(1) ],'E');
    
    %boundary_display is just for show
    boundary_display = zeros(r_range,c_range);
    for j=1:size(boundary,1)
         boundary_display(boundary(j,1),boundary(j,2))=1;
    end
    imshow(boundary_display);
    
    %normalize boundary to -1 ..1 range
    %not sure if it's needed...
    new_min=-1;
    new_max=1;
    min_a=min(boundary(:,1));
    max_a=max(boundary(:,1));
    min_b=min(boundary(:,2));
    max_b=max(boundary(:,2));
    
    for j=1:size(boundary,1)
        boundary(j,1)= ((boundary(j,1)-min_a)/(max_a-min_a))*(new_max-new_min) + new_min;
        boundary(j,2)= ((boundary(j,2)-min_b)/(max_b-min_b))*(new_max-new_min) + new_min;
    end
    
    %showtime!
    
    %first, the boundary
    subplot(2,2,1);imshow(boundary_display);
    %second, the centroid function
    subplot(2,2,2);centroidDistance(boundary,100,1);
    subplot(2,2,3);
    %third, fourier 
    cdf=centroidDistanceFourier(boundary,100,1);
    
    %now going to look for that gear
    
    %my assumption here , is that there are got be 
    %some empirics here. I will allow for two empirical values
    
    %we will not be looking for anything
    %below 12, as we know there are a lot of teeth on these gears
    empiric_min_teeth=12;
    
    %the frequency that indicates teeth is  
    %considerably higher than it's neighbor to 
    %the left, I'd say by factor of 5 
    empiric_jump_ratio=5;
    
    %also the frequency that indicates
    %teeth is max after empirical cut off
    max_value=0;
    for p=empiric_min_teeth:size(cdf)
        if(cdf(p)>max_value)
            max_value=cdf(p);
        end
    end    
    
    toothed_one=false;
    for p=empiric_min_teeth:size(cdf)
         %testing for "jump" and that it is the max after cut off
         if(cdf(p)/cdf(p-1)>empiric_jump_ratio && cdf(p)==max_value)
             toothed_one=true;
             break;
         end    
    end
    
    %display result
    %Sorry, did not know how to this one better
    if toothed_one
           subplot(2,2,4,'replace');
           s=['Toothed Gear ! with ' num2str(p) ' teeth'];
           title(s );
    else
           subplot(2,2,4,'replace');
           title('Nope');
    end
    
    dummy=ginput(1);
    
end



