В моем проекте я рассчитываю функции HOG на GPU для разных уровней на одном изображении. Моя цель — обнаружить следующие объекты.
1. Грузовик
2. Автомобиль
3. Человек
Наиболее важный вопрос выбор размера окна в случае детектора объектов мультикласса. это post предоставляет очень хорошую базу, но она не дает ответа для выбора размера окна в случае использования мультикласса.
Чтобы решить эту проблему, я рассчитал характеристики HOG каждого положительного изображения на разных уровнях / разрешении, сохранив размер окна (48 * 96) одинаковым, но размер файла для каждого изображения составляет около 600 МБ, что слишком велико.
Пожалуйста, дайте мне знать, как выбрать размер окна, размер блока и размер ячейки в случае обнаружения мультиклассовых объектов. Вот мой код, который я использовал для расчета функций HOG.
void App::run()
{
unsigned int count = 1;
FileStorage fs;
running = true;
//int width;
//int height;
Size win_size(args.win_width, args.win_width * 2);
Size win_stride(args.win_stride_width, args.win_stride_height);
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);
VideoCapture vc("/home/ubuntu/Desktop/getdescriptor/images/image%d.jpg");
Mat frame;
Mat Left;
Mat img_aux, img, img_to_show, img_new;
cv::Mat temp;
gpu::GpuMat gpu_img, descriptors, new_img;
char cbuff[20];while (running)
{
vc.read(frame);if (!frame.empty())
{
workBegin();
width = frame.rows;
height = frame.cols;
sprintf (cbuff, "%04d", count);
// Change format of the image
if (make_gray) cvtColor(frame, img_aux, CV_BGR2GRAY);
else if (use_gpu) cvtColor(frame, img_aux, CV_BGR2BGRA);
else Left.copyTo(img_aux);
// Resize image
if (args.resize_src) resize(img_aux, img, Size(args.width, args.height));
else img = img_aux;
img_to_show = img;
gpu_hog.nlevels = nlevels;
hogWorkBegin();
if (use_gpu)
{
gpu_img.upload(img);
new_img.upload(img_new);
fs.open(cbuff, FileStorage::WRITE);for(int levels = 0; levels < nlevels; levels++)
{
gpu_hog.getDescriptors(gpu_img, win_stride, descriptors, cv::gpu::HOGDescriptor::DESCR_FORMAT_ROW_BY_ROW);
descriptors.download(temp);
//printf("size %d %d\n", temp.rows, temp.cols);
fs <<"level" << levels;
fs << "features" << temp;
cout<<"("<<width<<","<<height<<")"<<endl;
width = round(width/scale);
height = round(height/scale);
if( width < win_size.width || height < win_size.height )
break;
cout<<"Levels "<<levels<<endl;
resize(img,img_new,Size(width,height));
scale *= scale;
}
cout<<count<< " Image feature calculated !"<<endl;
count++;
//width = 640; height = 480;
scale = 1.05;
}
hogWorkEnd();
fs.release();
}
else running = false;
}
}
Размер окна должен быть выбран, s.t. объект (ы), который вы хотите обнаружить, вписывается в окно. Если вы хотите иметь разные размеры окон для разных типов, это может быть сложно.
Обычно вы делаете следующее
Если вы хотите использовать окна обнаружения разного размера, вы получите векторы объектов разного размера (в зависимости от особенностей HoG). Сложность в том, что на этапе тестирования вы должны использовать столько скользящих окон, сколько типов объектов, которые вы используете. Это определенно сработает, но вам придется обрабатывать каждое тестовое изображение несколько раз, что приводит к увеличению времени обработки)
Чтобы ответить на ваш вопрос о размерах: я не могу дать вам никакого значения, это всегда зависит от ваших изображений. Использование пирамиды изображений, как вы упомянули выше, является хорошим способом работы с объектами разного масштаба.
Пример кода для визуализации функций HoG можно найти Вот. Это также помогает понять, как выглядят векторы функций.
РЕДАКТИРОВАТЬ: Выяснили трудным путем, что только cv::Size(8,8)
разрешено для размера ячейки. Увидеть документация.