function X = makevector(imno, vecMet, row, col, verbose)
% makevector       Make (training or test) vectors from a texture image
%                  A local neighborhood of pixels make up the vectors,
% 
% Simplified use of this function may be used for the (standard) images that I 
% often use, (see teximage). These images are scaled to be in range [-1, 1].
% Also a filename (URL) may be given, first argument is just passed to teximage.
% 
% use:
% X = makevector(A, vecMet, row, col, verbose);   % A is a grayscale image
% X = makevector(imno, 'b', row, col);  % simplified use, a numbered image
% X = makevector(fn, 'b', row, col);    % simplified use, a filename
%-------------------------------------------------------------------------
% arguments:
%   X        The resulting vectors as a NxL matrix, size N is given by
%            'vecMet', and L is given as  numel(row)*numel(col)
%   A        The input grascale image. It should be scaled to be within wanted
%            range, often [-1,1].
%   imno     Simplified use,  a numbered image (1-85, 101-113), see teximage.m
%   fn       Simplified use, image given as filename, see  teximage.m  
%   vecMet   a letter which gives the method to use, the following are ready:
%            we have: N = size(makevector(ones(19),vecMet,10,10,0),1);
%     'a'    N=9,  3x3 block 
%     'b'    N=25, 5x5 block
%     'c'    N=29, 9x9 block - most of corners, 
%     'd'    N=13, 3x3 block + 4 pixels (5x5 block - 12 corner pixels)
%     'e'    N=21, 5x5 block - 4 corner pixels
%     'f'    N=25, 7x7 block - 24 corner pixels ('e' + 4 pixel)
%     'g'    N=17, 7x7 block - most of corners
%     'h'    N=9,  5x5 block - 16 pixel (a pluss pattern)
%     'i'    N=13, 7x7 block - averaging pixel values in some areas
%     'j'    N=73, 11x11 block - corners
%   row      row index(es) of center pixel(s)
%   col      column index(es) of center pixel(s)
%   verbose  0 or 1
%-------------------------------------------------------------------------
% example:
%  A = FTCM_generate(2, 128, 128, 0, 0.08);  % imagesc(A); colormap(gray);
%  X = makevector(A, 'b', 6:15, 26:35);     
%  X = makevector(16, 'b', 25:50:125);     % special numbered image used

%----------------------------------------------------------------------
% Copyright (c) 2010.  Karl Skretting.  All rights reserved.
% University of Stavanger (Stavanger University), Signal Processing Group
% Mail:  karl.skretting@uis.no   Homepage:  http://www.ux.uis.no/~karlsk/
%
% HISTORY:  dd.mm.yyyy
% Ver. 2.0  25.10.2010  the TC2011\matlab vesion made from \DICT\matlab\ 
% Ver. 3.0  14.10.2011  renamed makeTexVec.m to makevector and move to tct
%                       also some minor changes
% Ver. 3.1  22.01.2012  use teximage.m to get (scale) the image
% Ver. 3.2  15.02.2012  added vecMet 'i'
% Ver. 3.3  28.03.2012  added vecMet 'j'
%----------------------------------------------------------------------

mfile = 'makevector';
if (nargin < 3)
    error([mfile,': wrong number of arguments, see help.']);
end
if (nargin < 5); verbose = 0; end;
if (nargin < 4); col = row; end;

if isnumeric(imno) && (numel(imno) > 1)
    A = double(imno);
    imfile = ['Supplied image of size ',int2str(size(A,1)),'x',int2str(size(A,2))];
else
    [A, imfile] = teximage(imno, [-1,1], 0);
end
             
[N, blockSize, ia] = getN_plus(vecMet);

b1 = blockSize(1);     % width of block
a1 = floor((b1-1)/2);  % pixels in block left of center pixel
c1 = b1-a1-1;          % pixels in block right of center pixel 
b2 = blockSize(2);     % hight of block
a2 = floor((b2-1)/2);  % pixels in block above center pixel
c2 = b2-a2-1;          % pixels in block below center pixel
L = numel(row)*numel(col);
X = zeros(N,L);

