function [X,y,N, ExtractedLocations] = SobelObjectDetector_GetTrainData(CAfilelist,TrainIndicies,resolution,obj,MAXRETURN)
%function [X,y,N, ExtractedLocations] = SobelObjectDetector_GetTrainData(CAfilelist,TrainIndicies,resolution,obj,MAXRETURN)
%
%
neg_per_pos = 10;
% (1) Get Training Data
[X,y,ExtractedLocations] = GetTrainingData(CAfilelist,TrainIndicies,resolution,neg_per_pos,obj,MAXRETURN);
%normalize columns
N = Normalize_Mtx_Learn(X);
X = Normalize_Mtx_Apply(X,N);



function [X,y,ExtractedLocations] = GetTrainingData(CAfilelist,TrainIndicies,resolution,neg_per_pos,obj,MAXRETURN)
X = [];
y = [];
ExtractedLocations = [];
for i = TrainIndicies
  fprintf('extracting training data %d of %d\n',find(TrainIndicies==i),length(TrainIndicies));
  %[p2,n2,e2] = fileparts(backslash2frontslash(CAfilelist{i}.imagename));
  %[p1,n1] = fileparts(p2);
  %orig_name = '/scratch2/bileschi/SSDB_Unfiltered/';
  %olist_name = fullfile(orig_name,n1,[n2,'_olist.mat']); 
  %orig_name = fullfile(orig_name,n1,[n2,'.JPG']);
  orig_name = CAfilelist{i}.imagename;
  olist_name = CAfilelist{i}.olistname;
  %
  im_orig = rgb2gray(imread(orig_name));
  olist = QReadOList2(olist_name);
  CAidx = i;
  [Xnew,ynew,ELnew] = GetOneImageTrainingData(im_orig, olist, resolution, neg_per_pos,CAidx,obj);
  ExtractedLocations = [ExtractedLocations,ELnew];
  X = [X,Xnew];
  y = [y;ynew];
  if((length(y)/(1+neg_per_pos)) > MAXRETURN)
    return;
  end 
end

function  [X,y,ExtractedLocations] = GetOneImageTrainingData(im_orig, olist, resolution, neg_per_pos,CAidx,obj)
X = [];,y = [];
if(not(isfield(olist,obj)))
  ExtractedLocations = [];
  return;
end
ncars = length(olist.(obj));
X = zeros(prod(resolution)*6,(ncars * (neg_per_pos * 1)));
% (1) For Every Car
idx = 0;
for i= 1:ncars
%   (a) Get the bounding box
    bbox_orig = poly2bbox(olist.(obj){i});
    bbox = bboxEnforceAspectRatio(bbox_orig,resolution,'bottom');
    bbox = bboxDescretizeSize(bbox);
    %for padding around the crop.
    bbox = [bbox(1) - bbox(3)/6,bbox(2) - bbox(4)/6,bbox(3)*4/3,bbox(4)*4/3];
%   (b) Extract the car
    im_layers = bbox_N_Im_2_LayerIm(im_orig,bbox,resolution);
    idx = idx+1;
    ExtractedLocations(idx).bbox = bbox;
    ExtractedLocations(idx).bbox_orig = bbox_orig;
    ExtractedLocations(idx).bbox_orig_cxy = BBoxCenter(bbox_orig);
    ExtractedLocations(idx).CAidx = CAidx;
    ExtractedLocations(idx).y = 1;

%   (c) Record it
    X(:,idx) = im_layers(:);
    y = [y;1];
%   (d) for some non cars
    for j = 1:neg_per_pos
%       (i) Get the bounding box
        [bboxN,bbox_offset] = BBoxGetRandomSameSize_CenterInBound(bbox,size(im_orig));
        idx = idx+1;
	ExtractedLocations(idx).bbox = bboxN;
	ExtractedLocations(idx).CAidx = CAidx;
	ExtractedLocations(idx).y = -1;
        ExtractedLocations(idx).bbox_orig = bbox_orig + bbox_offset;
        ExtractedLocations(idx).bbox_orig_cxy = BBoxCenter(bbox_orig + bbox_offset);
