Я работаю над небольшим проектом обработки изображений. Я хочу запустить программу CUDA, которая выполняет вычитание изображений. Итак, у вас есть фон изображения и изображение с тем же фоном, но с некоторыми другими вещами на нем. Как только вы вычитаете изображения, вы получите то, что осталось. Оба изображения имеют размер 480 * 360, а мой графический процессор - 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.
int idx = j * numCols + i;
, которой предшествуетj<numCols
, выглядит подозрительно. Еслиj
является вашим индексом столбца, вам лучше использоватьint idx = i * numCols + j;
. - person Peter Barmettler   schedule 01.04.2016size = width * height * 3
, а затем передаете ширину и высоту как numWidth и numHeight.) - person Elijan9   schedule 01.04.2016sizeof(imga1)
равно 32, но потому что это указатель шаблона. - person KostasRim   schedule 01.04.2016img1.data()
вместоimg1
иimg2.data()
вместоimg2
вcudaMemcpy
операциях? похоже, как извлекается указатель на базовые данные: адрес этого буфера памяти может быть получен функцией CImg‹T›::data(). - person Robert Crovella   schedule 01.04.2016int
, я получил тот же правильный результат, что и при передаче в качестве параметраimg1.data()
. По какой-то причинеCimg()
выделяет дополнительные байты за сценой. Хотя я понятия не имею, почему он это делает. Еще раз спасибо - person KostasRim   schedule 03.04.2016Cimg
делает некоторые распределения за кулисами. Пришлось проверить документацию. - person KostasRim   schedule 03.04.2016