]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/blob - src/piotr_fhog/fhog.hpp
d3b9d161b57001eb569e75afd07d3145624c081d
[hercules2020/kcf.git] / src / piotr_fhog / fhog.hpp
1 /*
2     - c++ wrapper for the piotr toolbox
3     Created by Tomas Vojir, 2014
4 */
5
6
7 #ifndef FHOG_HEADER_7813784354687
8 #define FHOG_HEADER_7813784354687
9
10 #include <vector>
11 #include <opencv2/opencv.hpp>
12
13 #include "gradientMex.h"
14
15
16 class FHoG
17 {
18 public:
19     //description: extract hist. of gradients(use_hog == 0), hog(use_hog == 1) or fhog(use_hog == 2)
20     //input: float one channel image as input, hog type
21     //return: computed descriptor
22     static std::vector<cv::Mat> extract(const cv::Mat & img, int use_hog = 2, int bin_size = 4, int n_orients = 9, int soft_bin = -1, float clip = 0.2)
23     {
24         // d image dimension -> gray image d = 1
25         // h, w -> height, width of image
26         // full -> ??
27         // I -> input image, M, O -> mag, orientation OUTPUT
28         int h = img.rows, w = img.cols, d = 1;
29         bool full = true;
30         if (h < 2 || w < 2) {
31             std::cerr << "I must be at least 2x2." << std::endl;
32             return std::vector<cv::Mat>();
33         }
34
35 //        //image rows-by-rows
36 //        float * I = new float[h*w];
37 //        for (int y = 0; y < h; ++y) {
38 //            const float * row_ptr = img.ptr<float>(y);
39 //            for (int x = 0; x < w; ++x) {
40 //                I[y*w + x] = row_ptr[x];
41 //            }
42 //        }
43
44         //image cols-by-cols
45         float * I = new float[h*w];
46         for (int x = 0; x < w; ++x) {
47             for (int y = 0; y < h; ++y) {
48                 I[x*h + y] = img.at<float>(y, x)/255.f;
49             }
50         }
51
52         float *M = new float[h*w], *O = new float[h*w];
53         gradMag(I, M, O, h, w, d, full);
54
55         int n_chns = (use_hog == 0) ? n_orients : (use_hog==1 ? n_orients*4 : n_orients*3+5);
56         int hb = h/bin_size, wb = w/bin_size;
57
58         float *H = new float[hb*wb*n_chns];
59         memset(H, 0, hb*wb*n_chns*sizeof(float));
60
61         if (use_hog == 0) {
62             full = false;   //by default
63             gradHist( M, O, H, h, w, bin_size, n_orients, soft_bin, full );
64         } else if (use_hog == 1) {
65             full = false;   //by default
66             hog( M, O, H, h, w, bin_size, n_orients, soft_bin, full, clip );
67         } else {
68             fhog( M, O, H, h, w, bin_size, n_orients, soft_bin, clip );
69         }
70
71         //convert, assuming row-by-row-by-channel storage
72         std::vector<cv::Mat> res;
73         int n_res_channels = (use_hog == 2) ? n_chns-1 : n_chns;    //last channel all zeros for fhog
74         res.reserve(n_res_channels);
75         for (int i = 0; i < n_res_channels; ++i) {
76             //output rows-by-rows
77 //            cv::Mat desc(hb, wb, CV_32F, (H+hb*wb*i));
78
79             //output cols-by-cols
80             cv::Mat desc(hb, wb, CV_32F);
81             for (int x = 0; x < wb; ++x) {
82                 for (int y = 0; y < hb; ++y) {
83                     desc.at<float>(y,x) = H[i*hb*wb + x*hb + y];
84                 }
85             }
86
87             res.push_back(desc.clone());
88         }
89
90         //clean
91         delete [] I;
92         delete [] M;
93         delete [] O;
94         delete [] H;
95
96         return res;
97     }
98
99 };
100
101 #endif //FHOG_HEADER_7813784354687