# FindEgret

## PURPOSE

FindEgret - A simple test case of detection using shape script.

## SYNOPSIS

This is a script file.

## DESCRIPTION

     FindEgret - A simple test case of detection using shape script.

       Detect egrets with a simple egret/pelican shape script template.

       The shape script template is found at "result/egret/egret_template.eps" or
     "result/egret/template.png". The detection results together with S3 and S2 maps
     are found at "result/egret".

## CROSS-REFERENCE INFORMATION

This function calls:

- GaborFilter GaborFilter - generate Gabor filter at fixed scale and orientation.
- applyfilterMultiScale applyfilterMultiScale - Filter image by a bank of multiscale filters, with local normalization.

This function is called by:

- StartFromHere StartFromHere - The entry point of this project.

## SOURCE CODE

    0001 % FindEgret - A simple test case of detection using shape script.
    0002 %
    0003 %   Detect egrets with a simple egret/pelican shape script template.
    0004 %
    0005 %   The shape script template is found at "result/egret/egret_template.eps" or
    0006 % "result/egret/template.png". The detection results together with S3 and S2 maps
    0007 % are found at "result/egret".
    0008
    0009 clear
    0010 close all
    0011 addpath('common');
    0012
    0013 category = 'egret';
    0014
    0015 %% load the S2 (shape motif) dictionary and S3 (shape script) template
    0016 load template_params
    0017 load result/transformedS2Template.mat
    0018 load result/egret/shapescript.mat
    0019
    0020 %% load the testing image
    0021
    0022 Iname = {'l1.jpg','l2.jpg','l3.jpg','l4.jpg','l5.jpg',...
    0023     'l6.jpg','l7.jpg','l8.jpg','l9.jpg','l10.jpg',...
    0024     'l11.jpg','l12.jpg','l13.jpg','l14.jpg','l15.jpg',...
    0025     'l16.jpg','l17.jpg','l18.jpg','l19.jpg','l20.jpg',...
    0026     'l4_dup.jpg', 'l12_dup.jpg', 'l12_dup2.jpg', 'l21.jpg', 'l22.jpg',...
    0027     'l23.jpg','l24.jpg','l25.jpg','l26.jpg','l27.jpg',...
    0028     'l28.jpg','l29.jpg','l30.jpg'};
    0029 imScale = [1.2 1.2 1 2 1,...
    0030     1 1.2 0.9 0.9 1,...
    0031     0.95 1 1.1 1 1,...
    0032     1.1 0.8 1.2 1.2 0.9,...
    0033     1.15 1.1 1.2 .55 .3,...
    0034     .3 .25 .3 .3 .4,...
    0035     .3 .35 .3];
    0036
    0037
    0038 subsampleM1 = 1;
    0039 for iImage = 1:length(Iname)
    0040     im = imread( sprintf('image/%s/%s',category,Iname{iImage}) );
    0041     im = imresize( im,imScale(iImage),'nearest' );
    0042
    0043     if size(im,3) == 3
    0044         im = rgb2gray(im);
    0045     end
    0046
    0047     im = single(im);
    0048     S1Map = applyfilterMultiScale({im},GaborFilter, nGaborOri);
    0049
    0050     % sigmoid transform
    0051     nImage = 1;
    0052     heightS1Map = zeros(length(S1Map),1,'single');
    0053     widthS1Map = zeros(length(S1Map),1,'single');
    0054     for i = 1:length(S1Map)
    0055         heightS1Map(i) = size(S1Map{i},1);
    0056         widthS1Map(i) = size(S1Map{i},2);
    0057     end
    0058     tmpNGaborOri = 1;
    0059     for i = 1:length(S1Map)
    0060         Csigmoid(nImage, heightS1Map(i), widthS1Map(i), tmpNGaborOri, GaborSaturation, S1Map(i));
    0061     end
    0062
    0063     % compute M1 map
    0064     sizeGaborPerScale = zeros(nGaborScale,1,'single');
    0065     for iS = 1:nGaborScale
    0066         sizeGaborPerScale(iS) = size( GaborFilter{(iS-1)*nGaborOri+1}, 1 );
    0067     end
    0068     locationShift = .2;
    0069     oriShift = 1;
    0070     [M1Map M1Trace M1RowShift M1ColShift M1OriShift] = ...
    0071         CcomputeMAX1( nGaborOri, S1Map, locationShift, oriShift, sizeGaborPerScale, subsampleM1 );
    0072
    0073     % compute S2 map
    0074     S2Map = CcomputeSUM2( nGaborOri, M1Map, TransformedTemplate, subsampleS2 );
    0075
    0076     % compute M2 map
    0077     locationPerturbationFraction = 0.2; subsampleM2 = 1;
    0078     M2Map = cell(nTransform, nS2);
    0079     M2LocationTrace = cell(nTransform, nS2);
    0080     M2TransformTrace = cell(nTransform, nS2);
    0081     for iS2 = 1:nS2
    0082         sizeTemplate = zeros(nTransform,1);
    0083         for iT = 1:nTransform
    0084             sizeTemplate(iT) = sqrt( ...
    0085                 size(TransformedTemplate{iT,iS2}.sym,1)...
    0086                 * size(TransformedTemplate{iT,iS2}.sym,2) ) / subsampleS2;
    0087         end
    0088         [M2Map(:,iS2) M2LocationTrace(:,iS2) M2TransformTrace(:,iS2) storedM2LocationShift] = ...
    0089               CcomputeMAX2( templateAffMat, S2Map((iS2-1)*nTransform + (1:nTransform)), locationPerturbationFraction, ...
    0090                  int32(sizeTemplate), subsampleM2 );
    0091         storedSizeS2Template{iS2} = sizeTemplate;
    0092     end
    0093
    0094     %% detection
    0095     subsampleS3 = 1;
    0096     %
    0097     % Compute SUM 3 map :
    0098     %
    0099     S3Map = CcomputeSUM3_loglinear( M2Map, S3Template, subsampleS3, nTransform );
    0100     selectedTransform = S3Template{1}.selectedTransform;
    0101     selectedRow = S3Template{1}.selectedRow;
    0102     selectedCol = S3Template{1}.selectedCol;
    0103     selectedS2Ind = S3Template{1}.selectedInd;
    0104     selectedLambda = S3Template{1}.selectedLambda;
    0105     selectedLogZ = S3Template{1}.selectedLogZ;
    0106     nF = length(selectedTransform);
    0107     %
    0108     %
    0109     %
    0110     storedS3Map = S3Map;
    0111     minval = min(S3Map{1}(:));
    0112
    0113     maxval = 10;
    0114     count = 0;
    0115     maxDetection = 1; % maximum number of detections, currently we only detect the maximum one
    0116
    0117
    0118     while maxval > -10
    0119         count = count + 1;
    0120         if count > maxDetection
    0121             break;
    0122         end
    0123
    0124         % find the best position
    0125         [maxval ind] = max(S3Map{1}(:));
    0126         col = ceil(ind/size(S3Map{1},1));
    0127         row = ind - (col-1) * size(S3Map{1},1);
    0128
    0129         overlay = single(im);
    0130         mask = zeros(size(im));
    0131         for iF = 1:nF
    0132             iT = selectedTransform(iF)+1;
    0133             iS2 = selectedS2Ind(iF) + 1;
    0134
    0135             part_row = row + selectedRow(iF);
    0136             part_col = col + selectedCol(iF);
    0137             if part_row <= 0 || part_col <= 0 || part_row > size(S3Map{1},1) || part_col > size(S3Map{1},2)
    0138                 continue;
    0139             end
    0140
    0141             % trace the deformation for each part
    0142             part_loc_trace = M2LocationTrace{iT,iS2}(part_row,part_col) + 1;
    0143             part_trans_trace = M2TransformTrace{iT,iS2}(part_row,part_col) + 1; % in matlab, the index start from 1
    0144             S2Size = storedSizeS2Template{iS2}(part_trans_trace); % size of the S2 template
    0145             part_row = part_row * subsampleS2 + floor( .5 + storedM2LocationShift(part_loc_trace,1) * S2Size ) * subsampleS2;
    0146             part_col = part_col * subsampleS2 + floor( .5 + storedM2LocationShift(part_loc_trace,2) * S2Size ) * subsampleS2;
    0147
    0148             S2T = TransformedTemplate{part_trans_trace,iS2};
    0149
    0150             for iGabor = 1:length(S2T.selectedRow)
    0151                 gabor_row = part_row + S2T.selectedRow(iGabor);
    0152                 gabor_col = part_col + S2T.selectedCol(iGabor);
    0153                 gabor_ori = S2T.selectedOri(iGabor) + 1;
    0154                 gabor_scale = S2T.selectedScale(iGabor) + 1;
    0155                 if gabor_row <= 0 || gabor_col <= 0 || gabor_row > size(im,1) || gabor_col > size(im,2)
    0156                     continue;
    0157                 end
    0158                 gabor_trace = M1Trace{(gabor_scale-1)*nGaborOri+gabor_ori}(gabor_row,gabor_col) + 1;
    0159                 gabor_dr = single(M1RowShift{gabor_scale}(gabor_trace,gabor_ori));
    0160                 gabor_dc = single(M1ColShift{gabor_scale}(gabor_trace,gabor_ori));
    0161                 gabor_do = single(M1OriShift{gabor_scale}(gabor_trace,gabor_ori));
    0162                 gabor_row = gabor_row + gabor_dr;
    0163                 gabor_col = gabor_col + gabor_dc;
    0164                 gabor_ori = gabor_do + 1; % note: gabor_do is already the transformed orientation
    0165                 while gabor_ori > nGaborOri
    0166                     gabor_ori = gabor_ori - nGaborOri;
    0167                 end
    0168                 while gabor_ori <= 0
    0169                     gabor_ori = gabor_ori + nGaborOri;
    0170                 end
    0171
    0172                 % strength of this Gabor symbol (between 0 and 1)
    0173                 S1score = S1Map{(gabor_scale-1)*nGaborOri+gabor_ori}(gabor_row,gabor_col);
    0174                 S1score = S1score - 3; % These two parameters are just for display purpose
    0175                 priorS1 = 0.5;
    0176                 strength = priorS1 * exp(S1score) / ( (1-priorS1) + priorS1 * exp(S1score) );
    0177                 strength = max(0.8,strength);
    0178
    0179                 % Gabor symbol
    0180                 patch = strength * GaborSymbol{(gabor_scale-1)*nGaborOri+gabor_ori};
    0181
    0182                 % below: the bounding box for Gabor inside the image
    0183                 top2 = gabor_row - floor(size(patch,1)/2);
    0184                 left2 = gabor_col - floor(size(patch,2)/2);
    0185                 for c = 1:size(patch,2)
    0186                     for r = 1:size(patch,1)
    0187                         c2 = left2 + c - 1;
    0188                         r2 = top2 + r - 1;
    0189                         if r2 <= 0 || r2 > size(mask,1) || c2 <= 0 || c2 > size(mask,2)
    0190                             continue;
    0191                         end
    0192                         val = patch(r,c);
    0193                         if val > mask(r2,c2)
    0194                             mask(r2,c2) = val;
    0195                         end
    0196                     end
    0197                 end
    0198             end
    0199
    0200         end
    0201
    0202         h = figure;
    0203         subplot(2,3,1);imshow(im+200*mask,[]);
    0204         subplot(2,3,2);imshow(S3Map{1},[]);
    0205         subplot(2,3,4);imshow(M2Map{selectedTransform(1)+1,selectedS2Ind(1)+1},[]);
    0206         subplot(2,3,5);imshow(M2Map{selectedTransform(2)+1,selectedS2Ind(2)+1},[]);
    0207         subplot(2,3,6);imshow(M2Map{selectedTransform(3)+1,selectedS2Ind(3)+1},[]);
    0208         mkdir(sprintf('result/%s',category));
    0209         saveas(h,sprintf('result/%s/detection%d_%s',category,count,Iname{iImage}));
    0210         save(sprintf('result/%s/detectionResult%d_%s.mat',category,count,Iname{iImage}),...
    0211             'im','mask','S3Map','M2Map', 'storedSizeS2Template');
    0212         close;
    0213
    0214         % inhibit the local region for the next detection
    0215         for r = row - floor(S3size/2/subsampleS2) : row + floor(S3size/2/subsampleS2)
    0216             for c = col - floor(S3size/2/subsampleS2) : col + floor(S3size/2/subsampleS2)
    0217                 if r <= 0 || c <= 0 || r > size(S3Map{1},1) || c > size(S3Map{1},2)
    0218                     continue;
    0219                 end
    0220                 S3Map{1}(r,c) = minval;
    0221             end
    0222         end
    0223     end
    0224 end
    0225