2013-11-01 72 views
0

我試過cudaMemcpy2DFromArray和cudaMemcpy2D,但都沒有正常工作。由於工作不正常,我的意思是GpuMat的確從cudaArray中複製了一些東西,但是水平尺度是錯誤的。如何將cudaArray(Cuda)複製到GpuMat(OpenCV)?

的代碼片段如下:

cudaArray *colorArr; 
checkCudaErrors(cudaGraphicsMapResources(1, &cudaResourceColor, 0)); 
checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&colorArr, cudaResourceColor, 0, 0)); 

cv::gpu::GpuMat gpuColorMat(Size(w,h), CV_32FC3); 

// Tried method 1: the following didn't work correctly 
checkCudaErrors(cudaMemcpy2DFromArray(gpuColorMat.data, gpuColorMat.step, colorArr, 
    0, 0, gpuColorMat.cols*sizeof(float3), gpuColorMat.rows, cudaMemcpyDeviceToDevice)); 

// Tried method 2: also didn't work correctly. Same error as the first method. 
float3 *cuarr; 
checkCudaErrors(cudaMalloc((void**)&cuarr, w*h*sizeof(float3))); 
checkCudaErrors(cudaMemcpy2DFromArray(cuarr, w*h, colorArr, 0, 0, w*sizeof(float3), h, cudaMemcpyDeviceToDevice)); 
checkCudaErrors(cudaMemcpy2D((float*)gpuColorMat.data, gpuColorMat.step, cuarr, w*sizeof(float3), w*sizeof(float3), h, cudaMemcpyDeviceToDevice)); 

// unmap buffer objects 
checkCudaErrors(cudaGraphicsUnmapResources(1, &cudaResourceColor, 0)); 

誰能幫助我?

回答

1

我終於做到了工作。我在下面分享我的代碼:

.cu file:做設備陣列的副本。渲染的圖像綁定到紋理inTex,並將其複製到目標float3 * dst。

texture<float4, 2, cudaReadModeElementType> inTex; 

__global__ void CuDeviceArrayCopyFromTexture(float3* dst, int dstStep, int width, int height)  
{ 
    int x = blockIdx.x * blockDim.x + threadIdx.x; 
    int y = blockIdx.y * blockDim.y + threadIdx.y; 

    if (x > width || y > height) return; 

    float4 res = tex2D(inTex, x, y); 
    float3* row_y = (float3*)((char*)dst + y * dstStep); 
    row_y[x] = make_float3(res.x, res.y, res.z); 
} 

// round up n/m 
inline int iDivUp(int n, int m) 
{ 
    return (n + m - 1)/m; 
} 

void DeviceArrayCopyFromTexture(float3* dst, int dstStep, int width, int height) 
{ 
    dim3 threads(64, 1); 
    dim3 grid = dim3(iDivUp(width, threads.x), height/threads.y); 
    CuDeviceArrayCopyFromTexture <<< grid, threads >>> (dst, dstStep, width, height); 
} 

void BindToTexture(cudaArray *cuArr) 
{ 
    checkCudaErrors(cudaBindTextureToArray(inTex, cuArr)); 
} 

.cpp file:設置gl渲染紋理,綁定到cuda紋理並調用設備數組拷貝方法。

glActiveTexture(GL_TEXTURE0); 
glGenTextures(1, &fboColorTex); 
glBindTexture(GL_TEXTURE_2D, fboColorTex); 
// I used RGB16F and RGB32F, both not working. So I changed to GL_RGBA16F and it could be mapped to cudaArray as float4 element. 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
checkCudaErrors(cudaGraphicsGLRegisterImage(&cudaResourceColor, fboColorTex, GL_TEXTURE_2D, cudaGraphicsMapFlagsReadOnly)); 

extern void BindToTexture(cudaArray *cuArr); 
extern void DeviceArrayCopyFromTexture(float3* dst, int dstStep, int width, int height); 

static GpuMat gpuMat(Size(w,h), CV_32FC3); 
cudaArray *cuArr; 

// Copy color buffer 
checkCudaErrors(cudaGraphicsMapResources(1, &cudaResourceColor, 0)); 
checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&cuArr, cudaResourceColor, 0, 0)); 

BindToTexture(cuArr); 
DeviceArrayCopyFromTexture((float3*)gpuMat.data, gpuMat.step, gpuMat.cols, gpuMat.rows ); 

checkCudaErrors(cudaGraphicsUnmapResources(1, &cudaResourceColor, 0)); 

參考文獻:

  1. http://answers.opencv.org/question/12958/read-rendered-images-using-gpumat-and-cuda/

  2. CUDA樣品\ V5.5 \ 3_Imaging \ postProcessGL

1

GpuMat ::一步中元素的個數,而pitch以字節爲單位,所以要儘量改變從

cudaMemcpy2DFromArray(gpuColorMat.data, gpuColorMat.step,     colorArr, 0, 0, gpuColorMat.cols*sizeof(float3), gpuColorMat.rows, cudaMemcpyDeviceToDevice); 

cudaMemcpy2DFromArray(gpuColorMat.data, gpuColorMat.step * sizeof(float3), colorArr, 0, 0, gpuColorMat.cols*sizeof(float3), gpuColorMat.rows, cudaMemcpyDeviceToDevice); 
+0

我想你的建議的方法。它也沒有工作。謝謝你們一樣! – Feng

相關問題