selectButterflies.m 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. function selectButterflies ( varargin )
  2. % function selectButterflies ( s_img, s_dest )
  3. %
  4. % BRIEF
  5. % Select bounding boxes for images, save those guys to a specified
  6. % folder, and keep track of everything with a small cache.
  7. %
  8. % INPUT
  9. % either a struct with required fields 's_img' and optional fields
  10. % 's_dest', 's_cacheDest'
  11. % OR
  12. % combinations of 'string', value for the beforementioned fields
  13. %
  14. % OUTPUT
  15. % none
  16. %
  17. % fetch specified inputs and set default values if possible
  18. %% parse inputs
  19. myInput = parseMyInputs ( varargin{:} );
  20. % shorten writening
  21. s_img = myInput.s_img;
  22. s_dest = myInput.s_dest;
  23. s_cacheDest = myInput.s_cacheDest;
  24. % check whether a cache is available
  25. if ( exist ( s_cacheDest ) )
  26. load ( s_cacheDest, 'cacheButterflies', 'i_counter' );
  27. end
  28. % current image
  29. im = imread ( s_img );
  30. % allocated figures
  31. figImg = figure;
  32. figCrop = figure;
  33. b_continueSelection = true;
  34. % ask for 1 bounding box at a time
  35. i_numBoxesPerClick = 1;
  36. % image to be shown to the user to visualize currently selected boxes
  37. imWithBoxes = im;
  38. %
  39. i_linewidth = 4;
  40. partcolor = [255,0,0];
  41. % if cache exists, plot the boxes belonging to the current image
  42. if ( ~exist ( 'cacheButterflies' ) )
  43. cacheButterflies = struct( 'name', 'rectangle' ) ;
  44. else
  45. idxSameImg = strcmp ( {cacheButterflies.name}, s_img);
  46. bBox = {cacheButterflies.rectangle};
  47. bBoxSameImg = cell2mat(bBox(idxSameImg));
  48. imWithBoxes = drawBoxesToImg(imWithBoxes, bBoxSameImg, partcolor, i_linewidth);
  49. end
  50. if ( ~exist ( 'i_counter') )
  51. i_counter = 1 ;
  52. end
  53. % prompt user help
  54. s_prompt = sprintf('Press enter for save+continue, r for retry, and X for abort\n');
  55. % ask for selection as long as user is interested...
  56. while b_continueSelection
  57. % bring bbox-vis figure to front
  58. figure ( figImg );
  59. imshow ( imWithBoxes );
  60. % ask for a new bounding box
  61. [xmin, ymin, xmax, ymax] = clickBoundingBoxes2D ( i_numBoxesPerClick );
  62. xmin = int32(round(xmin));
  63. ymin = int32(round(ymin));
  64. xmax = int32(round(xmax));
  65. ymax = int32(round(ymax));
  66. % crop selection and present it to user
  67. imTmp = imcrop(im, [xmin, ymin, xmax-xmin, ymax-ymin]);
  68. figure ( figCrop );
  69. imshow ( imTmp );
  70. % ask user for judgement (okay, retry, abort)
  71. result = input(s_prompt, 's');
  72. while ( ~isempty(result) && (strcmp(result,'r')==0) && (strcmp(result,'X')==0) )
  73. disp(sprintf('Retry input!\n'))
  74. result = input(s_prompt, 's');
  75. end
  76. % did user wanted to quit?
  77. if ( strcmp(result,'X') )
  78. return;
  79. end
  80. if ( isempty(result) )
  81. % write current proposal
  82. s_destFig = sprintf('%s_%03d.png',s_dest, i_counter);
  83. imwrite ( imTmp, s_destFig );
  84. % save results to cache
  85. cacheButterflies( i_counter ).name = s_img;
  86. cacheButterflies( i_counter ).rectangle = [xmin,ymin,xmax,ymax];
  87. i_counter = i_counter +1;
  88. save ( s_cacheDest, 'cacheButterflies', 'i_counter' );
  89. % plot current result
  90. newproposal = [xmin,ymin,xmax,ymax];
  91. imWithBoxes = drawBoxesToImg(imWithBoxes, newproposal, partcolor, i_linewidth);
  92. end
  93. end
  94. end
  95. function myInput = parseMyInputs(varargin)
  96. if ( (nargin == 1) && isstruct( varargin{1} ) )
  97. %% was only a struct given? If so, use it :)
  98. myInput = varargin{1};
  99. else
  100. %% check for explicitely specified settings
  101. for i=1:2:nargin
  102. if ( strcmp ( varargin{i}, 's_img' ) )
  103. myInput.s_img = varargin{i+1};
  104. %
  105. elseif ( strcmp ( varargin{i}, 's_dest' ) )
  106. myInput.s_dest = varargin{i+1};
  107. %
  108. elseif ( strcmp ( varargin{i}, 's_cacheDest' ) )
  109. myInput.s_cacheDest = varargin{i+1};
  110. %
  111. end
  112. end
  113. end
  114. %% now check default stuff
  115. checkCrucialField ( myInput, 's_img' );
  116. myInput = setFieldDefault ( myInput, 's_dest', './butterflies-' );
  117. myInput = setFieldDefault ( myInput, 's_cacheDest', './cacheButterflies.mat' );
  118. end
  119. function myInput = setFieldDefault ( myInput, s_fieldname, value )
  120. if ( ~(isfield(myInput, s_fieldname) ) || isempty(myInput.(s_fieldname)) )
  121. myInput = setfield( myInput, s_fieldname, value );
  122. end
  123. end
  124. function checkCrucialField ( myInput, s_fieldname )
  125. assert ( (isfield(myInput, s_fieldname) ) && ~isempty(myInput.(s_fieldname)), ...
  126. sprintf('No %s specified, aborting...', s_fieldname) ...
  127. );
  128. end