使用cuda将RGB转换GREY

#include "device_functions.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "stdlib.h"
#include <string>
#include <cassert>
#include <iostream>
using namespace std;
#include <opencv2\opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;


//求解公式:   .299f*R+.587f*G+.114*B
cv::Mat imageRGBA;
cv::Mat imageGrey;

//返回RGBA照片的行数
size_t numRows()
{
	return imageRGBA.rows;
}
//返回照片的列数
size_t numCols()
{
	return imageRGBA.cols;
}

void preProcess(uchar4 **inputImage, unsigned char **greyImage, uchar4 **d_rgbaImage, unsigned char **d_greyImage, const string &filename)
{
	//Mat对象
	cv::Mat image;
	//读取image
	image = cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR);
	if (image.empty())
	{
		cerr << "读取照片失败:" << filename << endl;
		exit(1);
	}

	//将BGR转换成RGB
	cv::cvtColor(image, imageRGBA, CV_BGR2RGBA);
	//构造一个和RGB一样大的灰度照片
	imageGrey.create(image.rows, image.cols, CV_8UC1);
	if (!imageRGBA.isContinuous() || !imageGrey.isContinuous())
	{
		cerr << "空间不连续" << endl;
		exit(1);
	}
	//将imageRGBA的地址传出去目的是将Mat转换成数组
	*inputImage = (uchar4*)imageRGBA.ptr<unsigned char>(0);
	*greyImage = imageGrey.ptr<unsigned char>(0);
	//记录照片的大小
	const size_t numPixels = numCols()*numRows();

	//在Device 上开辟内存
	cudaMalloc(d_rgbaImage, sizeof(uchar4)*numPixels);
	cudaMalloc(d_greyImage, sizeof(unsigned char)*numPixels);
	//将d_greyImage全都初始化成0
	cudaMemset(*d_greyImage, 0, numPixels * sizeof(unsigned char));

	//为d_rgbaImage赋值
	cudaMemcpy(*d_rgbaImage, *inputImage, sizeof(uchar4)*numPixels, cudaMemcpyHostToDevice);
}

__global__ void rgba_to_greyscale(uchar4* const rgbaImage, unsigned char *const greyImage, int numRows, int numCols)
{
	//获取每个线程的ID方法一
	//const int idx = blockIdx.x*blockDim.x + threadIdx.x;
	//const int idy = blockIdx.y*blockDim.y + threadIdx.y;
	//const int id = idx * numCols + idy;
	//方法二
	const int id = blockIdx.x*blockDim.x*blockDim.y + threadIdx.y*blockDim.x + threadIdx.x;
	
	if (id < numRows*numCols)
	{
		const unsigned char R = rgbaImage[id].x;
		const unsigned char G = rgbaImage[id].y;
		const unsigned char B = rgbaImage[id].z;
		greyImage[id] = .299f*R + .587f*G + .114*B;
	}
}

//保存照片
void postProcess(string &outPut_file, unsigned char *greyImage)
{
	//将数组转换成Mat
	cv::Mat outImage(numRows(), numCols(), CV_8UC1,(void*)greyImage);
	cv::imwrite(outPut_file.c_str(), outImage);
	//显示处理好的照片
	imshow("sucessed", outImage);
	waitKey(0);
}

int main(string *input)
{
	string input_file = "E:\\ZC\\procedure\\CUDA\\Images\\1.png";//这个地方写你自己照片的的路径
	string output_file = "E:\\ZC\\procedure\\CUDA\\Images\\2.png";//你要保存的路径
	uchar4* h_rgbaImage, *d_rgbaImage;
	unsigned char *h_greyImage, *d_greyImage;
	preProcess(&h_rgbaImage, &h_greyImage, &d_rgbaImage, &d_greyImage, input_file);
	const int thread = 16;
	const int grid = (numRows()*numCols() + thread - 1) / (thread*thread);
	const dim3 blockSize(thread, thread);
	const dim3 gridSize(grid);
	rgba_to_greyscale << <gridSize, blockSize >> > (d_rgbaImage, d_greyImage, numRows(), numCols());

	//等待线程全部结束
	cudaDeviceSynchronize();

	//将结果传回Host上
	cudaMemcpy(h_greyImage, d_greyImage, sizeof(unsigned char)*numRows()*numCols(), cudaMemcpyDeviceToHost);

	postProcess(output_file, h_greyImage);
	//cleanup();
	cudaFree(d_rgbaImage);
	cudaFree(d_rgbaImage);
}

处理前:在这里插入图片描述
处理后:在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值