~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/apps/traincascade/HOGfeatures.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "opencv2/core.hpp"
 
2
#include "opencv2/imgproc.hpp"
 
3
 
 
4
#include "HOGfeatures.h"
 
5
#include "cascadeclassifier.h"
 
6
 
 
7
using namespace std;
 
8
using namespace cv;
 
9
 
 
10
CvHOGFeatureParams::CvHOGFeatureParams()
 
11
{
 
12
    maxCatCount = 0;
 
13
    name = HOGF_NAME;
 
14
    featSize = N_BINS * N_CELLS;
 
15
}
 
16
 
 
17
void CvHOGEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize)
 
18
{
 
19
    CV_Assert( _maxSampleCount > 0);
 
20
    int cols = (_winSize.width + 1) * (_winSize.height + 1);
 
21
    for (int bin = 0; bin < N_BINS; bin++)
 
22
    {
 
23
        hist.push_back(Mat(_maxSampleCount, cols, CV_32FC1));
 
24
    }
 
25
    normSum.create( (int)_maxSampleCount, cols, CV_32FC1 );
 
26
    CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
 
27
}
 
28
 
 
29
void CvHOGEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
 
30
{
 
31
    CV_DbgAssert( !hist.empty());
 
32
    CvFeatureEvaluator::setImage( img, clsLabel, idx );
 
33
    vector<Mat> integralHist;
 
34
    for (int bin = 0; bin < N_BINS; bin++)
 
35
    {
 
36
        integralHist.push_back( Mat(winSize.height + 1, winSize.width + 1, hist[bin].type(), hist[bin].ptr<float>((int)idx)) );
 
37
    }
 
38
    Mat integralNorm(winSize.height + 1, winSize.width + 1, normSum.type(), normSum.ptr<float>((int)idx));
 
39
    integralHistogram(img, integralHist, integralNorm, (int)N_BINS);
 
40
}
 
41
 
 
42
//void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
 
43
//{
 
44
//    _writeFeatures( features, fs, featureMap );
 
45
//}
 
46
 
 
47
void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
 
48
{
 
49
    int featIdx;
 
50
    int componentIdx;
 
51
    const Mat_<int>& featureMap_ = (const Mat_<int>&)featureMap;
 
52
    fs << FEATURES << "[";
 
53
    for ( int fi = 0; fi < featureMap.cols; fi++ )
 
54
        if ( featureMap_(0, fi) >= 0 )
 
55
        {
 
56
            fs << "{";
 
57
            featIdx = fi / getFeatureSize();
 
58
            componentIdx = fi % getFeatureSize();
 
59
            features[featIdx].write( fs, componentIdx );
 
60
            fs << "}";
 
61
        }
 
62
    fs << "]";
 
63
}
 
64
 
 
65
void CvHOGEvaluator::generateFeatures()
 
66
{
 
67
    int offset = winSize.width + 1;
 
68
    Size blockStep;
 
69
    int x, y, t, w, h;
 
70
 
 
71
    for (t = 8; t <= winSize.width/2; t+=8) //t = size of a cell. blocksize = 4*cellSize
 
72
    {
 
73
        blockStep = Size(4,4);
 
74
        w = 2*t; //width of a block
 
75
        h = 2*t; //height of a block
 
76
        for (x = 0; x <= winSize.width - w; x += blockStep.width)
 
77
        {
 
78
            for (y = 0; y <= winSize.height - h; y += blockStep.height)
 
79
            {
 
80
                features.push_back(Feature(offset, x, y, t, t));
 
81
            }
 
82
        }
 
83
        w = 2*t;
 
84
        h = 4*t;
 
85
        for (x = 0; x <= winSize.width - w; x += blockStep.width)
 
86
        {
 
87
            for (y = 0; y <= winSize.height - h; y += blockStep.height)
 
88
            {
 
89
                features.push_back(Feature(offset, x, y, t, 2*t));
 
90
            }
 
91
        }
 
92
        w = 4*t;
 
93
        h = 2*t;
 
94
        for (x = 0; x <= winSize.width - w; x += blockStep.width)
 
95
        {
 
96
            for (y = 0; y <= winSize.height - h; y += blockStep.height)
 
97
            {
 
98
                features.push_back(Feature(offset, x, y, 2*t, t));
 
99
            }
 
100
        }
 
101
    }
 
102
 
 
103
    numFeatures = (int)features.size();
 
104
}
 
105
 
 
106
CvHOGEvaluator::Feature::Feature()
 
107
{
 
108
    for (int i = 0; i < N_CELLS; i++)
 
109
    {
 
110
        rect[i] = Rect(0, 0, 0, 0);
 
111
    }
 
112
}
 
113
 
 
114
CvHOGEvaluator::Feature::Feature( int offset, int x, int y, int cellW, int cellH )
 
115
{
 
116
    rect[0] = Rect(x, y, cellW, cellH); //cell0
 
117
    rect[1] = Rect(x+cellW, y, cellW, cellH); //cell1
 
118
    rect[2] = Rect(x, y+cellH, cellW, cellH); //cell2
 
119
    rect[3] = Rect(x+cellW, y+cellH, cellW, cellH); //cell3
 
120
 
 
121
    for (int i = 0; i < N_CELLS; i++)
 
122
    {
 
123
        CV_SUM_OFFSETS(fastRect[i].p0, fastRect[i].p1, fastRect[i].p2, fastRect[i].p3, rect[i], offset);
 
124
    }
 
125
}
 
126
 
 
127
void CvHOGEvaluator::Feature::write(FileStorage &fs) const
 
128
{
 
129
    fs << CC_RECTS << "[";
 
130
    for( int i = 0; i < N_CELLS; i++ )
 
131
    {
 
132
        fs << "[:" << rect[i].x << rect[i].y << rect[i].width << rect[i].height << "]";
 
133
    }
 
134
    fs << "]";
 
135
}
 
