Задача написать программу, которая будет изменять яркость для каждого пикселя картинки. Само по себе изменение яркости кажется несложным, проблема непосредственно с самим OpenCL.
Код ниже по задумке должен преобразовать каждый пиксель в RGB цвет (123,123,123).
Код:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
int main() {
// Включаем использование OpenCL в OpenCV
cv::ocl::setUseOpenCL(true);
// Загружаем изображение
cv::Mat image = cv::imread("/home/marat/Desktop/white-opencl/h.jpg");
//cv::imshow("abc", image);
//cv::waitKey();
// Проверяем, удалось ли загрузить изображение
if (image.empty()) {
std::cout << "Не удалось загрузить изображение" << std::endl;
return -1;
}
// Создаем контекст OpenCL
cv::ocl::Context context;
if (!context.create(cv::ocl::Device::TYPE_GPU)) {
std::cout << "Не удалось создать контекст OpenCL" << std::endl;
return -1;
}
// Создаем объект управления очередью выполнения OpenCL
cv::ocl::Queue queue = cv::ocl::Queue(context, context.device(0));
// Создаем объект управления памятью OpenCL для изображения
cv::UMat uimage = image.getUMat(cv::ACCESS_READ, cv::USAGE_ALLOCATE_DEVICE_MEMORY);
// Создаем OpenCL ядро для преобразования пикселей
std::string kernelSource = R"(
__kernel void white_pixels(__global uchar3* image) {
int x = get_global_id(0);
int y = get_global_id(1);
int index = y * get_global_size(0) + x;
image[index].x = 123;
image[index].y = 123;
image[index].z = 123;
}
)";
cv::ocl::ProgramSource programSource(kernelSource);
cv::String errmsg;
//cv::String buildopt = cv::format("-D dstT=%s", cv::ocl::typeToStr(umat_dst.depth())); // "-D dstT=float"
cv::String buildopt = "";
cv::ocl::Program program = context.getProg(programSource, buildopt, errmsg);
cv::ocl::Kernel kernel("white_pixels", program);
// Устанавливаем аргументы ядра
kernel.set(0,uimage);
//kernel.args(cv::ocl::KernelArg::ReadWrite(uimage));
// Запускаем ядро на устройстве OpenCL
size_t globalSize[2] = {image.cols, image.rows};
if (!kernel.run(2, globalSize, nullptr, false)) {
std::cout << "Ошибка выполнения ядра OpenCL" << std::endl;
return -1;
}
// Копируем результат обратно в память хоста
//image = uimage.getMat(cv::ACCESS_READ);
uimage.copyTo(image);
// Отображаем результат
cv::imshow("The result", image);
cv::waitKey();
return 0;
}