- Principle
- Early
- Kernel
- Configuration file
- Effect
- Reference
What you do here is to use OpenCL to rotate the image 90 degrees, which is a relatively entry-level program. Hope to help you, look at the code is familiar with.
Principle
Image rotation refers to the definition of the image around a point in a counterclockwise or clockwise rotation of a certain angle, usually refers to the center of the image around the direction of rotation counterclockwise. Assuming that the upper-left corner of the image is (Ieft, top), and the lower-right corner is (r, bottom), any point on the image (x0, y0) rotates the ycenter angle counterclockwise around its center (xcenter, Angle), and the new coordinate position (x′, y′) is calculated as:
Early
Need to process the image, then introduce a library here to everyone: freeimage.
Not familiar to see: please click here.
Methods for using this library: (common method, very effective)
Property->c/c++-> General, additional Include Directories: path to Add. h.
Additional Library Directories: Add Lib Path, general, Linker.
Additional dependencies, input, linker: Add the required Lib name.
Put the DLL file under the EXE path.
Kernel
#pragma OPENCL EXTENSION cl_amd_printf:enable__kernelvoidImage_rotate (__globalUchar* Src_data, __globalUchar* Dest_data,//data in global memory intWintH//image Dimensions floatSintheta,floatCostheta)//rotation Parameters{//thread gets its index within index space Const intIX = GET_GLOBAL_ID (0);Const intiy = get_global_id (1);intXC = w/2;intYC = h/2;intXpos = (IX-XC) *costheta-(IY-YC) *sintheta+xc;intYpos = (IX-XC) *sintheta + (IY-YC) *costheta+yc; if ((xpos>=0) && (xpos< W) && (ypos>=0) && (ypos< H))//bound Checking{dest_data[ypos*w+xpos]= Src_data[iy*w+ix]; }}
We compare this with the CPU serial processing can be obtained as follows:
//cpu Rotate an Image: Use the CPU to rotate the picturevoidCpu_rotate (unsigned Char* Inbuf,unsigned Char* Outbuf,intWintHfloatSintheta,floatCostheta) {intI, J;intXC = w/2;intYC = h/2; for(i =0; I < H; i++) { for(j=0; j< W; J + +) {intXpos = (J-XC) *costheta-(I-YC) *sintheta+xc;intYpos = (J-XC) *sintheta + (I-YC) *costheta+yc;if(xpos>=0&&ypos>=0&&XPOS<W&&YPOS<H) Outbuf[ypos*w + xpos] = Inbuf[i*w+j]; } }}
After comparison we found that the OpenCL write kernel when the cycle is not, instead of giving global_id can be.
Configuration file
Here also involves a number of pictures of the operation, see the use of freeimage.
#include "stdafx.h"#include <CL/cl.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include <iostream>#include <fstream>#include "gFreeImage.h"using namespace STD;#define NWITEMS 4#pragma comment (lib, "OpenCL.lib")#pragma comment (lib, "FreeImage.lib")//To read a text file into a string, which is actually to pass the running program to the slave machineintConvertToString (Const Char*filename,STD::string& s) {size_t size;Char* STR;STD:: FStream f (filename, (STD:: Fstream::in |STD:: Fstream::binary));if(F.is_open ()) {size_t fileSize; F.SEEKG (0,STD:: Fstream::end); Size = FileSize = (size_t) f.tellg (); F.SEEKG (0,STD:: Fstream::beg); str =New Char[size+1];if(!STR) {F.close ();returnNULL; } f.read (str, fileSize); F.close (); Str[size] =' + '; s = str;Delete[] str;return 0; }printf("error:failed to open file%s\n", filename);return 1;}//cpu Rotate an Image: Use the CPU to rotate the picturevoidCpu_rotate (unsigned Char* Inbuf,unsigned Char* Outbuf,intWintHfloatSintheta,floatCostheta) {intI, J;intXC = w/2;intYC = h/2; for(i =0; I < H; i++) { for(j=0; j< W; J + +) {intXpos = (J-XC) *costheta-(I-YC) *sintheta+xc;intYpos = (J-XC) *sintheta + (I-YC) *costheta+yc;if(xpos>=0&&ypos>=0&&XPOS<W&&YPOS<H) Outbuf[ypos*w + xpos] = Inbuf[i*w+j]; } }}intMainintargcChar* argv[]) {//Loading images unsigned Char*src_image=0;unsigned Char*cpu_image=0;intW, H; Gfreeimage img;if(!img. Loadimagegrey ("Lenna.jpg")) {printf("Loading lenna.jpg failed \ n");Exit(0); }ElseSrc_image = Img.getimagedatagrey (W, H); size_t mem_size = w*h; Cpu_image = (unsigned Char*)malloc(mem_size); Cl_uint status; CL_PLATFORM_ID platform;//Create platform ObjectStatus = Clgetplatformids (1, &platform, NULL); CL_DEVICE_ID device;//Create GPU devicesClgetdeviceids (Platform, Cl_device_type_gpu,1, &device, NULL);//Create ContextCl_context context = Clcreatecontext (NULL,1, &device, NULL, NULL, or NULL);//create command queueCl_command_queueQueue= Clcreatecommandqueue (context, device, cl_queue_profiling_enable, NULL);//Create three OpenCL memory objects and put the contents of the BUF1 through an implicit copy //Copy to CLBUF1,BUF2 content copied to Clbuf2 by means of a copy displayCl_mem d_ip = Clcreatebuffer (Context, cl_mem_read_only, mem_size, NULL, NULL); Cl_mem D_op = Clcreatebuffer (Context, cl_mem_write_only, mem_size, NULL, NULL); Status = Clenqueuewritebuffer (Queue, D_ip, Cl_true,0, Mem_size, (void*) Src_image,0, NULL, NULL);Const Char* filename ="rotate.cl";STD::stringSOURCESTR; Status = ConvertToString (filename, sourcestr);Const Char* Source = Sourcestr.c_str (); size_t sourcesize[] = {strlen(source)};//Create program ObjectCl_program program = Clcreateprogramwithsource (Context,1, &source, Sourcesize, NULL);//Compile program objectStatus = Clbuildprogram (program,1, &device, NULL, NULL, or NULL);if(Status! =0) {printf("Clbuild failed:%d\n", status);Chartbuf[0x10000]; Clgetprogrambuildinfo (program, device, Cl_program_build_log,0x10000, Tbuf, NULL);printf("\n%s\n", TBUF);return-1; }//Create kernel object //use the "image_rotate" function as the kernel //Create kernel objectCl_kernel kernel = Clcreatekernel (program,"Image_rotate", NULL);//Set kernel parameters floatSintheta =1, Costheta =0; Clsetkernelarg (Kernel,0,sizeof(Cl_mem), (void*) &d_ip); Clsetkernelarg (Kernel,1,sizeof(Cl_mem), (void*) &d_op); Clsetkernelarg (Kernel,2,sizeof(Cl_int), (void*) &w); Clsetkernelarg (Kernel,3,sizeof(Cl_int), (void*) &h); Clsetkernelarg (Kernel,4,sizeof(Cl_float), (void*) &sintheta); Clsetkernelarg (Kernel,5,sizeof(Cl_float), (void*) &costheta);//set Local and global workgroup sizessize_t localws[2] = { -, -} ; size_t globalws[2] = {W, H};//assume divisible byCl_event ev;//Execute kernelClenqueuendrangekernel (Queue, Kernel,2,0, GLOBALWS, LOCALWS,0, NULL, &ev); ClFinish (Queue);//Calculate kerenl Execution TimeCl_ulong StartTime, EndTime; Clgeteventprofilinginfo (EV, Cl_profiling_command_start,sizeof(Cl_ulong), &starttime, NULL); Clgeteventprofilinginfo (EV, Cl_profiling_command_end,sizeof(Cl_ulong), &endtime, NULL); Cl_ulong kernelexectimens = endtime-starttime;printf("Kernal exec time:%8.6f ms\n", kernelexectimens*1e-6);//Data copy back to host memory //Copy results from device to host unsigned Char*op_data=0; Op_data = (Cl_uchar *) Clenqueuemapbuffer (Queue, D_op, Cl_true, Cl_map_read,0, Mem_size,0, NULL, NULL, NULL);intI Cpu_rotate (Src_image,cpu_image, W, H,1,0); for(i =0; i < mem_size; i++) {src_image[i] =cpu_image[i]; } img. SaveImage ("Cpu_lenna_rotate.jpg"); for(i =0; i < mem_size; i++) {src_image[i] =op_data[i]; } img. SaveImage ("Lenna_rotate.jpg");if(Cpu_image) Free(Cpu_image);//Delete OpenCL resource objectClreleasememobject (D_IP); Clreleasememobject (D_OP); Clreleaseprogram (program); Clreleasecommandqueue (Queue); Clreleasecontext (context);return 0;}
Effect
Initial Picture:
After processing with OpenCL: A grayscale image is used.
After processing with the CPU: Grayscale image is used.
Reference
Freeimage Download, please click here.
Please click here for the reference code.
The realization of the picture rotation of OpenCL