Vexcl方便的opencl c++库

Vexcl是c++版的opencl,他实现减少opencl的代码量,并且能打印内核内的信息,所以很方便,在github上就可以找到,下面是本人对vexcl的一个应用。

提取将原图像通过opencl变为灰度图像,希望能对需要的对有一点帮助
1.需要github上下载vexcl直接cmake编译安装
2.下载opencv sdk
3.配置好环境
4.完成

本文不能直接运行,部分头文件是测试用的,需要删除,部分函数未删,下次时间充足在补上

#include <iostream>
#include <stdexcept>
#include <vexcl/vexcl.hpp>
#include <opencv2/opencv.hpp>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include "ComputeTime.h"
#include "Init_CLBuffer.h"
#include "Dump.h"
//生成高斯核
#define ENumber 2.71828183f
#define PI 3.1415926f
int makeGaussianData(float ** data, int width, int height, float filterRatio) {
	int i, j;
	float sum = 0.0f;
	*data = (float*)malloc(sizeof(float) * width * height);
	for (i = 0; i < height; i++) {
		for (j = 0; j < width; j++) {
			float temp = 0.0f;
			temp = -1.0f * ((j - width / 2) * (j - width / 2) + (i - height / 2) * (i - height / 2)) / (2.0f * filterRatio * filterRatio);
			temp = powf(ENumber, temp);
			(*data)[i * width + j] = (1.0f / (2.0f * PI * filterRatio * filterRatio)) * temp;
			sum += (*data)[i * width + j];
		}
	}
	printf("sum = %f\n", sum);
	for (i = 0; i < height; i++) {
		for (j = 0; j < width; j++) {
			(*data)[i * width + j] = (*data)[i * width + j] / sum;
		}
	}
	return 0;
}
int main()
{
	cv::Mat image;
	std::string imageName = "./image/input.jpg";
	image = cv::imread(imageName, cv::IMREAD_COLOR); // Read the file
	if (!image.data) // Check for invalid input
	{
		std::cout << "Could not open or find the image" << std::endl;
		return false;
	}
	cv::cvtColor( image, image, CV_RGB2RGBA );
	int width = image.cols;
	int height = image.rows;
	int channel = image.channels();
	uchar* mData = image.data;//input buffer data
	uchar* nData = (uchar*)malloc(image.rows * image.cols * channel * sizeof(uchar));//output buffer data
	std::cout << image.rows << " " << image.cols << " " << image.channels() << " " << sizeof(uchar) << std::endl;
	std::cout << image.step << std::endl;
	vex::Context ctx(vex::Filter::Type(CL_DEVICE_TYPE_GPU) && vex::Filter::Count(1));
	std::cout << ctx << std::endl;
	std::vector<vex::backend::kernel> kernel;
	dump("srcimage.txt", (char *)mData, width * height * image.channels() * sizeof(uchar));
	// Compile and store the kernels for later use.
	// Create an OpenCL Image / texture and transfer data to the device
	cl::Buffer srcImage;
	try {
		 srcImage = cl::Buffer(ctx.context(0), CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * image.cols * image.channels() * image.rows, (void*)mData );
	}
	catch (const cl::Error &err) {
		std::cerr << "OpenCL error: " << err << std::endl;
	}
	catch (const std::exception &err) {
		std::cerr << "Error: " << err.what() << std::endl;
	}
	// Create a buffer for the result
	cl::Buffer clResult = cl::Buffer(ctx.context(0), CL_MEM_WRITE_ONLY, sizeof(float)* image.cols *  image.rows * channel);
	// Create Gaussian mask
	float *GaussData = NULL;
	int GaussWidth = 5;
	makeGaussianData(&GaussData, 5, 5, 0.8f);
	InitCLBuffer init;
	// Create buffer for mask and transfer it to the device
	cl::Buffer clGaussData = cl::Buffer(ctx.context(0), CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 5 * 5 * sizeof(float), (void *)GaussData);
	ComputeTime ct_init;//calculate timer
	ct_init.Begin();
	for (uint d = 0; d < ctx.size(); d++)
	{
		kernel.emplace_back(ctx.queue(d),
			VEX_STRINGIZE_SOURCE(
			kernel void getBinPerPixel(
				__global uchar4 * in,
				__global float * binPerPixelImg,
				int width)
			{
			int idx = get_global_id(0);
			int idy = get_global_id(1);
			uchar4 src = in[idy * width + idx];
			binPerPixelImg[idy * width + idx] = (float)(0.2989f*(src.x) + 0.5870f*(src.y) + 0.1140f*(src.z));
			}), "getBinPerPixel");
			
	}
	std::cout << "time:  " << ct_init.End() << "ms" << std::endl;
	// Apply the kernels to the vector partitions on each device.
	for (uint d = 0; d < ctx.size(); d++)
	{
		try {
			kernel[d].push_arg(srcImage);
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error11: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error11: " << err.what() << std::endl;
		}
		try {
			kernel[d].push_arg(clResult);
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error22: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error22: " << err.what() << std::endl;
		}
	
		try {
			kernel[d].push_arg(width);
	//		kernel[d].push_arg(height);
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error33: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error33: " << err.what() << std::endl;
		}
		try {
		//	kernel[d].push_arg(width);
		//	kernel[d].push_arg(height);
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error44: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error44: " << err.what() << std::endl;
		}
		float sinx = sin(30.0f * PI / 180.0f);
		float cosx = cos(30.0f * PI / 180.0f);
		try {
		//	kernel[d].push_arg(sinx);
		//	kernel[d].push_arg(cosx);
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error55: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error55: " << err.what() << std::endl;
		}
		try {
			kernel[d].config(vex::backend::ndrange(width, height), vex::backend::ndrange(1, 1));
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error1: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error1: " << err.what() << std::endl;
		}
		try {
			kernel[d](ctx.queue(d));
		}
		catch (const cl::Error &err) {
			std::cerr << "OpenCL error2: " << err << std::endl;
		}
		catch (const std::exception &err) {
			std::cerr << "Error2: " << err.what() << std::endl;
		}
	}
	
	ctx.queue(0).enqueueReadBuffer(clResult, CL_TRUE, 0, sizeof(uchar)* image.cols * channel * image.rows, (void*)nData);
	dump("p_image.txt", (char *)nData, width * height * channel * sizeof(float));
	ctx.queue(0).flush();
	ctx.queue(0).finish();
	cv::Mat outputImage(image.rows, image.cols, CV_8UC3, (void*)nData);
	if (!outputImage.data) // Check for invalid input
	{
		std::cout << "Could not open or find the image" << std::endl;
		return false;
	}
	
	cv::namedWindow("Input image window", cv::WINDOW_AUTOSIZE); // Create a window for display.
	cv::imshow("Input image window", image); // Show our image inside it.
	
	cv::namedWindow("Output image window", cv::WINDOW_AUTOSIZE); // Create a window for display.
	cv::imshow("Output image window", outputImage); // Show our image inside it.
	cv::waitKey(0); // Wait for a keystroke in the window
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值