2

I'm new to OpenCL and I'm trying to load a .png or .jpg image to blur it, but I can't seem to figure out where to even begin.

I would like to open an image given the image path, then send that image to a kernel which blurs the image, returns the blurred image and saves it as a .png or .jpg file.

Thanks! :)

Anders
  • 301
  • 5
  • 12
  • To be more helpful: what is your application language? The answer from D. Ehrmann already gives you some general instructions. – Christian Mar 09 '15 at 11:26

2 Answers2

2

The simplest way is to use OpenCV. Suppose, you use C++:

cv::Mat shore_mask = cv::imread("Shore_mask.jpg", CV_LOAD_IMAGE_GRAYSCALE);

Then create OpenCL image (or buffer, whatever you like):

cl_int ret_code = CL_SUCCESS;
cl_mem shore_mask_buff = clCreateBuffer(ocl_context, CL_MEM_COPY_HOST_PTR, shore_mask.cols * shore_mask.rows * sizeof(uint8_t), (void*)shore_mask.data, &ret_code);

After you do some black magick with that shore_mask_buff, you copy it back to OpenCV image:

ret_code = clEnqueueReadBuffer(ocl_command_queue, shore_mask_buff, CL_TRUE, 0, shore_mask.cols * shore_mask.rows * sizeof(uint8_t), (void*)shore_mask.data, 0, NULL, NULL);

And save it to file

cv::imwrite("Processed_shore_mask.jpg", shore_mask);

Source code above may be full of bugs & need to be carefully checked.

Roman Arzumanyan
  • 1,784
  • 10
  • 10
1

JPEGs and PNGs are both compressed, so the first thing you need to do is outside of OpenCL: load them into memory in an uncompressed form. Implementation detail: PNGs and JPEGs support different color spaces, channel counts, and bits per channel. If you're trying to build a robust solution, there's a lot to support.

A simple Gaussian blur can be done with a convolution kernel, so generate one based off the blur radius.

Your OpenCL code will accept the raw image data and the kernel, and it will return a blurred image. Push the data over with clEnqueueWriteBuffer. You'll run the kernel with clEnqueueNDRangeKernel, and read the blurred image data out with clEnqueueReadBuffer. When you run the kernel, you can run with different number of "processors." You'll have to benchmark a bit, and figuring out the optimal number can be a bit tricky. Experiment!

In the kernel (the OpenCL one), you're basically writing C code. Use get_group_id and get_num_groups to determine which chunk of the image the current "thread" is supposed to work on. Apply the convolution kernel to each pixel in the input, and write the result to the output.

Once OpenCL finishes, reencode the PNG/JPEG, hopefully keeping the color space, bit depth, transparency, etc., and write that to a file.

David Ehrmann
  • 7,366
  • 2
  • 31
  • 40