Извлечение функций HoG с использованием OpenCV
Я пытаюсь извлечь функции с помощью API OpenCV HoG, однако я не могу найти API, который позволяет мне это делать.
Я пытаюсь извлечь функции с помощью HoG из всего моего набора данных (заданное количество положительных и отрицательных изображений), а затем тренировать собственный SVM.
Я заглянул в HoG.cpp под OpenCV, и это не помогло. Все коды закопаны в сложностях и нуждаются в обслуживании разных аппаратных средств (например, Intel IPP).
Мой вопрос:
- Есть ли какой-либо API из OpenCV, который я могу использовать, чтобы извлечь все эти функции/дескрипторы для подачи в SVM? Если я могу использовать его для обучения моего SVM?
- Если нет, существуют ли там существующие библиотеки, которые могли бы выполнить одно и то же?
До сих пор я фактически переносил существующую библиотеку (http://hogprocessing.altervista.org/) из Processing (Java) на С++, но она все еще очень медленная, с обнаружением, занимающим не менее 16 секунд
Кто-нибудь еще успешно извлекает функции HoG, как вы обходили его? И есть ли у вас какие-то открытые исходные коды, которые я мог бы использовать?
Заранее спасибо
Ответы
Ответ 1
Вы можете использовать класс hog в opencv следующим образом
HOGDescriptor hog;
vector<float> ders;
vector<Point> locs;
Эта функция вычисляет функции hog для вас
hog.compute(grayImg, ders, Size(32, 32), Size(0, 0), locs);
Функции HOG, рассчитанные для grayImg
, сохраняются в векторе ders
, чтобы превратить его в матрицу, которую можно использовать позже для обучения.
Mat Hogfeat(ders.size(), 1, CV_32FC1);
for(int i=0;i<ders.size();i++)
Hogfeat.at<float>(i,0)=ders.at(i);
Теперь ваши функции HOG хранятся в матрице Hogfeat.
Вы также можете установить размер окна, размер ячейки и размер блока, используя объект hog
следующим образом:
hog.blockSize = 16;
hog.cellSize = 4;
hog.blockStride = 8;
// This is for comparing the HOG features of two images without using any SVM
// (It is not an efficient way but useful when you want to compare only few or two images)
// Simple distance
// Consider you have two HOG feature vectors for two images Hogfeat1 and Hogfeat2 and those are same size.
double distance = 0;
for(int i = 0; i < Hogfeat.rows; i++)
distance += abs(Hogfeat.at<float>(i, 0) - Hogfeat.at<float>(i, 0));
if (distance < Threshold)
cout<<"Two images are of same class"<<endl;
else
cout<<"Two images are of different class"<<endl;
Надеюсь, что это полезно:)
Ответ 2
Я также написал программу из 2 функций свиньи, сравниваемую с помощью этой статьи.
И я применяю этот метод для изменения области ROI или нет.
Пожалуйста, обратитесь к странице здесь.
исходный код и простое введение
Ответ 3
Здесь также есть версия графического процессора.
cv::Mat temp;
gpu::GpuMat gpu_img, descriptors;
cv::gpu::HOGDescriptor gpu_hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9,
cv::gpu::HOGDescriptor::DEFAULT_WIN_SIGMA, 0.2, gamma_corr,
cv::gpu::HOGDescriptor::DEFAULT_NLEVELS);
gpu_img.upload(img);
gpu_hog.getDescriptors(gpu_img, win_stride, descriptors, cv::gpu::HOGDescriptor::DESCR_FORMAT_ROW_BY_ROW);
descriptors.download(temp);
Ответ 4
OpenCV 3 предоставляет некоторые изменения в том, как пользователь может использовать алгоритмы GPU (например, CUDA), см. Руководство по переходу - CUDA.
Чтобы обновить ответ от user3398689 до OpenCV 3, вот отрезанный код:
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudaimgproc.hpp>
[...]
/* Suppose you load an image in a cv::Mat variable called 'src' */
int img_width = 320;
int img_height = 240;
int block_size = 16;
int bin_number = 9;
cv::Ptr<cv::cuda::HOG> cuda_hog = cuda::HOG::create(Size(img_width, img_height),
Size(block_size, block_size),
Size(block_size/2, block_size/2),
Size(block_size/2, block_size/2),
bin_number);
/* The following commands are optional: default values applies */
cuda_hog->setDescriptorFormat(cuda::HOG::DESCR_FORMAT_COL_BY_COL);
cuda_hog->setGammaCorrection(true);
cuda_hog->setWinStride(Size(img_width_, img_height_));
cv::cuda::GpuMat image;
cv::cuda::GpuMat descriptor;
image.upload(src);
/* May not apply to you */
/* CUDA HOG works with intensity (1 channel) or BGRA (4 channels) images */
/* The next function call convert a standard BGR image to BGRA using the GPU */
cv::cuda::GpuMat image_alpha;
cuda::cvtColor(image, image_alpha, COLOR_BGR2BGRA, 4);
cuda_hog->compute(image_alpha, descriptor);
cv::Mat dst;
image_alpha.download(dst);
Затем вы можете использовать дескрипторы в переменной "dst", как вам нравится, например, как предложено G453.