-
Notifications
You must be signed in to change notification settings - Fork 0
/
imageDenoising.cu
129 lines (102 loc) · 3.61 KB
/
imageDenoising.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* Copyright 1993-2015 NVIDIA Corporation. All rights reserved.
*
* Please refer to the NVIDIA end user license agreement (EULA) associated
* with this source code for terms and conditions that govern your use of
* this software. Any use, reproduction, disclosure, or distribution of
* this software and related documentation outside the terms of the EULA
* is strictly prohibited.
*
*/
/*
* This sample demonstrates two adaptive image denoising techniques:
* KNN and NLM, based on computation of both geometric and color distance
* between texels. While both techniques are already implemented in the
* DirectX SDK using shaders, massively speeded up variation
* of the latter technique, taking advantage of shared memory, is implemented
* in addition to DirectX counterparts.
* See supplied whitepaper for more explanations.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <helper_cuda.h>
#include "imageDenoising.h"
////////////////////////////////////////////////////////////////////////////////
// Helper functions
////////////////////////////////////////////////////////////////////////////////
float Max(float x, float y)
{
return (x > y) ? x : y;
}
float Min(float x, float y)
{
return (x < y) ? x : y;
}
int iDivUp(int a, int b)
{
return ((a % b) != 0) ? (a / b + 1) : (a / b);
}
__device__ float lerpf(float a, float b, float c)
{
return a + (b - a) * c;
}
__device__ float vecLen(float4 a, float4 b)
{
return (
(b.x - a.x) * (b.x - a.x) +
(b.y - a.y) * (b.y - a.y) +
(b.z - a.z) * (b.z - a.z)
);
}
__device__ TColor make_color(float r, float g, float b, float a)
{
return
((int)(a * 255.0f) << 24) |
((int)(b * 255.0f) << 16) |
((int)(g * 255.0f) << 8) |
((int)(r * 255.0f) << 0);
}
////////////////////////////////////////////////////////////////////////////////
// Global data handlers and parameters
////////////////////////////////////////////////////////////////////////////////
//Texture object and channel descriptor for image texture
cudaTextureObject_t texImage;
cudaChannelFormatDesc uchar4tex = cudaCreateChannelDesc<uchar4>();
//CUDA array descriptor
cudaArray *a_Src;
////////////////////////////////////////////////////////////////////////////////
// Filtering kernels
////////////////////////////////////////////////////////////////////////////////
#include "imageDenoising_copy_kernel.cuh"
#include "imageDenoising_knn_kernel.cuh"
#include "imageDenoising_nlm_kernel.cuh"
#include "imageDenoising_nlm2_kernel.cuh"
extern "C"
cudaError_t CUDA_MallocArray(uchar4 **h_Src, int imageW, int imageH)
{
cudaError_t error;
error = cudaMallocArray(&a_Src, &uchar4tex, imageW, imageH);
error = cudaMemcpyToArray(a_Src, 0, 0,
*h_Src, imageW * imageH * sizeof(uchar4),
cudaMemcpyHostToDevice
);
cudaResourceDesc texRes;
memset(&texRes,0,sizeof(cudaResourceDesc));
texRes.resType = cudaResourceTypeArray;
texRes.res.array.array = a_Src;
cudaTextureDesc texDescr;
memset(&texDescr,0,sizeof(cudaTextureDesc));
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModeLinear;
texDescr.addressMode[0] = cudaAddressModeWrap;
texDescr.addressMode[1] = cudaAddressModeWrap;
texDescr.readMode = cudaReadModeNormalizedFloat;
checkCudaErrors(cudaCreateTextureObject(&texImage, &texRes, &texDescr, NULL));
return error;
}
extern "C"
cudaError_t CUDA_FreeArray()
{
return cudaFreeArray(a_Src);
}