136
 
 
137
//cell and bin idx writing
 
138
//void CvHOGEvaluator::Feature::write(FileStorage &fs, int varIdx) const
 
139
//{
 
140
//    int featComponent = varIdx % (N_CELLS * N_BINS);
 
141
//    int cellIdx = featComponent / N_BINS;
 
142
//    int binIdx = featComponent % N_BINS;
 
143
//
 
144
//    fs << CC_RECTS << "[:" << rect[cellIdx].x << rect[cellIdx].y <<
 
145
//        rect[cellIdx].width << rect[cellIdx].height << binIdx << "]";
 
146
//}
 
147
 
 
148
//cell[0] and featComponent idx writing. By cell[0] it's possible to recover all block
 
149
//All block is nessesary for block normalization
 
150
void CvHOGEvaluator::Feature::write(FileStorage &fs, int featComponentIdx) const
 
151
{
 
152
    fs << CC_RECT << "[:" << rect[0].x << rect[0].y <<
 
153
        rect[0].width << rect[0].height << featComponentIdx << "]";
 
154
}
 
155
 
 
156
 
 
157
void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, Mat &norm, int nbins) const
 
158
{
 
159
    CV_Assert( img.type() == CV_8U || img.type() == CV_8UC3 );
 
160
    int x, y, binIdx;
 
161
 
 
162
    Size gradSize(img.size());
 
163
    Size histSize(histogram[0].size());
 
164
    Mat grad(gradSize, CV_32F);
 
165
    Mat qangle(gradSize, CV_8U);
 
166
 
 
167
    AutoBuffer<int> mapbuf(gradSize.width + gradSize.height + 4);
 
168
    int* xmap = (int*)mapbuf + 1;
 
169
    int* ymap = xmap + gradSize.width + 2;
 
170
 
 
171
    const int borderType = (int)BORDER_REPLICATE;
 
172
 
 
173
    for( x = -1; x < gradSize.width + 1; x++ )
 
174
        xmap[x] = borderInterpolate(x, gradSize.width, borderType);
 
175
    for( y = -1; y < gradSize.height + 1; y++ )
 
176
        ymap[y] = borderInterpolate(y, gradSize.height, borderType);
 
177
 
 
178
    int width = gradSize.width;
 
179
    AutoBuffer<float> _dbuf(width*4);
 
180
    float* dbuf = _dbuf;
 
181
    Mat Dx(1, width, CV_32F, dbuf);
 
182
    Mat Dy(1, width, CV_32F, dbuf + width);
 
183
    Mat Mag(1, width, CV_32F, dbuf + width*2);
 
184
    Mat Angle(1, width, CV_32F, dbuf + width*3);
 
185
 
 
186
    float angleScale = (float)(nbins/CV_PI);
 
187
 
 
188
    for( y = 0; y < gradSize.height; y++ )
 
189
    {
 
190
        const uchar* currPtr = img.ptr(ymap[y]);
 
191
        const uchar* prevPtr = img.ptr(ymap[y-1]);
 
192
        const uchar* nextPtr = img.ptr(ymap[y+1]);
 
193
        float* gradPtr = grad.ptr<float>(y);
 
194
        uchar* qanglePtr = qangle.ptr(y);
 
195
 
 
196
        for( x = 0; x < width; x++ )
 
197
        {
 
198
            dbuf[x] = (float)(currPtr[xmap[x+1]] - currPtr[xmap[x-1]]);
 
199
            dbuf[width + x] = (float)(nextPtr[xmap[x]] - prevPtr[xmap[x]]);
 
200
        }
 
201
        cartToPolar( Dx, Dy, Mag, Angle, false );
 
202
        for( x = 0; x < width; x++ )
 
203
        {
 
204
            float mag = dbuf[x+width*2];
 
205
            float angle = dbuf[x+width*3];
 
206
            angle = angle*angleScale - 0.5f;
 
207
            int bidx = cvFloor(angle);
 
208
            angle -= bidx;
 
209
            if( bidx < 0 )
 
210
                bidx += nbins;
 
211
            else if( bidx >= nbins )
 
212
                bidx -= nbins;
 
213
 
 
214
            qanglePtr[x] = (uchar)bidx;
 
215
            gradPtr[x] = mag;
 
216
        }
 
217
    }
 
218
    integral(grad, norm, grad.depth());
 
219
 
 
220
    float* histBuf;
 
221
    const float* magBuf;
 
222
    const uchar* binsBuf;
 
223
 
 
224
    int binsStep = (int)( qangle.step / sizeof(uchar) );
 
225
    int histStep = (int)( histogram[0].step / sizeof(float) );
 
226
    int magStep = (int)( grad.step / sizeof(float) );
 
227
    for( binIdx = 0; binIdx < nbins; binIdx++ )
 
228
    {
 
229
        histBuf = histogram[binIdx].ptr<float>();
 
230
        magBuf = grad.ptr<float>();
 
231
        binsBuf = qangle.ptr();
 
232
 
 
233
        memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
 
234
        histBuf += histStep + 1;
 
235
        for( y = 0; y < qangle.rows; y++ )
 
236
        {
 
237
            histBuf[-1] = 0.f;
 
238
            float strSum = 0.f;
 
239
            for( x = 0; x < qangle.cols; x++ )
 
240
            {
 
241
                if( binsBuf[x] == binIdx )
 
242
                    strSum += magBuf[x];
 
243
                histBuf[x] = histBuf[-histStep + x] + strSum;
 
244
            }
 
245
            histBuf += histStep;
 
246
            binsBuf += binsStep;
 
247
            magBuf += magStep;
 
248
        }
 
249
    }
 
250
}