OpenCL: ядро ​​читает только первый пиксельC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 OpenCL: ядро ​​читает только первый пиксель

Сообщение Anonymous »

Ядро оттенков серого читает только первый пиксель
Ниже представлена ​​моя реализация ядра Grayscale.cl. Проблема, с которой я столкнулся, заключается в том, что ядро, похоже, выполняет расчет оттенков серого только для первого пикселя и присваивает это значение всем остальным пикселям во время итерации.
Правильно ли я использую read_imagef и write_imagef?

Код: Выделить всё

grayscale.cl

Код: Выделить всё

__kernel void grayscale(
__read_only image2d_t inputImage,
__write_only image2d_t outputImage,
const int width,
const int height)
{
int x = get_global_id(0); // X-coordinate
int y = get_global_id(1); // Y-coordinate

if (x < get_image_width(inputImage) && y < get_image_height(inputImage)) {
int2 coord = (int2)(x, y);
float4 pixel = read_imagef(inputImage, CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST, coord);

// Converts un-normalised values
float f_x = pixel.x * 255.0f;
float f_y = pixel.y * 255.0f;
float f_z = pixel.z * 255.0f;

printf("Processing pixel: (%d, %d) : %f, %f, %f\n", x, y, f_x, f_y, f_z);

// Grayscale calculation
float gray = 0.299f * f_x + 0.587f * f_y + 0.114f * f_z;

// Write the grayscale value to the output image
write_imagef(outputImage, coord, (float4)(gray, gray, gray, 1.0f));
}
}
Вывод отладки ядра

Код: Выделить всё

Processing pixel: (292, 233) : 23.000000, 5.000000, 3.000000
Processing pixel: (293, 233) : 23.000000, 5.000000, 3.000000
Processing pixel: (294, 233) : 23.000000, 5.000000, 3.000000
Processing pixel: (295, 233) : 23.000000, 5.000000, 3.000000
Ниже приведен соответствующий (обобщенный) код хоста для контекста.
Получение изображения с использованием OpenCV

Код: Выделить всё

// Load the input image using OpenCV
cv::Mat image = cv::imread(image_path, cv::IMREAD_COLOR);
if(image.empty()){
logger.log("Failed to load image", Logger::LogLevel::ERROR);
}

// Display image (if necessary)
if(DISPLAY_IMAGES){
cv::imshow("Reference Image Window", image);
cv::waitKey(0);
}

// Convert to RGBA and get image dimensions
cv::cvtColor(image, image, cv::COLOR_BGR2RGBA);
*width = image.cols;
*height = image.rows;

// Flatten image into uchar array
std::vector _input_data(image.data, image.data + image.total() * 4);
Объекты изображений

Код: Выделить всё

// Define cl_image variables and format
cl_image_format input_format;
input_format.image_channel_order = CL_RGBA;     // RGB
input_format.image_channel_data_type = CL_UNORM_INT8;

cl_image_format output_format;
output_format.image_channel_order = CL_R;       // Single channel (grayscale)
output_format.image_channel_data_type = CL_FLOAT;

// Create memory objects
cl_mem input_image = clCreateImage2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &input_format, width, height, 0, input_data.data(), &err_num);
if(err_num != CL_SUCCESS){
logger.log("Failed to create cl_image input_image mem object", Logger::LogLevel::ERROR);
}

cl_mem output_image = clCreateImage2D(*context, CL_MEM_WRITE_ONLY, &output_format, width, height, 0, nullptr, &err_num);
if(err_num != CL_SUCCESS){
logger.log("Failed to create cl_image output_image mem object", Logger::LogLevel::ERROR);
}
Ядро: запись, выполнение и чтение

Код: Выделить всё

// Initialise input image
size_t origin[3] = {0, 0, 0};
size_t region[3] = {width, height, 1};

// Set kernel arguments
err_num = clSetKernelArg(*kernel, 0, sizeof(cl_mem), &input_image);
err_num |= clSetKernelArg(*kernel, 1, sizeof(cl_mem), &output_image);
err_num |= clSetKernelArg(*kernel, 2, sizeof(int), &width);
err_num |= clSetKernelArg(*kernel, 3, sizeof(int), &height);
if(err_num != CL_SUCCESS){
logger.log("Failed to set kernel arguments", Logger::LogLevel::ERROR);
}

err_num = clEnqueueWriteImage(*command_queue, input_image, CL_TRUE, origin, region, 0, 0, input_data.data(), 0, nullptr, &write_event);
if(err_num != CL_SUCCESS){
logger.log("Failed to write cl_image", Logger::LogLevel::ERROR);
}

// Perform kernel
err_num = clEnqueueNDRangeKernel(*command_queue, *kernel, 2, nullptr, global_work_size, nullptr, 0, nullptr, &kernel_event);
if(err_num != CL_SUCCESS){
logger.log("Failed when executing kernel", Logger::LogLevel::ERROR);
}

// Read back image data
err_num = clEnqueueReadImage(*command_queue, output_image, CL_TRUE, origin, region, 0, 0, output_data.data(), 0, nullptr, &read_event);
if(err_num != CL_SUCCESS){
logger.log("Failed to read back image data from kernel", Logger::LogLevel::ERROR);
}
Я новичок в OpenCL, поэтому буду очень признателен за любую помощь.
Заранее спасибо!

Подробнее здесь: https://stackoverflow.com/questions/792 ... irst-pixel
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»