Browse Source

initial commit, selection tool is running

Alexander Freytag 10 years ago
commit
a12f642f9c
6 changed files with 322 additions and 0 deletions
  1. 1 0
      .gitignore
  2. 7 0
      README.md
  3. 62 0
      clickBoundingBoxes2D.m
  4. 57 0
      clickPoints2D.m
  5. 85 0
      drawBoxesToImg.m
  6. 110 0
      selectButterflies.m

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+*~

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+Summary
+==============
+Brief summary goes here...
+
+Requirements / Dependencies
+==============
+* the source code was developed in Matlab 8.0

+ 62 - 0
clickBoundingBoxes2D.m

@@ -0,0 +1,62 @@
+function [X1,Y1,X2,Y2]=clickBoundingBoxes2D( i_maxNoBBs )
+% function [X,Y]=clickBoundingBoxes2D( i_maxNoBBs )
+% 
+% date: 04-02-2014 (dd-mm-yyyy)
+% author: Alexander Freytag
+    
+    %% check inputs and default arguments
+    
+    if ( nargin < 1 )
+        i_maxNoBBs = Inf;
+    end
+
+    X1 = [];
+    Y1 = [];
+    X2 = [];
+    Y2 = [];
+    
+    keydown = 0;
+    
+    %% start clicking
+    
+    statusMsg = sprintf( ' --- Start clicking bounding box points! ---' );
+    disp(statusMsg);      
+    while ( size( X1, 1 ) < i_maxNoBBs ), 
+        
+       
+        [X12,Y12, b_success]=clickPoints2D( 2 ); % we need two points for a bounding box
+        
+
+        
+        % check whether input is valid
+        if ( b_success )
+            
+            xl = min ( X12(1,1) , X12(2,1) );
+            xr = max ( X12(1,1) , X12(2,1) );
+            width  = xr - xl;
+            
+            yl = min ( Y12(1,1) , Y12(2,1) );
+            yr = max ( Y12(1,1) , Y12(2,1) );
+            height = yr - yl;
+            
+            % we currently only accept squared regions, so we take the
+            % small size
+%             smallDim = min ( width, height);
+            xr = xl + width;
+            yr = yl + height;
+            
+            X1 = [ X1; xl ];
+            Y1 = [ Y1; yl ];
+            X2 = [ X2; xr ];
+            Y2 = [ Y2; yr ];            
+            
+            hold on;
+            line([xl xl xr  xr  xl]',[yl yr yr yl yl]','color','r','linewidth',5);
+            hold off;         
+        else
+            % break clicking loop
+            break;
+        end
+        
+    end
+end

+ 57 - 0
clickPoints2D.m

@@ -0,0 +1,57 @@
+function [X,Y,b_success]=clickPoints2D( i_maxNoClicks, style )
+% function [X,Y,b_success]=clickPoints2D( i_maxNoClicks, style )
+% 
+% date: 04-02-2014 (dd-mm-yyyy)
+% author: Alexander Freytag
+    
+    %% check inputs and default arguments
+    if ( nargin < 1 )
+        i_maxNoClicks = Inf;
+    end
+    
+    if ( nargin < 2 )
+        % default for plotting clicked points
+        style='bx'; 
+    end    
+
+    XY=[];
+    keydown = 0;
+    
+    if ( nargout > 2 )
+        b_success = true;
+    end
+    
+    %% start clicking
+    while ( size( XY, 1 ) < i_maxNoClicks ), 
+        % grep point from current figure by clicking
+        p=ginput(1); 
+        
+        % check whether input is valid
+        if keydown==0 && ~isempty(p)
+            
+            % append point to point list
+            XY = [XY; p(1),p(2)];
+            
+            % plot point to figure
+            hold on ;
+            plot(p(1),p(2),style,'MarkerSize',8,'LineWidth',1); 
+            hold off ;
+        else
+            % break clicking loop
+            if ( nargout > 2 )
+                b_success = false;
+            end
+            
+            break;
+        end; 
+    end
+    
+    %% final formatting of outputs
+    if ( ~isempty( XY ) ) 
+        X=XY(:,1);
+        Y=XY(:,2);
+    else
+        X = [];
+        Y = [];
+    end
+end

