我最近一直在研究使用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;
}
有两点要提:
对较大的图像进行下采样是我的后备选项,但我发现结论是,HOG描述符计算功能的OpenCL版本无法处理超出一定大小的图像,这有点令人不满意-存在未处理的异常而不是异常的事实。断言和明智的错误消息使我相信它比这更复杂/更险恶。.
预先感谢
有人能对此有所启示吗?任何输入将不胜感激。
编辑:
根据要求,提供一个独立的示例。我能够通过输入足够大的随机Google图片(搜索大小为2592x1936的jpg)来重现该问题:
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整除,所以毫不奇怪地更改为下限没有任何影响。
根据要求提供的其他信息:
感谢您的帮助,很乐意提供更多信息