OPENCL+OPENCV implementation of Sobel algorithm

Source: Internet
Author: User

These days, looking at the OpenCL Programming Guide, follow the example in the book to implement the Sobel algorithm:

1. Combine OpenCV to read the image and save to the buffer;

2. Write and compile the kernel and save the results after display processing.

Kernel:

Const sampler_t Sampler = Clk_address_clamp_to_edge | Clk_filter_nearest;kernel void Sobel_rgb (read_only image2d_t src,write_only image2d_t DST) {int x = (int) get_global_id (0 int y = (int) get_global_id (1), if (x >= get_image_width (src) | | y >= get_image_height (src)) return;float4 p00 = Read _IMAGEF (SRC, sampler, (Int2) (X-1, y-1)); Float4 P10 = READ_IMAGEF (src, sampler, (Int2) (x, y-1)); Float4 P20 = Read_ima GEF (SRC, Sampler, (Int2) (x + 1, y-1)), float4 P01 = READ_IMAGEF (src, sampler, (Int2) (x-1, y)); Float4 P21 = READ_IMAGEF (  SRC, Sampler, (Int2) (x + 1, y)), float4 p02 = READ_IMAGEF (src, sampler, (Int2) (x-1, y + 1)); Float4 p12 = READ_IMAGEF (src, Sampler, (Int2) (x, y + 1)), float4 P22 = READ_IMAGEF (src, sampler, (Int2) (x + 1, y + 1)); FLOAT3 GX =-p00.xyz + p20.xyz + 2.0* (P21.XYZ-P01.XYZ)-p02.xyz + p22.xyz;float3 Gy =-p00.xyz + p02.xyz + 2.0* (p21.xyz-p10.xyz)-p20.xyz + p22.xyz;f LOAT3 g = native_sqrt (GX*GX + gy*gy); Write_imagef (DST, (Int2) (x, Y), (FLOAT4) (g.x,g.y,g.z,1.0f));}Todo:add OpenCL kernel code here. 

C + + Source:

BOOK:OPENCL (R) programming guide//authors:aaftab Munshi, Benedict Gaster, Timothy Mattson, James Fung, Dan ginsburg//isbn-10:0-321-74964-2//isbn-13:978-0-321-74964-2//Publisher:addison-wesley Professional//urls:h ttp://safari.informit.com/9780132488006///http://www.openclprogrammingguide.com////imagefilter2d.cpp////T His example demonstrates performing Gaussian filtering on a 2D image using//opencl////Requires freeimage Library F or image i/o://http://freeimage.sourceforge.net/#include <iostream> #include <fstream> #include <sstre am> #include <string.h> #include <opencv.hpp> #ifdef __apple__#include <OpenCL/cl.h> #else #   Include <CL/cl.h> #endif # include "FreeImage.h"/////Create a OpenCL context on the first available platform using// Either a GPU or CPU depending on what's Available.//cl_context Createcontext () {cl_int errnum;cl_uint NUMPLATFORMS;CL_PL ATFORM_ID Firstplatformid;cl_context Context = null;//First, select an OpenCL platform to run on.  For this example, we//simply choose the first available platform. Normally, would//query for all available platforms and select the most appropriate one.errnum = Clgetplatformids (1, & Amp;firstplatformid, &numplatforms); if (errnum! = cl_success | | numplatforms <= 0) {std::cerr << "Failed to fi nd any OpenCL platforms. "<< Std::endl;return NULL;}  Next, create an OpenCL context on the platform. Attempt to//Create a gpu-based context, and if that fails, try to create//a cpu-based context.cl_context_properties cont Extproperties[] ={cl_context_platform, (cl_context_properties) Firstplatformid,0};context = ClCreateContextFromType (Contextproperties, Cl_device_type_gpu,null, NULL, &errnum); if (errnum! = cl_success) {std::cout << "Could not Create GPU context, trying CPU ... "<< std::endl;context = Clcreatecontextfromtype (contextproperties, Cl_device_ Type_cpu,null, NULL, &errnum); if (errnum! = cl_success) {std::cerr << "Failed to create an OpenCL GPU or CPU context." << Std::endl;return NULL;}} return context;} Create a command queue on the first device available on the//context//cl_command_queue createcommandqueue (cl_cont Ext context, cl_device_id *device) {cl_int errnum;cl_device_id *devices;cl_command_queue commandqueue = NULL;size_t  Devicebuffersize = -1;//First get the size of the devices Buffererrnum = Clgetcontextinfo (context, cl_context_devices, 0, NULL, &devicebuffersize), if (errnum! = cl_success) {std::cerr << "Failed call to Clgetcontextinfo (..., gl_ Context_devices,...) "; return NULL;} if (devicebuffersize <= 0) {std::cerr << "No devices available."; return NULL;} Allocate memory for the devices bufferdevices = new Cl_device_id[devicebuffersize/sizeof (cl_device_id)];errnum = Clge Tcontextinfo (context, cl_context_devices, Devicebuffersize, DEVICES, NULL); if (errnum! = cl_success) {Std::cerr < < "Failed to get Device IDs"; RetuRN NULL;}  In this example, we just choose the first available device.  In a//Real program, you would likely with all available devices or choose//the highest performance device based on OpenCL Device Queriescommandqueue = Clcreatecommandqueue (context, Devices[0], 0, NULL); if (commandqueue = = NULL) {Std::cerr < < "Failed to create commandqueue for device 0"; return NULL;} *device = Devices[0];d elete[] Devices;return commandqueue;} Create an OpenCL program from the kernel source File//cl_program Createprogram (cl_context context, cl_device_id Dev Ice, const char* fileName) {cl_int errnum;cl_program program;std::ifstream kernelfile (FileName, std::ios::in); Kernelfile.is_open ()) {Std::cerr << "Failed to open file for reading:" << fileName << Std::endl;return N ULL;} Std::ostringstream oss;oss << kernelfile.rdbuf (); std::string srcstdstr = OSS.STR (); const char *SRCSTR = Srcstdstr.c_str ();p Rogram = Clcreateprogramwithsource (context, 1, (const char**) &AMP;SRCSTR,null, NULL), if (program = = NULL) {std::cerr << "Failed to create CL program from source." << Std::endl;return NULL;} Errnum = Clbuildprogram (program, 0, NULL, NULL, NULL, NULL); if (errnum! = cl_success) {//Determine the reason for the Erro Rchar buildlog[16384];clgetprogrambuildinfo (program, Device, Cl_program_build_log,sizeof (Buildlog), BuildLog, NULL) ; Std::cerr << ' Error in kernel: ' << std::endl;std::cerr << buildlog;clreleaseprogram (program); return NULL;} return program;} Cleanup any created OpenCL resources//void Cleanup (cl_context context, Cl_command_queue Commandqueue,cl_program PR Ogram, Cl_kernel kernel, Cl_mem Imageobjects[2],cl_sampler sampler) {for (int i = 0; i < 2; i++) {if (imageobjects[i]! = 0) Clreleasememobject (imageobjects[i]);} if (commandqueue! = 0) Clreleasecommandqueue (commandqueue); if (kernel! = 0) Clreleasekernel (kernel); if (program! = 0) Clreleaseprogram (program); if (sampler! = 0) Clreleasesampler (sampler); if (context! = 0) ClreleaseContext (context);} Load an image using the Freeimage library and create a opencl//image out of It//cl_mem LoadImage (Cl_context cont Ext, char *filename, int &width, int &height) {//free_image_format FORMAT = freeimage_getfiletype (fileName, 0);// fibitmap* image = Freeimage_load (format, fileName);////Convert to 32-bit image//fibitmap* temp = Image;//image = Freeimag E_convertto32bits (image);//freeimage_unload (temp);//width = Freeimage_getwidth (image);//height = Freeimage_ GetHeight (image);/*char *buffer = new Char[width * Height * 4];memcpy (buffer, freeimage_getbits (image), Width * Height * 4 ); Freeimage_unload (image); */cv::mat image1 = Cv::imread (fileName); width = Image1.cols;height = Image1.rows;char *buffer = New Char[width * Height * 4];int w = 0;for (int v = height-1; v >= 0; v--) {for (int u = 0; u <width; u++) {buffer[w + +] = image1.at<cv::vec3b> (V, u) [0];buffer[w++] = image1.at<cv::vec3b> (V, u) [1];buffer[w++] = image1.at <cv::Vec3b> (V, u) [2];w++;}} Create OpenCL Imagecl_image_format climageformat;climageformat.image_channel_order = Cl_rgba;climageformat.image_ Channel_data_type = cl_unorm_int8;cl_int Errnum;cl_mem climage;climage = clcreateimage2d (Context,CL_MEM_READ_ONLY | Cl_mem_copy_host_ptr,&climageformat,width,height,0,buffer,&errnum); if (errnum! = CL_SUCCESS) {Std::cerr << "Error Creating CL Image Object" << Std::endl;return 0;} return climage;} Save an image using the Freeimage library//bool saveimage (char *filename, char *buffer, int width, int height) {free _image_format FORMAT = Freeimage_getfiffromfilename (fileName); Fibitmap *image = Freeimage_convertfromrawbits ((byte*) buffer, width,height, Width * 4, 32,0xff000000, 0x00ff0000, 0x0000FF00); return freeimage_save (format, image, FileName);} Round up to the nearest multiple of the group size//size_t RoundUp (int groupsize, int globalsize) {int r = Globalsiz E% groupsize;if (r = = 0) {return globalsize;} Else{return globalsize + groupsize-r;}} /Main () for Hellobinaryworld example//int main (int argc, char** argv) {cl_context context = 0;cl_command_queue COMMANDQ Ueue = 0;cl_program program = 0;cl_device_id device = 0;cl_kernel kernel = 0;cl_mem Imageobjects[2] = {0, 0};cl_sampler  Sampler = 0;cl_int Errnum;/*if (argc! = 3) {std::cerr << "USAGE:" << argv[0] << "<inputImageFile> <outputImageFiles> "<< Std::endl;return 1;}  *///Create An OpenCL context on first available Platformcontext = Createcontext (); if (context = = NULL) {Std::cerr << "Failed to create OpenCL context." << Std::endl;return 1;}  Create a command-queue on the first device available//on the Created Contextcommandqueue = createcommandqueue (Context, &device); if (commandqueue = = NULL) {Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Make sure the device supports images, otherwise exitcl_bool imagesupport = Cl_false;clgetdeviceinfo (device, cl_device_i Mage_support, sizeof (Cl_booL), &imagesupport, NULL); if (imagesupport! = cl_true) {std::cerr << "OpenCL device does not support images." <& Lt Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Load input image from file and load it into//an OpenCL image objectint width, height;char *src0 = "C:/users/jiang/desk Top/image/tu1.jpg "; Imageobjects[0] = LoadImage (context, src0, width, height); if (imageobjects[0] = = 0) {Std::cerr < < "Error loading:" << std::string (SRC0) << Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Create ouput image Objectcl_image_format Climageformat;climageformat.image_channel_order = Cl_rgba; Climageformat.image_channel_data_type = cl_unorm_int8;imageobjects[1] = clcreateimage2d (Context,CL_MEM_WRITE_ONLY, &climageformat,width,height,0,null,&errnum); if (errnum! = cl_success) {std::cerr << "Error creating CL Output image object. "<< Std::endl; Cleanup (Context, CommAndqueue, program, kernel, imageobjects, sampler); return 1;} Create Sampler for sampling image objectsampler = Clcreatesampler (Context,cl_false,//non-normalized Coordinatescl_ad Dress_clamp_to_edge,cl_filter_nearest,&errnum); if (errnum! = cl_success) {std::cerr << "Error creating CL Sampler object. "<< Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Create OpenCL Program//program = Createprogram (context, device, "imagefilter2d.cl");p Rogram = Createprogram (Context, Device, "sobel.cl"), if (program = = NULL) {Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1 ;} Create OpenCL Kernelkernel = Clcreatekernel (program, "Sobel_rgb", null); if (kernel = = null) {Std::cerr << Failed To create kernel "<< Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Set the kernel argumentserrnum = clsetkernelarg (kernel, 0, sizeof (CL_MEM), &imageobjects[0]); ErrnuM |= Clsetkernelarg (kernel, 1, sizeof (CL_MEM), &imageobjects[1]);/*errnum |= Clsetkernelarg (kernel, 2, sizeof (CL_ Sampler), &sampler) errnum |= clsetkernelarg (kernel, 3, sizeof (Cl_int), &width); Errnum |= Clsetkernelarg ( Kernel, 4, sizeof (Cl_int), &height); */if (errnum! = cl_success) {std::cerr << "Error setting kernel arguments." & lt;< Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} size_t Localworksize[2] = {};size_t Globalworksize[2] = {RoundUp (localworksize[0], width), RoundUp (localworksize[ 1], height)};//Queue the kernel up for executionerrnum = Clenqueuendrangekernel (Commandqueue, kernel, 2, null,globalwork Size, localworksize,0, NULL, NULL), if (errnum! = cl_success) {std::cerr << "Error queuing kernel for execution." < < Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Read the output buffer back to the Hostchar *buffer = new Char[width * Height * 4];size_t Origin[3] = {0, 0, 0};size_t region[3] = {width, height, 1};errnum = Clenqueuereadimage (Commandqueue, Imageobject S[1], Cl_true,origin, region, 0, 0, buffer,0, NULL, NULL); if (errnum! = cl_success) {std::cerr << "Error reading ResU Lt buffer. "<< Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 1;} Std::cout << std::endl;std::cout << "Executed program succesfully." << std::endl;//memset (buffer, 0xFF, Width * height * 4);//Save the image out to Diskchar *saveimage = "c:/users/jiang/desktop/image/tu2.jpg";//std::cou T << buffer << Std::endl;cv::mat imagecolor = Cv::imread (SRC0); Cv::mat imagecolor2;imagecolor2.create ( Imagecolor.rows, Imagecolor.cols, Imagecolor.type ()), int w = 0;for (int v = imagecolor2.rows-1; v >=0; v--) {for (int u =0; U <imageColor2.cols; u++) {imagecolor2.at<cv::vec3b> (V, u) [0] = buffer[w++];imagecolor2.at<cv::vec3b> (V, u) [1] = buffer[w++]; Imagecolor2.at<cv::vec3B> (V, u) [2] = buffer[w++];w++;}} Cv::imshow ("image", ImageColor2); Cv::imwrite (SaveImage, ImageColor2); Cv::waitkey (0);/*if (!  SaveImage (saveimage, buffer, width, height)) {std::cerr << "Error Writing output Image:" << saveimage<< Std::endl; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler);d elete[] Buffer;return 1;} */delete[] buffer; Cleanup (context, Commandqueue, program, kernel, imageobjects, sampler); return 0;}


OPENCL+OPENCV implementation of Sobel algorithm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.