+ 85 - 0
drawBoxesToImg.m

@@ -0,0 +1,85 @@
+function imWithBoxes = drawBoxesToImg(im, boxes, partcolor, i_linewidth)
+% showboxes(im, boxes)
+% Draw boxes on top of image.
+
+if nargin < 4
+    i_linewidth = 1;
+end
+
+if nargin < 3,
+  partcolor{1}    = [255,0,0];
+  partcolor(2:20) = num2cell(repmat( [0,0,255], [19,1]),2);
+end
+
+
+
+
+if ( nargout == 0)
+    %imagesc(im); axis image; axis off;
+    imshow(im); hold on;
+    if ~isempty(boxes)
+      numparts = floor(size(boxes, 2)/4);
+      for i = 1:numparts
+        x1 = boxes(:,1+(i-1)*4);
+        y1 = boxes(:,2+(i-1)*4);
+        x2 = boxes(:,3+(i-1)*4);
+        y2 = boxes(:,4+(i-1)*4);
+        line([x1 x1 x2 x2 x1]',[y1 y2 y2 y1 y1]','Color',partcolor{i},'linewidth',i_linewidth);
+      end
+    end
+    drawnow;
+    hold off;
+else
+    
+    if ( ndims(im) == 2 )
+        imWithBoxes = repmat( im, [1,1,3] );        
+    else
+        imWithBoxes = im;
+    end
+        
+    
+    hold on;
+    
+    i_offset = i_linewidth/2;
+    
+
+    %imagesc(im); axis image; axis off;
+    if ~isempty(boxes)
+      numparts = floor(size(boxes, 2)/4);
+           
+            
+      for i = 1:numparts
+          
+        %[dist-to-left dist-to-top dist-to-left+width dist-to-top+height]  
+        x1 = boxes(:,1+(i-1)*4);
+        y1 = boxes(:,2+(i-1)*4);
+        x2 = boxes(:,3+(i-1)*4);
+        y2 = boxes(:,4+(i-1)*4);
+        
+        [ height, width, ~ ] = size ( imWithBoxes );
+        
+        i_minLeft   = max ( 1 , x1-i_offset );
+        i_maxRight  = min ( width, x2+i_offset);
+        i_minBottom = max ( 1 , y1-i_offset );
+        i_maxTop    = min ( height, y2+i_offset);
+%         
+        imWithBoxes( i_minBottom:y2+i_offset, i_minLeft:x1+i_offset, 1) = partcolor{i}(1);
+        imWithBoxes( i_minBottom:y2+i_offset, i_minLeft:x1+i_offset, 2) = partcolor{i}(2);
+        imWithBoxes( i_minBottom:y2+i_offset, i_minLeft:x1+i_offset, 3) = partcolor{i}(3);
+%         
+        imWithBoxes( i_minBottom:i_maxTop,        x2-i_offset:i_maxRight, 1) = partcolor{i}(1);
+        imWithBoxes( i_minBottom:i_maxTop,        x2-i_offset:i_maxRight, 2) = partcolor{i}(2);
+        imWithBoxes( i_minBottom:i_maxTop,        x2-i_offset:i_maxRight, 3) = partcolor{i}(3);
+%         
+        imWithBoxes( i_minBottom:y1+i_offset, x1:x2, 1) = partcolor{i}(1);
+        imWithBoxes( i_minBottom:y1+i_offset, x1:x2, 2) = partcolor{i}(2);
+        imWithBoxes( i_minBottom:y1+i_offset, x1:x2, 3) = partcolor{i}(3);
+%         
+        imWithBoxes( y2-i_offset:i_maxTop, x1:x2, 1) = partcolor{i}(1);      
+        imWithBoxes( y2-i_offset:i_maxTop, x1:x2, 2) = partcolor{i}(2); 
+        imWithBoxes( y2-i_offset:i_maxTop, x1:x2, 3) = partcolor{i}(3); 
+      end
+    end
+end
+
+

