CUDA图像处理错误

3
我正在进行一个小的图像处理项目。我想运行一个CUDA程序来执行图像减法。因此,您有图像背景和一个具有相同背景但带有其他东西的图像。一旦您对这两个图像进行减法运算,就会得到剩下的内容。这两个图像的大小都为480*360,我的GPU是GTX780。我的程序抛出一个错误./main': free(): invalid next size (normal): 0x000000000126bd70 *** Aborted (core dumped)并且输出的图像是错误的。我一直在努力解决这个问题。以下是代码:
内核:
__global__ void add(unsigned char* a, unsigned char* b, unsigned char* c, int numCols, int numWidth) {
    int i = blockIdx.x * blockDim.x + threadIdx.x; //Column
    int j = blockIdx.y * blockDim.y + threadIdx.y; //Row
    if(i < numWidth && j < numCols)
    {
      int idx = j * numCols + i;
      c[idx] = b[idx] - a[idx];
    }   
}

和主要功能:

int main() {
    CImg<unsigned char> img1("1.bmp");
    CImg<unsigned char> img2("2.bmp");
    //both images have the same size
    int width = img1.width();
    int height = img1.height();

    int size = width * height * 3; //both images of same size

    dim3 blockSize(16, 16, 1);
    dim3 gridSize((width + blockSize.x - 1) / blockSize.x, (height + blockSize.y - 1) / blockSize.y, 1);

    unsigned char *dev_a, *dev_b, *dev_c;

    cudaMalloc((void**)&dev_a, size * (sizeof(unsigned char)));
    cudaMalloc((void**)&dev_b, size * (sizeof(unsigned char)));
    cudaMalloc((void**)&dev_c, size * (sizeof(unsigned char)));

    cudaMemcpy(dev_a, img1, size * (sizeof(unsigned char)), cudaMemcpyHostToDevice);
    cudaMemcpy(dev_b, img2, size * (sizeof(unsigned char)), cudaMemcpyHostToDevice);

    add<<<gridSize, blockSize>>>(dev_a, dev_b, dev_c, height, width);

    cudaMemcpy(img2, dev_c, size * (sizeof(unsigned char)), cudaMemcpyDeviceToHost);

    img2.save("out.bmp");
    cudaFree(dev_a);
    cudaFree(dev_b);
    cudaFree(dev_c);
    return 0;
}

图像加载使用CImg库。

1
j<numCols之前的代码行int idx = j * numCols + i;看起来有些可疑。如果j是您的列索引,您应该使用int idx = i * numCols + j; - Peter Barmettler
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - KostasRim
2
cudaMemcpy操作中,你应该使用img1.data()而不是仅仅使用img1,并且使用img2.data()而不是仅仅使用img2。这似乎是如何检索指向底层数据的指针的(请参见http://cimg.eu/reference/group__cimg__storage.html):“可以通过函数CImg<T>::data()检索此内存缓冲区的地址。” - Robert Crovella
@talonmies,你在这里。 - KostasRim
@KostasRim:感谢您的帮助。 - talonmies
显示剩余7条评论
1个回答

2
问题在于主机代码中对cimg容器的不正确使用。根据文档,图像数据指针通过data()方法访问,这意味着主机代码中的cudaMemcpy调用应该提供img1.data()img2.data()。[此答案是从评论中组合而成并添加为社区wiki条目]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接