opencv+cuda实现彩色图转灰度图或二值化

来源:互联网 发布:2016年有哪些网络剧 编辑:程序博客网 时间:2024/05/16 00:30
**main.cpp**//******************************//Created on 2016-07-02//@author : baicai//@email : wnw@bupt.edu.cn//@OpenCV3.0 + Cuda7.5//******************************#include "opencv2/core/utility.hpp"#include "opencv2/video/tracking.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/videoio.hpp"#include "opencv2/highgui.hpp"#include "opencv2/opencv.hpp"#include "opencv2/core/core.hpp"#include <iostream>#include <ctype.h>#define WINDOW_NAME "[输出图像]"using namespace cv;using namespace std;extern "C" void Cuda_Threshold(unsigned char*indata_h, unsigned char*outdata_h, int w, int h,int THRESHOLD);//CUDA接口函数int ThresholdValue = 100;Mat srcImage;Mat dstImage(960, 1280, CV_8UC1);//输出图像1280*960,位深8bit,单通道unsigned char*outdata_h = NULL;int w, h;int framesize, framesizeout;void on_Threshold(int, void*);//回调函数int main(){    srcImage = imread("hand.jpg");//输入图像    imshow("输入图像", srcImage);    w = srcImage.cols;    h = srcImage.rows;    framesize = sizeof(char)*w*h * 3;    framesizeout = sizeof(char)*w*h;    outdata_h = (unsigned char*)malloc(framesizeout);//为主机端输出数据开辟内存    namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);    //创建阈值滑动条,可通过调节阈值来改变二值化的结果    createTrackbar("阈值", WINDOW_NAME, &ThresholdValue, 255, on_Threshold);    on_Threshold(0, 0);    while (1)    {        int key;        key = waitKey(20);        if ((char)key ==13)//按下Enter保存输出图像            imwrite("output.jpg", dstImage);        if ((char)key == 27)//按下Esc退出            break;    }}void on_Threshold(int, void *){    Cuda_Threshold(srcImage.data, outdata_h, w, h, ThresholdValue);    memcpy(dstImage.data, outdata_h, framesizeout);    imshow(WINDOW_NAME, dstImage);}
**kernel.cu**//**************************************************************//该核函数可以实现输入图转灰度图,也可以实现输入图转二值图//**************************************************************#include <cuda.h>#include "cuda_runtime.h"#include <cuda_runtime_api.h>#include "device_functions.h"#include <helper_cuda.h>#include <helper_math.h>#include <helper_functions.h>#include "device_launch_parameters.h"int iDivUp(int a, int b){    return ((a % b) != 0) ? (a / b + 1) : (a / b);}__global__ void threshold(unsigned char*indata, unsigned char*outdata, int w, int h,int THRESHOLD){    int x = blockDim.x*blockIdx.x + threadIdx.x;    int y = blockDim.y*blockIdx.y + threadIdx.y;    if (x < w&&y < h)    {        int coordinator = y*w*3 + x*3;        int coordinator_out = y*w + x;        //用opencv读入的图,子像素排列顺序是BGR的        int b = indata[coordinator];        int g = indata[coordinator + 1];        int r = indata[coordinator + 2];        int gray = (r * 30 + g * 59 + b * 11 + 50) / 100;//计算灰度值        {   //输出二值图            if (gray < THRESHOLD)                outdata[coordinator_out] = 255;            else                outdata[coordinator_out] = 0;           }        //outdata[coordinator_out] = gray;//直接输出灰度图    }}extern "C" void Cuda_Threshold(unsigned char*indata_h, unsigned char*outdata_h, int w, int h,int THRESHOLD){    int framesize = sizeof(char)*w*h * 3;    int framesizeout = sizeof(char)*w*h;    unsigned char*indata_d;    checkCudaErrors(cudaMalloc((void **)&indata_d, framesize));//为设备端输入数据开辟内存    unsigned char*outdata_d;    checkCudaErrors(cudaMalloc((void **)&outdata_d, framesizeout));//为设备端输出数据开辟内存    dim3 block(16, 16, 1);    dim3 grid(iDivUp(w, block.x), iDivUp(h, block.y), 1);//设置网格    checkCudaErrors(cudaMemcpy(indata_d, indata_h, framesize, cudaMemcpyHostToDevice));//把输入数据从主机端拷贝到设备端    threshold << <grid, block >> >(indata_d, outdata_d, w, h,THRESHOLD);//调用核函数    checkCudaErrors(cudaMemcpy(outdata_h, outdata_d, framesizeout, cudaMemcpyDeviceToHost));//把输出结果从设备端拷贝到主机端}

输入图像
输入RGB图像

输出图像
输出二值图

输出灰度图

0 0
原创粉丝点击