+ 110 - 0
selectButterflies.m

@@ -0,0 +1,110 @@
+function selectButterflies ( s_img, s_dest ) 
+% function selectButterflies ( s_img, s_dest ) 
+% 
+% BRIEF
+%   Select bounding boxes for images, save those guys to a specified
+%   folder, and keep track of everything with a small cache.
+% 
+% INPUT
+%   s_img  -- string specifying name of image to be annotated
+%   s_dest -- where to save cropped images to
+% 
+% OUTPUT
+%    none
+% 
+
+   s_cacheDest = './cacheButterflies.mat';
+   if ( exist ( s_cacheDest ) )
+       load ( s_cacheDest, 'cacheButterflies', 'i_counter' );
+   end
+   
+
+
+   im = imread ( s_img );  
+   
+   figImg   = figure;
+   figCrop  = figure;   
+   
+   b_continueSelection = true;
+   i_numBoxesPerClick  = 1;
+   
+   imWithBoxes = im;
+   
+   %
+   i_linewidth = 3;
+   partcolor{1} = [255,0,0];
+   
+   if ( ~exist ( 'cacheButterflies' ) )
+       cacheButterflies = struct( 'name', 'rectangle' ) ;
+   else
+       idxSameImg = strcmp ( {cacheButterflies.name}, s_img);
+       bBox = {cacheButterflies.rectangle};
+       bBoxSameImg = cell2mat(bBox(idxSameImg)');
+       imWithBoxes = drawBoxesToImg(imWithBoxes, bBoxSameImg, partcolor, i_linewidth);         
+   end
+   
+   if ( ~exist ( 'i_counter') )
+       i_counter = 1 ;
+   end   
+   
+ 
+   
+   
+   
+   
+   s_prompt = sprintf('Press enter for save+continue, r for retry, and X for abort\n');
+   
+   while b_continueSelection
+      
+       figure ( figImg );
+       imshow ( imWithBoxes );
+       [xmin, ymin, xmax, ymax] = clickBoundingBoxes2D ( i_numBoxesPerClick );       
+       xmin = int32(round(xmin));
+       ymin = int32(round(ymin));
+       xmax = int32(round(xmax));
+       ymax = int32(round(ymax));
+      
+       imTmp = imcrop(im, [xmin, ymin, xmax-xmin, ymax-ymin]);
+       
+       figure ( figCrop );
+       imshow ( imTmp );       
+       
+       
+       result = input(s_prompt, 's');
+       while ( ~isempty(result) && (strcmp(result,'r')==0) && (strcmp(result,'X')==0) )
+           disp(sprintf('Retry input!\n'))
+           result = input(s_prompt, 's');
+       end
+       
+       
+       if ( strcmp(result,'X') )
+           return;
+       end
+       
+       if ( isempty(result) )
+           
+           % write current proposal
+           s_destFig = sprintf('%s_%03d.png',s_dest, i_counter);
+           imwrite ( imTmp, s_destFig );
+
+           % save results to cache
+           
+           cacheButterflies( i_counter ).name      = s_img;
+           cacheButterflies( i_counter ).rectangle = [xmin,ymin,xmax,ymax];
+           i_counter = i_counter +1;           
+           save ( s_cacheDest, 'cacheButterflies', 'i_counter' );
+
+
+           
+           
+            % plot current result 
+            newproposal = [xmin,ymin,xmax,ymax];
+            imWithBoxes = drawBoxesToImg(imWithBoxes, newproposal, partcolor, i_linewidth);            
+       end
+      
+
+            
+   end
+   
+   
+end