直接上代码:
#include <opencv2/opencv.hpp>
using namespace cv;
#include <cmath>
using namespace std;
template<typename T>
int _get_hog(vector<float> &hist, const Mat &img, const int nbins = 8, const bool need_normalize=false){
int rows_minus_1 = img.rows - 1;
int cols_minus_1 = img.cols - 1;
float dx, dy;
float angle;
const float angle_base = atan2f(0, -1);
const float angle_piece = 2.f*angle_base / (float)nbins;
int bin_id;
for (int y = 0; y < rows_minus_1; y++){
for (int x = 0; x < cols_minus_1; x++){
dx = (float)(img.at<T>(y, x) - img.at<T>(y, x + 1));
dy = (float)(img.at<T>(y, x) - img.at<T>(y + 1, x));
angle = atan2f(dy, dx) + angle_base;
bin_id = (int)floorf(angle / angle_piece);
hist[bin_id] += 1.f;
}
}
hist[nbins - 1] += hist[nbins];
hist.resize(nbins);
if (!need_normalize){
return 0;
}
float num_pixels = (float)(rows_minus_1*cols_minus_1);
for (int i = 0; i < nbins; i++){
hist[i] = hist[i] / num_pixels;
}
return 0;
}
// support
// CV_8UC1
// CV_32FC1
// CV_64FC1
int get_hog(vector<float> &hist, const Mat &img, const int nbins = 8, const bool need_normalize = false){
if (img.type() != CV_8UC1 && img.type() != CV_32FC1 && img.type() != CV_64FC1){
cerr << __FUNCDNAME__ << " invalid image type!" << endl;
return 1;
}
hist.resize(nbins+1);
hist.assign(nbins+1, 0);
if (img.type() == CV_8UC1){
return _get_hog<uchar> (hist, img, nbins, need_normalize);
}
else if (img.type() == CV_32FC1) {
return _get_hog<float> (hist, img, nbins, need_normalize);
}
else if (img.type() == CV_64FC1) {
return _get_hog<double>(hist, img, nbins, need_normalize);
}
return 1;
}