Недавно я изучал использование OpenCL для уменьшения узкого места в нашем приложении, которое является вызовом cv :: HOGDescriptor :: compute (). Использование версии OpenCL кажется простым случаем использования UMat вместо Mat, и я уже добился некоторого успеха в следующем:
// Replaced the following...
// _descriptor_calculator.compute(image, descriptor_flat);
// with...
cv::UMat input = image.getUMat(cv::ACCESS_RW);
_descriptor_calculator.compute(input, descriptor_flat);
Работает для изображений с разрешением (до включительно) 2048x1536. Однако для изображения 2592x1936 я получаю необработанное исключение, и мой отладчик прерывается в gshandlereh.c.
GSUnwindInfo = *(PULONG)GSHandlerData;
if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags)
? (GSUnwindInfo & UNW_FLAG_EHANDLER)
: (GSUnwindInfo & UNW_FLAG_UHANDLER))
{
Disposition = __CxxFrameHandler3( // <--------- breaks here
ExceptionRecord,
EstablisherFrame,
ContextRecord,
DispatcherContext
);
}
else
{
Disposition = ExceptionContinueSearch;
}
Два важных момента для упоминания:
- Я могу исправить ошибку, уменьшив частоту дискретизации изображения, поэтому она, похоже, связана с размером изображения
- Версия кода процессора прекрасно работает с изображениями 2592x1936, поэтому я вполне уверен, что ни один из входных параметров не содержит ошибок
Уменьшение выборки больших изображений - мой запасной вариант, но я нахожу вывод, что версия OpenCL вычислительной функции дескриптора HOG не может обрабатывать изображения, превышающие определенный размер, немного неудовлетворительно - тот факт, что существует необработанное исключение, а не Утверждение и разумное сообщение об ошибке заставляют меня поверить, что это сложнее / зловещее, чем это ..!
Заранее спасибо
Кто-нибудь может пролить свет на это? Любой вклад будет оценен.
EDIT:
По запросу, отдельный пример. Я смог воспроизвести проблему, введя случайное изображение Google, которое было достаточно большим (искал jpgs размером 2592x1936):
cv::UMat img = cv::imread("image3.jpg", cv::IMREAD_COLOR).getUMat(cv::ACCESS_RW);
uint16_t image_width = img.cols;
uint16_t image_height = img.rows;
int down_scale = 1;
uint16_t _image_width = (uint16_t)ceil((float)(image_width / down_scale) / 16) * 16;
uint16_t _image_height = (uint16_t)ceil((float)(image_height / down_scale) / 16) * 16;
std::cout << _image_height << " x " << _image_width << std::endl;
std::cout << (_image_width - 16) % 16 << std::endl;
std::cout << (_image_height - 16) % 16 << std::endl;
auto descriptor_calculator = cv::HOGDescriptor(cv::Size(_image_width, _image_height), cv::Size(16, 16), cv::Size(16, 16), cv::Size(16, 16), 9);
std::vector<float> descriptor_flat;
descriptor_calculator.compute(img, descriptor_flat);
Аналогично исходной задаче, работает для достаточно маленьких изображений, не подходит для достаточно больших изображений. К сожалению, мне не удалось собрать гораздо больше информации от запуска вне среды IDE или настройки IDE для разбивки на все исключения - единственное, что я получил, это то, что исключение является нарушением прав доступа. Я задавался вопросом, был ли призыв к ceil вызывать нарушение доступа, но разрешение делится на 16, так что неудивительно, что переход на floor не имеет значения.
Дополнительная информация по запросу:
- работает в Windows
- Компилятор / IDE - это Visual Studio 2015
- Версия OpenCV - 3.4.0
Спасибо за помощь, рад предоставить больше информации