前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cuda纹理内存的使用

cuda纹理内存的使用

作者头像
一棹烟波
发布2018-01-12 16:46:28
2.1K0
发布2018-01-12 16:46:28
举报
文章被收录于专栏:一棹烟波一棹烟波

CUDA纹理内存的访问速度比全局内存要快,因此处理图像数据时,使用纹理内存是一个提升性能的好方法。

贴一段自己写的简单的实现两幅图像加权和的代码,使用纹理内存实现。

输入:两幅图 lena, moon

输出:两幅图像加权和

代码语言:javascript
复制
 1 #include <opencv2\opencv.hpp> 
 2 #include <iostream>
 3 #include <string>
 4 #include <cuda.h>
 5 #include <cuda_runtime.h>
 6 #include <device_launch_parameters.h>
 7 
 8 using namespace std;
 9 using namespace cv;
10 
11 //声明CUDA纹理
12 texture <uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> refTex1;
13 texture <uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> refTex2;
14 //声明CUDA数组
15 cudaArray* cuArray1;
16 cudaArray* cuArray2;
17 //通道数
18 cudaChannelFormatDesc cuDesc = cudaCreateChannelDesc<uchar4>();
19 
20 
21 __global__ void weightAddKerkel(uchar *pDstImgData, int imgHeight, int imgWidth,int channels)
22 {
23     const int tidx=blockDim.x*blockIdx.x+threadIdx.x;
24     const int tidy=blockDim.y*blockIdx.y+threadIdx.y;
25 
26     if (tidx<imgWidth && tidy<imgHeight)
27     {
28         float4 lenaBGR,moonBGR;
29         //使用tex2D函数采样纹理
30         lenaBGR=tex2D(refTex1, tidx, tidy);
31         moonBGR=tex2D(refTex2, tidx, tidy);
32 
33         int idx=(tidy*imgWidth+tidx)*channels;
34         float alpha=0.5;
35         pDstImgData[idx+0]=(alpha*lenaBGR.x+(1-alpha)*moonBGR.x)*255;
36         pDstImgData[idx+1]=(alpha*lenaBGR.y+(1-alpha)*moonBGR.y)*255;
37         pDstImgData[idx+2]=(alpha*lenaBGR.z+(1-alpha)*moonBGR.z)*255;
38         pDstImgData[idx+3]=0;
39     }
40 }
41 
42 void main()
43 {
44     Mat Lena=imread("data/lena.jpg");
45     Mat moon=imread("data/moon.jpg");
46     cvtColor(Lena, Lena, CV_BGR2BGRA);
47     cvtColor(moon, moon, CV_BGR2BGRA);
48     int imgWidth=Lena.cols;
49     int imgHeight=Lena.rows;
50     int channels=Lena.channels();
51 
52     //设置纹理属性
53     cudaError_t t;
54     refTex1.addressMode[0] = cudaAddressModeClamp;
55     refTex1.addressMode[1] = cudaAddressModeClamp;
56     refTex1.normalized = false;
57     refTex1.filterMode = cudaFilterModeLinear;
58     //绑定cuArray到纹理
59     cudaMallocArray(&cuArray1, &cuDesc, imgWidth, imgHeight);
60     t = cudaBindTextureToArray(refTex1, cuArray1);
61 
62     refTex2.addressMode[0] = cudaAddressModeClamp;
63     refTex2.addressMode[1] = cudaAddressModeClamp;
64     refTex2.normalized = false;
65     refTex2.filterMode = cudaFilterModeLinear;
66      cudaMallocArray(&cuArray2, &cuDesc, imgWidth, imgHeight);
67     t = cudaBindTextureToArray(refTex2, cuArray2);
68 
69     //拷贝数据到cudaArray
70     t=cudaMemcpyToArray(cuArray1, 0,0, Lena.data, imgWidth*imgHeight*sizeof(uchar)*channels, cudaMemcpyHostToDevice);
71     t=cudaMemcpyToArray(cuArray2, 0,0, moon.data, imgWidth*imgHeight*sizeof(uchar)*channels, cudaMemcpyHostToDevice);
72 
73     //输出图像
74     Mat dstImg=Mat::zeros(imgHeight, imgWidth, CV_8UC4);
75     uchar *pDstImgData=NULL;
76     t=cudaMalloc(&pDstImgData, imgHeight*imgWidth*sizeof(uchar)*channels);
77 
78     //核函数,实现两幅图像加权和
79     dim3 block(8,8);
80     dim3 grid( (imgWidth+block.x-1)/block.x, (imgHeight+block.y-1)/block.y );
81     weightAddKerkel<<<grid, block, 0>>>(pDstImgData, imgHeight, imgWidth, channels);
82     cudaThreadSynchronize();
83 
84     //从GPU拷贝输出数据到CPU
85     t=cudaMemcpy(dstImg.data, pDstImgData, imgWidth*imgHeight*sizeof(uchar)*channels, cudaMemcpyDeviceToHost);
86 
87     //显示
88     namedWindow("show");
89     imshow("show", dstImg);
90     waitKey(0);
91 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-11-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档