这几天在看opencl编程指南。照着书中的样例实现了sobel算法:

1.结合opencv读取图像,保存到缓冲区中。

2.编写和编译内核。并保存显示处理后的结果。

内核:

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_imagef(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;
float3 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++源代码:

//
// 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: http://safari.informit.com/9780132488006/
// http://www.openclprogrammingguide.com
// // ImageFilter2D.cpp
//
// This example demonstrates performing gaussian filtering on a 2D image using
// OpenCL
//
// Requires FreeImage library for image I/O:
// http://freeimage.sourceforge.net/ #include <iostream>
#include <fstream>
#include <sstream>
#include <string.h>
#include <opencv.hpp> #ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif #include "FreeImage.h" ///
// Create an OpenCL context on the first available platform using
// either a GPU or CPU depending on what is available.
//
cl_context CreateContext()
{
cl_int errNum;
cl_uint numPlatforms;
cl_platform_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, you would
// query for all available platforms and select the most appropriate one.
errNum = clGetPlatformIDs(1, &firstPlatformId, &numPlatforms);
if (errNum != CL_SUCCESS || numPlatforms <= 0)
{
std::cerr << "Failed to find 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 contextProperties[] =
{
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_context 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 buffer
errNum = 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 buffer
devices = new cl_device_id[deviceBufferSize / sizeof(cl_device_id)];
errNum = clGetContextInfo(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 use all available devices or choose
// the highest performance device based on OpenCL device queries
commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL);
if (commandQueue == NULL)
{
std::cerr << "Failed to create commandQueue for device 0";
return NULL;
} *device = devices[0];
delete[] devices;
return commandQueue;
} ///
// Create an OpenCL program from the kernel source file
//
cl_program CreateProgram(cl_context context, cl_device_id device, const char* fileName)
{
cl_int errNum;
cl_program program; std::ifstream kernelFile(fileName, std::ios::in);
if (!kernelFile.is_open())
{
std::cerr << "Failed to open file for reading: " << fileName << std::endl;
return NULL;
} std::ostringstream oss;
oss << kernelFile.rdbuf(); std::string srcStdStr = oss.str();
const char *srcStr = srcStdStr.c_str();
program = clCreateProgramWithSource(context, 1,
(const char**)&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 error
char 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 program, 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 an OpenCL
// image out of it
//
cl_mem LoadImage(cl_context context, 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 = FreeImage_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 image
cl_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 = globalSize % 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 commandQueue = 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 platform
context = 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 context
commandQueue = CreateCommandQueue(context, &device);
if (commandQueue == NULL)
{
Cleanup(context, commandQueue, program, kernel, imageObjects, sampler);
return 1;
} // Make sure the device supports images, otherwise exit
cl_bool imageSupport = CL_FALSE;
clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool),
&imageSupport, NULL);
if (imageSupport != CL_TRUE)
{
std::cerr << "OpenCL device does not support images." << std::endl;
Cleanup(context, commandQueue, program, kernel, imageObjects, sampler);
return 1;
} // Load input image from file and load it into
// an OpenCL image object
int width, height;
char *src0 = "C:/Users/jiang/Desktop/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 object
cl_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 object
sampler = clCreateSampler(context,
CL_FALSE, // Non-normalized coordinates
CL_ADDRESS_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");
program = CreateProgram(context, device, "Sobel.cl");
if (program == NULL)
{
Cleanup(context, commandQueue, program, kernel, imageObjects, sampler);
return 1;
}
// Create OpenCL kernel
kernel = 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 arguments
errNum = 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." << std::endl;
Cleanup(context, commandQueue, program, kernel, imageObjects, sampler);
return 1;
} size_t localWorkSize[2] = { 16, 16 };
size_t globalWorkSize[2] = { RoundUp(localWorkSize[0], width),
RoundUp(localWorkSize[1], height) }; // Queue the kernel up for execution
errNum = clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL,
globalWorkSize, 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 Host
char *buffer = new char[width * height * 4];
size_t origin[3] = { 0, 0, 0 };
size_t region[3] = { width, height, 1 };
errNum = clEnqueueReadImage(commandQueue, imageObjects[1], CL_TRUE,
origin, region, 0, 0, buffer,
0, NULL, NULL);
if (errNum != CL_SUCCESS)
{
std::cerr << "Error reading result 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 disk
char *saveImage = "C:/Users/jiang/Desktop/image/tu2.jpg";
//std::cout << 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);
delete[] buffer;
return 1;
}*/ delete[] buffer;
Cleanup(context, commandQueue, program, kernel, imageObjects, sampler);
return 0;
}

opencl+opencv实现sobel算法的更多相关文章

  1. Sobel算法

    最近看了一些Sobel算法,并试了一下,源码如下: private void Sobel(Bitmap img) { int width = img.Width; int height = img.H ...

  2. OpenCV实现KNN算法

    原文 OpenCV实现KNN算法 K Nearest Neighbors 这个算法首先贮藏所有的训练样本,然后通过分析(包括选举,计算加权和等方式)一个新样本周围K个最近邻以给出该样本的相应值.这种方 ...

  3. OpenCL + OpenCV 图像旋转

    ▶ 使用 OpenCV 从文件读取彩色的 png 图像,旋转一定角度以后写回文件 ● 代码,核函数 // rotate.cl //__constant sampler_t sampler = CLK_ ...

  4. java 在centos6.5+eclipse环境下调用opencv实现sift算法

    java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core ...

  5. OPENCV下SIFT算法使用方法笔记

    这几天继续在看Lowe大神的SIFT神作,看的眼花手脚抽筋.也是醉了!!!!实在看不下去,来点干货.我们知道opencv下自带SIFT特征检测以及MATCH匹配的库,这些库完全可以让我们进行傻瓜似的操 ...

  6. 用OpenCV实现Photoshop算法(三): 曲线调整

    http://blog.csdn.net/c80486/article/details/52499919 系列文章: 用OpenCV实现Photoshop算法(一): 图像旋转 用OpenCV实现Ph ...

  7. OpenCV中Camshitf算法学习(补充)

    结合OpenCV中Camshitf算法学习,做一些简单的补充,包括: 实现全自动跟随的一种方法 参考opencv中的相关demo,可以截取目标物体的图片,由此预先计算出其色彩投影图,用于实际的目标跟随 ...

  8. 基于OpenCV的KNN算法实现手写数字识别

    基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...

  9. 14FPGA综设之图像边沿检测的sobel算法

    连续学习FPGA基础课程接近一个月了,迎来第一个有难度的综合设计,图像的边沿检测算法sobel,用verilog代码实现算法功能. 一设计功能 (一设计要求) (二系统框图) 根据上面的系统,Veri ...

随机推荐

  1. 谈谈JVM垃圾回收机制及垃圾回收算法

    一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理.由于有个垃圾回收机制 ...

  2. opencv笔记

    加载图像: OpenCV支持图像格式Windows位图(bmp),便携式图像格式(pbm,pgm,ppm)和Sun光栅(sr,ras). Mat image = imread( imageName, ...

  3. filezilla server FTP 安装报错 "could not load TLS network. Aborting start of administration interface"

    filezilla server FTP 安装报错   "could not load TLS network. Aborting start of administration inter ...

  4. JAVA基础——内存流

    掌握内存操作流 输入和输出都是从文件中来的,当然,也可将输出的位置设置在内存上,这就需要ByteArrayInputStream和ByteArrayOutputStream ByteArrayInpu ...

  5. left_v2.js

    $(document).ready(function(){ $(".mc_left a").each(function(){ var href = $(this).attr(&qu ...

  6. vue+VeeValidate 校验范围(部分校验,全部校验)

    搜索很久,没有发现有关于vue+VeeValidate部分校验的.自己写一个. 主要是两个场景: 1. 校验范围内,所有的字段. 2. 校验全局所有字段.主要方法: 1.validate(fields ...

  7. [Python3网络爬虫开发实战] 6.1-什么是Ajax

    Ajax,全称为Asynchronous JavaScript and XML,即异步的JavaScript和XML.它不是一门编程语言,而是利用JavaScript在保证页面不被刷新.页面链接不改变 ...

  8. python实现tcp文件下载器

    服务器端代码 import socket import os import threading # 处理客户端请求下载文件的操作(从主线程提出来的代码) def deal_client_request ...

  9. ppt_旋转抽奖_制作步骤

    1 ppt制作抽奖转盘 插入饼状图,更改比例,更改颜色(一般选取相邻的一组颜色匹配比较好看): 插入竖文本框,编辑每一个部分为特等奖.一等奖.二等奖.三等奖: 全部选中,ctrl+G组合: 添加陀螺旋 ...

  10. C#上位机开发(四)—— SerialAssistant功能完善

    上一篇中我们完成了一个串口助手的雏形,实现了基本发送和接收字符串功能,并将打开/关闭串口进行了异常处理,这篇就来按照流程,逐步将功能完善: 1.构思功能 首先是接收部分,要添加一个“清空接收”的按钮来 ...