Я работаю с процессорной версией Гистограммы ориентированных градиентов OpenCV (HOG). Я использую изображение 32×32 с ячейками 4×4, блоками 4×4, без перекрытия между блоками и 15 ячейками ориентации. OpenCV-х HOGDescriptor
дает мне одномерный вектор характеристик длины 960. Это имеет смысл, потому что (32 * 32 пикселя) * (15 ориентаций) / (4 * 4 ячейки) = 960.
Тем не менее, я не уверен, как эти 960 номеров расположены в памяти. мой Угадай было бы, что это так:
vector<float> descriptorsValues =
[15 bins for cell 0, 0]
[15 bins for cell 0, 1]
...
[15 bins for cell 0, 7]
....
[15 bins for cell 7, 0]
[15 bins for cell 7, 1]
...
[15 bins for cell 7, 7]
Конечно, это двумерная проблема, сведенная в 1D, поэтому она будет выглядеть примерно так:
[cell 0, 0] [cell 0, 1] ... [cell 7, 0] ... [cell 7, 7]
Вот мой пример кода для этого:
using namespace cv;
//32x32 image, 4x4 blocks, 4x4 cells, 4x4 blockStride
vector<float> hogExample(cv::Mat img)
{
img = img.rowRange(0, 32).colRange(0,32); //trim image to 32x32
bool gamma_corr = true;
cv::Size win_size(img.rows, img.cols); //using just one window
int c = 4;
cv::Size block_size(c,c);
cv::Size block_stride(c,c); //no overlapping blocks
cv::Size cell_size(c,c);
int nOri = 15; //number of orientation bins
cv::HOGDescriptor d(win_size, block_size, block_stride, cell_size, nOri, 1, -1,
cv::HOGDescriptor::L2Hys, 0.2, gamma_corr, cv::HOGDescriptor::DEFAULT_NLEVELS);
vector<float> descriptorsValues;
vector<cv::Point> locations;
d.compute(img, descriptorsValues, cv::Size(0,0), cv::Size(0,0), locations);
printf("descriptorsValues.size() = %d \n", descriptorsValues.size()); //prints 960
return descriptorsValues;
}
Связанные ресурсы:
Это сообщение StackOverflow а также этот урок помог мне начать работу с OpenCV HOGDescriptor.
Я верю, что вы поняли правильную идею.
В оригинальной статье Гистограммы ориентированных градиентов для обнаружения человека (Страница 2), это говорит
[…] Окно детектора покрыто сеткой перекрывающихся блоков, в которые извлекаются векторы признаков гистограммы ориентированного градиента. […] […] Черепица окно обнаружения с плотной (фактически перекрывающейся) сеткой дескрипторов HOG и
используя объединенный векторный признак […]
Все о чем говорили плиточные работы их вместе. Хотя никакой подробной информации о том, как их объединить, пока нет. Я предполагаю, что здесь не должно происходить никаких причудливых вещей (иначе они будут говорить об этом), то есть просто регулярно объединять их (слева направо, сверху вниз).
В конце концов, это разумный и самый простой способ размещения данных.
Редактировать: Вы убедите себя больше, если вы посмотрите на как люди получают доступ и визуализируют данные.
for (int blockx=0; blockx<blocks_in_x_dir; blockx++)
{
for (int blocky=0; blocky<blocks_in_y_dir; blocky++)
{
for (int cellNr=0; cellNr<4; cellNr++)
{
for (int bin=0; bin<gradientBinSize; bin++)
{
float gradientStrength = descriptorValues[ descriptorDataIdx ];
descriptorDataIdx++;
// ... ...
} // for (all bins)
} // for (all cells)
} // for (all block x pos)
} // for (all block y pos)
Других решений пока нет …