【发布时间】:2017-11-15 15:40:06
【问题描述】:
我将使用 cuda 示例中的 grabcutNPP 来加快图像处理速度。原始示例代码是为 FIBITMAP 实现的,但我的输入/输出类型将是 Mat。
我已经弄清楚了大部分代码,但卡在了cudaMemcpyDeviceToHost 步骤……作为一个 CUDA 初学者,我没有理由总是在这一步停止
这是我的代码的一部分:
void grabcutGPU(Mat& _src, Mat& _dst, Rect _srcRect){
GrabCut *grabcut;
const size_t width = _src.rows;
const size_t height = _src.cols;
size_t image_pitch;
size_t result_pitch;
size_t trimap_pitch;
uchar4 *gpu_src, *gpu_dst;
unsigned char *d_trimap;
NppiRect rect;
// rect to nppirect
rect.x = _srcRect.x;
rect.y = _srcRect.y;
rect.width = _srcRect.width;
rect.height = _srcRect.height;
//melloc for src_image
checkCudaErrors(cudaMallocPitch(&gpu_src, &image_pitch, width * sizeof(uchar4), height));
checkCudaErrors(cudaMemcpy2D(gpu_src, image_pitch, _src.ptr<uchar4>(), width * sizeof(uchar4), width * sizeof(uchar4), height, cudaMemcpyHostToDevice));
// melloc foe rect
checkCudaErrors(cudaMallocPitch(&d_trimap, &trimap_pitch, width, height));
// Setup GrabCut
grabcut = new GrabCut(gpu_src, (int)image_pitch, d_trimap, (int)trimap_pitch, width, height);
//rect to memory
checkCudaErrors(TrimapFromRect(d_trimap, (int)trimap_pitch, rect, width, height));
//grabcut segmentation
grabcut->computeSegmentationFromTrimap();
//melloc for dst_image
checkCudaErrors(cudaMallocPitch(&gpu_dst, &result_pitch, width * 4, height));
//GPU process
checkCudaErrors(ApplyMatte(2, gpu_dst, (int)result_pitch, gpu_src, (int)image_pitch, grabcut->getAlpha(), grabcut->getAlphaPitch(), width, height));
size_t output_pitch = result_pitch;
//send result to dst
checkCudaErrors(cudaMemcpy2D(_dst.ptr(), (int)output_pitch, gpu_dst, result_pitch, width * 4, height, cudaMemcpyDeviceToHost));
delete grabcut;
checkCudaErrors(cudaDeviceSynchronize(), "Kernel Launch Failed");
checkCudaErrors(cudaFree(gpu_src), "CUDA Free Failed");
checkCudaErrors(cudaFree(gpu_dst));
checkCudaErrors(cudaFree(d_trimap), "CUDA Free Failed");}
【问题讨论】:
-
您的图像像素类型是 uchar4 吗?标准是 Vec3b,应该等于 uchar3。
-
宽度是列,高度是行!
-
因为有一个用于grabcut的alpha通道,这就是我使用uchar4的原因。这是否意味着我无法将结果传递给 Mat?还是我应该做一些额外的处理?
-
BGR转BGRA后就可以了!非常感谢!
-
太棒了,如果你愿意,自己写一个答案:)