File size: 5,304 Bytes
7142654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
function WriteOutFaceCheckersCNNbinary(locationTxt, faceCheckers)

    addpath('../PDM_helpers\');
    
    % use little-endian
    faceCheckerFile = fopen(locationTxt, 'w', 'l');        
    
    views = numel(faceCheckers);
    
    % Type 0 - linear SVR, 1 - feed forward neural net, 2 - CNN, 3 - new
    % CNN
    fwrite(faceCheckerFile, 3, 'uint'); % 4 bytes
            
    % Number of face checkers
    fwrite(faceCheckerFile, views, 'uint'); % 4 bytes
    
    % Matrices representing view orientations
    for i=1:views
        % this indicates that we're writing a 3x1 double matrix
        writeMatrixBin(faceCheckerFile, faceCheckers(i).centres', 6);
    end
    
    for i = 1:views
        
        % The normalisation models
        % Mean of images
        writeMatrixBin(faceCheckerFile, faceCheckers(i).mean_ex, 6);
                
        % Standard deviation of images
        writeMatrixBin(faceCheckerFile, faceCheckers(i).std_ex, 6);
                
        cnn = faceCheckers(i).cnn;
        
        num_depth_layers = size(cnn.layers,2);

        % Get the number of layers
        fwrite(faceCheckerFile, num_depth_layers, 'uint'); % 4 bytes
        
        % For disambiguation between FC and conv layers
        res = vl_simplenn(cnn, single(faceCheckers(i).mask), [], []);
        
        for layers=1:num_depth_layers
           
            % write layer type: 0 - convolutional, 1 - max pooling (2x2 stride 2), 2 -
            % fully connected, 3 - relu, 4 - sigmoid
            if(cnn.layers{layers}.type == 'conv')
                
                % First check if it is an FC layer (they are represented
                % like that in matconvnet)
                if(numel(res(layers).x) == numel(cnn.layers{layers}.weights{1}(:,:,:,1)))
                    % This is the fully connected layer
                    fwrite(faceCheckerFile, 2, 'uint'); % 4 bytes

                    % the bias term
                    writeMatrixBin(faceCheckerFile, cnn.layers{layers}.weights{2}(:), 5);
                    % the weights
                    
                    % Convert the filters to a matrix
                    weights_c = cnn.layers{layers}.weights{1};
                    size_w = size(weights_c);
                    weights = zeros(size_w(1)*size_w(2)*size_w(3), size_w(4));
                    weights(:) = weights_c;
                    writeMatrixBin(faceCheckerFile, weights, 5);
                else
                
                    % write the type (convolutional)
                    fwrite(faceCheckerFile, 0, 'uint'); % 4 bytes

                    num_in_map = size(cnn.layers{layers}.weights{1},3);

                    % write the number of input maps
                    fwrite(faceCheckerFile, num_in_map, 'uint'); % 4 bytes

                    num_out_kerns = size(cnn.layers{layers}.weights{1},4);

                    % write the number of kernels for each output map
                    fwrite(faceCheckerFile, num_out_kerns, 'uint'); % 4 bytes

                    % Write output map bias terms
                    for k2=1:num_out_kerns    
                        fwrite(faceCheckerFile, cnn.layers{layers}.weights{2}(k2), 'float32'); % 4 bytes
                    end

                    for k=1:num_in_map                                        
                        for k2=1:num_out_kerns
                            % Write out the kernel                              
                            W = squeeze(cnn.layers{layers}.weights{1}(:,:,k,k2));
                            writeMatrixBin(faceCheckerFile, W, 5);                
                        end
                    end    
                end
            elseif(cnn.layers{layers}.type == 'pool')
                fwrite(faceCheckerFile, 1, 'uint'); % 4 bytes, indicate max pooling layer, no params, assume (2x2 stride 2)
            elseif(cnn.layers{layers}.type == 'relu')
                fwrite(faceCheckerFile, 3, 'uint'); % 4 bytes, indicate relu layer, no params
            end            
        end
        

        % Piecewise affine warp
        
        nPix = faceCheckers(i).nPix;
        minX = faceCheckers(i).minX;
        minY = faceCheckers(i).minY;
               
        destination = reshape(faceCheckers(i).destination, numel(faceCheckers(i).destination), 1);         
        triangulation = faceCheckers(i).triangulation;
        triX = faceCheckers(i).triX;
        mask = faceCheckers(i).mask;
        alphas = faceCheckers(i).alphas;
        betas = faceCheckers(i).betas;
        
        fwrite(faceCheckerFile, nPix, 'uint'); % 4 bytes
        fwrite(faceCheckerFile, minX, 'float64'); % 8 bytes
        fwrite(faceCheckerFile, minY, 'float64'); % 8 bytes
        
        % Destination shape
        writeMatrixBin(faceCheckerFile, destination, 6);
        
        % Triangulation
        writeMatrixBin(faceCheckerFile, triangulation, 4);
        
        % Triangle map
        writeMatrixBin(faceCheckerFile, triX, 4);        

        % Mask
        writeMatrixBin(faceCheckerFile, mask, 4);        
        
        % Alphas
        writeMatrixBin(faceCheckerFile, alphas, 6);        

        % Betas
        writeMatrixBin(faceCheckerFile, betas, 6);        

    end
    
    fclose(faceCheckerFile);
    
end