caffe_features_multiple_images.m 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. function [ features ] = caffe_features_multiple_images( s_filelist, f_mean, net, s_layer)
  2. % function [ features ] = caffe_features_multiple_images( s_filelist, f_mean, net, s_layer)
  3. %
  4. % BRIEF:
  5. % Run a forward pass of a given net on a set of images which are
  6. % listed in an external file and grep features of a specified layer.
  7. % Requires Caffe version from 17-07-2015 (hash: 6d92d8fcfe0eea9495ffbc)
  8. %
  9. % INPUT
  10. % s_filelist -- string, filename to an external list which contains
  11. % image names in each line. Alternatively, the variable is
  12. % given as cell array where each entry contains a loaded
  13. % image.
  14. % f_mean -- The average image of your dataset. This should be the same that was used during training of the CNN model.
  15. % Required to be cropped to the input size of your
  16. % network! See caffe_load_network.m
  17. % net -- a previously loaded network, see caffe_load_network.m
  18. % s_layer -- optional (default: 'relu7'), string, specifies the layer used for feature exatraction
  19. %
  20. %% parse inputs
  21. if (nargin<2)
  22. error ( 'no mean passed');
  23. end
  24. if (nargin<3)
  25. error ( 'no network passed');
  26. end
  27. if (nargin<4)
  28. s_layer = 'relu7';
  29. end
  30. %% prepare list of filenames
  31. b_filelistmode = ischar( s_filelist );
  32. if (b_filelistmode)
  33. % load the file list
  34. fid = fopen( s_filelist );
  35. s_filelist_to_use = textscan(fid,'%s');
  36. s_filelist_to_use = s_filelist_to_use{1};
  37. fclose(fid);
  38. else
  39. % use the passed filelist
  40. s_filelist_to_use = s_filelist;
  41. end
  42. %% new caffe layout
  43. net_input_shape = net.blobs('data').shape;
  44. i_batch_size = net_input_shape(4);
  45. % create tmp for batch
  46. batch_data = {zeros(net_input_shape(1),... %height
  47. net_input_shape(2),... %width
  48. net_input_shape(3),... %width, ...%RGB
  49. i_batch_size,...
  50. 'single')};
  51. % Calculate the starting indices of every batch
  52. slices = 1:i_batch_size:size(s_filelist_to_use,1);
  53. slices(end+1)=size(s_filelist_to_use,1)+1;
  54. % crop the list of files into batches of adequate size
  55. % then run over every batch
  56. for i=1:numel(slices)-1
  57. % debug information for progress
  58. if ( ( i > 1 ) && ( mod(i,10) == 0 ) )
  59. fprintf('Running batch number %i of %i\n',i, numel(slices)-1);
  60. end
  61. % load the images of the next slice
  62. for j=slices(i):slices(i+1)-1;
  63. if (b_filelistmode)
  64. batch_data{1}(:,:,:,j-slices(i)+1) = caffe_prepare_image(imread( s_filelist_to_use{j} ), f_mean );
  65. else
  66. batch_data{1}(:,:,:,j-slices(i)+1) = caffe_prepare_image(s_filelist_to_use{j}, f_mean );
  67. end
  68. end
  69. % run a single forward pass
  70. [~] = net.forward( batch_data );
  71. % fetch activations from specified layer
  72. tmp_feat = net.blobs( s_layer ).get_data();
  73. % vectorize and concatenate activation maps
  74. if ( ndims( tmp_feat ) > 2 )
  75. tmp_feat = reshape( tmp_feat, ...
  76. size(tmp_feat,1)*size(tmp_feat,2)*size(tmp_feat,3), ...
  77. size(tmp_feat,4)...
  78. );
  79. end
  80. % allocate enough space in first run
  81. if ( ~exist('features','var') )
  82. features = zeros( size(tmp_feat,1), size(s_filelist_to_use,1), 'single');
  83. end
  84. % store computed feature accordingly
  85. features( :, slices(i):(slices(i+1)-1) ) = tmp_feat( :, 1:(slices(i+1)-slices(i)) );
  86. end
  87. % convert output to double precision
  88. features = double(features);
  89. end