传统的OpenCV形态学运算函数不能直接在GPU上运行,现提供几种方法,使得膨胀、腐蚀能在GPU上实现加速。笔者使用的是GPU是Nvidia的,故以下代码基于CUDA。
1. 传统的膨胀、腐蚀
下面的例子是,对一个尺寸为5×5的矩形元素分别进行腐蚀、膨胀,元素的支点为其中心,坐标为(2, 2)。它相当于对3×3元素进行两次操作。
1.1 OpenCV 1.0
IplConvKernel *elem = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_RECT);
cvErode(src, dst, elem, 1); // 相当于cvErode(src, dst, NULL, 2);
cvDilate(src, dst, elem, 1); // 相当于cvDilate(src, dst, NULL, 2);
cvReleaseStructuringElement(&elem);
1.2 OpenCV 2.0
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5), cv::Point(2, 2));
cv::dilate(src, dst, kernel, cv::Point(2, 2), 1);
cv::dilate(src, dst, kernel, cv::Point(2, 2), 1);
2. 使用CUDA提供的函数实现腐蚀、膨胀
// 假设src、dst的类型为IplImage*
using namespace cv;
Mat mat_src = cvarrToMat(src);
Mat mat_dst(mat_src);
cuda::GpuMat gpu_src(mat_src);
cuda::GpuMat gpu_dst(mat_dst);
Mat elem = getStructuringElement( MORPH_RECT, Size(5, 5), Point(2, 2) );
Ptr<cuda::Filter> erodeFilter = cuda::createMorphologyFilter( MORPH_ERODE, CV_8U, elem );
erodeFilter->apply( gpu_src, gpu_dst );
Ptr<cuda::Filter> dilateFilter = cuda::createMorphologyFilter( MORPH_DILATE, CV_8U, elem );
dilateFilter->apply( gpu_src, gpu_dst );
gpu_dst.download( mat_dst );
*dst = IplImage( mat_dst );
需要注意的是,这种方法第一次使用时,耗时较多,从第二次调用开始,运行时间变得正常。