%       (ii)    Extract it
        im_layers = bbox_N_Im_2_LayerIm(im_orig,bboxN,resolution);
%       (iii)   Record it
        X(:,idx) = im_layers(:);
	y = [y;-1];
    end
end

function bbox = bboxDescretizeSize(bbox);
%resizes box so that width is a member of floor(2^(n/2)) n elm Z
%
width = bbox(3);
PowersOfSqt2 = ((2^.5).^ (2:21));
new_width = findNearestIn(width,PowersOfSqt2);
resize_factor = new_width / width;
bbox = ResizeByFactor(bbox, resize_factor);

function bbox = ResizeByFactor(bbox, resize_factor)
cxy = BBoxCenter(bbox);
w = bbox(3);
h = bbox(4);
nw = w * resize_factor;
nh = h * resize_factor;
bbox(1) = cxy(1) - floor(nw / 2);
bbox(2) = cxy(2) - floor(nh / 2);
bbox(3) = ceil(nw);
bbox(4) = ceil(nh);

function y = findNearestIn(sample,list);
d = list - sample;
[md,mdi] = min(abs(d));
y = list(mdi);

function cxy = BBoxCenter(bbox)
cxy = [bbox(1) + bbox(3) / 2, bbox(2) + bbox(4) / 2];

function im_layers = bbox_N_Im_2_LayerIm(im,bbox,resolution)
	crop = imcrop_pad(im,bbox,'symmetric');
        crop = imresize(crop, resolution*4,'bilinear');
        im_layers = ApplySobelFilts(crop);
        im_layers = maxfilter(im_layers,5);
        im_layers = imresize(im_layers,resolution,'bilinear');
	
function [bboxN,os] = BBoxGetRandomSameSize(bbox,s)
%function [bboxN,os] = BBoxGetRandomSameSize(bbox,s)
%
%returns a bbox the same size as bbox at a random location completely within s
maxL = s(2) - bbox(3) + 1;
maxT = s(1) - bbox(4) + 1;
L = ceil(rand * maxL);
T = ceil(rand * maxT);
bboxN = [L,T,bbox(3),bbox(4)];
os = [L - bbox(1), T - bbox(2), 0 , 0 ];

function [bboxN,os] = BBoxGetRandomSameSize_CenterInBound(bbox,s)
%function [bboxN,os] = BBoxGetRandomSameSize_CenterInBound(bbox,s)
%
%returns a bbox the same size as bbox at a random location who's center lies within the boundary.
wL = floor(bbox(3) / 2);
hT = floor(bbox(4) / 2);

cX = ceil(rand * s(2));
cY = ceil(rand * s(1));
bboxN = [cX - wL,cY - hT,bbox(3),bbox(4)];
os = [bboxN(1) - bbox(1), bboxN(2) - bbox(2), 0 , 0 ];



function s2 = backslash2frontslash(s1)
s2 = strrep(s1,'\','/');

function im_layers = ApplySobelFilts(crop)
filts{1} = [1,1,1;0,0,0;-1,-1,-1];
filts{2} = [-1,0,1;-1,0,1;-1,0,1];
filts{3} = [0,1,1;-1,0,1;-1,-1,0];
filts{4} = [1,1,0;1,0,-1;0,-1,-1];
filts{5} = [-1,-1,-1;-1,8,-1;-1,-1,-1];
filts{6} = [0,0,0;0,1,0;0,0,0];
s = size(crop);
im_layers = zeros(s(1),s(2),length(filts));
crop = im2double(crop);
for i = 1:length(filts)
  im_layers(:,:,i) = imfilter(crop,filts{i},'symmetric');
  if(i ~= 6)
    im_layers(:,:,i) = abs(im_layers(:,:,i));
  end
end