if verbose
    t1 = [mfile,': vector method is ''',vecMet,''': N=',int2str(N),' from ',...
        int2str(b1),'x',int2str(b2),' block.'];
    t2 = ['Make ',int2str(L),' vectors from ',imfile,'.'];
    disp(t1);
    disp(t2);
end

% row and col is given as index for center pixel in block
% below it will be changed to index of upper left corner
if ( (min(row) < (a1+1)) || ...
     (max(row) > (size(A,1)-c1)) || ...     
     (min(col) < (a2+1)) || ...
     (max(col) > (size(A,2)-c2)) )
    A = utvid(A,a1,c1,a2,c2);
    if verbose
        disp('Extended image (so that pixels near edge can be used as center pixel).');
    end
else
    row = row-floor(b1/2);
    col = col-floor(b2/2);
    if verbose
        disp('   row and col changed from center to upper left corner ');
    end
end


i = 1;
pbs = prod(blockSize);
for r = (row-1)
    for c = (col-1);
        x = reshape( A(r+(1:b1),c+(1:b2)), b1*b2, 1);  % block as column vector
        if (N == pbs)
            X(:,i) = x;
        else
            if isnumeric(ia)
                X(:,i) = x(ia);
            elseif iscell(ia) 
                for n = 1:N
                    X(n,i) = mean(x(ia{n}));
                end
            end
        end
        i = i+1;
    end
end

return    % from main function

% ------------ subfunctions --------------

function B = utvid(A,a1,c1,a2,c2)  % mirror edges: a1 at left, c1 at right, a2 above and c2 below
    if (nargin < 3); c1 = a1; end;
    if (nargin < 4); a2 = a1; end;
    if (nargin < 5); c2 = c1; end;
    % disp('   extend image by mirrowing at edges ');
    B = A([(a1+1):(-1):2, 1:size(A,1), size(A,1) - (1:c1)],:);
    B = B(:,[(a2+1):(-1):2, 1:size(A,2), size(A,2) - (1:c2)]);
return


function [N, blockSize, ia] = getN_plus(vecMet)
if (vecMet == 'a')
    N = 9;
    blockSize = [3,3];
    ia = reshape(1:N,N,1);
elseif (vecMet == 'b') 
    N = 25;
    blockSize = [5,5];
    ia = reshape(1:N,N,1);
elseif (vecMet == 'c')
    N = 29;
    blockSize = [9,9];
    ia = find([ 0,0,0,0,1,0,0,0,0; ...   
                0,0,0,0,1,0,0,0,0; ...   
                0,0,0,1,1,1,0,0,0; ...
                0,0,1,1,1,1,1,0,0; ...
                1,1,1,1,1,1,1,1,1; ...
                0,0,1,1,1,1,1,0,0; ...
                0,0,0,1,1,1,0,0,0; ...
                0,0,0,0,1,0,0,0,0; ...   
                0,0,0,0,1,0,0,0,0      ]);   % 29 non-zeros
elseif (vecMet == 'd') 
    N = 13;
    blockSize = [5,5];
    ia = find( [ 0,0,1,0,0; ...
                 0,1,1,1,0; ...
                 1,1,1,1,1; ...
                 0,1,1,1,0; ...
                 0,0,1,0,0  ]);   % 13 non-zeros
elseif (vecMet == 'e') 
    N = 21;
    blockSize = [5,5];
    ia = find( [ 0,1,1,1,0; ...
                 1,1,1,1,1; ...
                 1,1,1,1,1; ...
                 1,1,1,1,1; ...
                 0,1,1,1,0  ]);   % 21 non-zeros
elseif (vecMet == 'f')
    N  = 25;
    blockSize = [7,7];
    ia = find([ 0,0,0,1,0,0,0; ...   
                0,0,1,1,1,0,0; ...
                0,1,1,1,1,1,0; ...
                1,1,1,1,1,1,1; ...
                0,1,1,1,1,1,0; ...
                0,0,1,1,1,0,0; ...
                0,0,0,1,0,0,0      ]);   % 25 non-zeros
elseif (vecMet == 'g') 
    N  = 17;
    blockSize = [7,7];
    ia = find([ 0,0,0,1,0,0,0; ...   
                0,0,0,1,0,0,0; ...
                0,0,1,1,1,0,0; ...
                1,1,1,1,1,1,1; ...
                0,0,1,1,1,0,0; ...
                0,0,0,1,0,0,0; ...
                0,0,0,1,0,0,0      ]);   % 17 non-zeros
elseif (vecMet == 'h') 
    N = 9;
    blockSize = [5,5];
    ia = find( [ 0,0,1,0,0; ...
                 0,0,1,0,0; ...
                 1,1,1,1,1; ...
                 0,0,1,0,0; ...
                 0,0,1,0,0  ]);   % 9 non-zeros
elseif (vecMet == 'i') 
    N  = 13;
    blockSize = [7,7];
    a = [1,2,3,8,9,10,15,16,17];
    ia = { 25, [4,11,18], [26,27,28], [32,39,46], [22,23,24], ...
           [17,18,19], [17,24,31], [31,32,33], [19,26,33], ...
           a, a+4, a+28, a+32 };   
elseif (vecMet == 'j')
    N = 73;
    blockSize = [11,11];
    ia = find([ 0,0,0,0,1,1,1,0,0,0,0; ...   
                0,0,0,0,1,1,1,0,0,0,0; ...   
                0,0,1,1,1,1,1,1,1,0,0; ...
                0,0,1,1,1,1,1,1,1,0,0; ...
                1,1,1,1,1,1,1,1,1,1,1; ...
                1,1,1,1,1,1,1,1,1,1,1; ...
                1,1,1,1,1,1,1,1,1,1,1; ...
                0,0,1,1,1,1,1,1,1,0,0; ...
                0,0,1,1,1,1,1,1,1,0,0; ...
                0,0,0,0,1,1,1,0,0,0,0; ...   
                0,0,0,0,1,1,1,0,0,0,0      ]);   % 73 non-zeros
end
return