-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDataTerm.cpp
More file actions
165 lines (140 loc) · 5.1 KB
/
Copy pathDataTerm.cpp
File metadata and controls
165 lines (140 loc) · 5.1 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*! @file DataTerm.cpp
* Functions for Data Term calculation and Image highlighting.
*/
#define N_PDF 256 //!>Size of colorspace used for class membership probability density. The used colorspace is 256*256*256
#define DEFAULT_SIGMA 5 //!>default std deviation value for gaussian envelope
#include "DataTerm.h"
#include "DataTermKernels.cu"
int* DataTerm::getPos()
{
/*!
* Returns device pointer for positive data points. Used inside graph cuts initialization.
*/
return d_pos;
}
int* DataTerm::getNeg()
{
/*!
* Returns device pointer for negative data points. Used inside graph cuts initialization.
*/
return d_neg;
}
void DataTerm::init_data_term(int w, int h)
{
/*!
* Inits all datastructure needed for calculation, tell the size of the processed image and the resolution of the pdf.
*/
width = w;
height = h;
threadsPerBlock3d.x = 8;
threadsPerBlock3d.y = 8;
threadsPerBlock3d.z = 8;
numBlocks_3d.x = N_PDF / threadsPerBlock3d.x;
numBlocks_3d.y = N_PDF / threadsPerBlock3d.y;
numBlocks_3d.z = N_PDF / threadsPerBlock3d.z;
threadsPerBlock.x = 16;
threadsPerBlock.y = 16;
threadsPerBlock.z = 1;
// one thread for a pixel (with 3 ch)
numBlocks_img.x = width / threadsPerBlock.x;
numBlocks_img.y = height / threadsPerBlock.y;
numBlocks_img.z = 1;
numBlocks_lin.x = 256*3 / threadsPerBlock.x;
numBlocks_lin.y = 1;
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_img), sizeof(unsigned char)*3*width*height));
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_gaussian), sizeof(float)*N_PDF));
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_pdf), sizeof(float)*N_PDF*N_PDF*N_PDF));
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_selection_map), sizeof(unsigned char)*width*height));
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_pos), sizeof(int)*width*height));
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_neg), sizeof(int)*width*height));
K_InitGaussian<<<numBlocks_lin, threadsPerBlock>>>(DEFAULT_SIGMA, d_gaussian);
reset();
}
void DataTerm::free_data_term()
{
/*!
* free device memory
*/
//CUDA_SAFE_CALL(cudaFree(d_pos));
//CUDA_SAFE_CALL(cudaFree(d_neg));
CUDA_SAFE_CALL(cudaFree(d_img));
CUDA_SAFE_CALL(cudaFree(d_pdf));
CUDA_SAFE_CALL(cudaFree(d_selection_map));
CUDA_SAFE_CALL(cudaFree(d_gaussian));
}
void DataTerm::setImage (unsigned char* h_img)
{
/*!
* Load image data to device.
*/
CUDA_SAFE_CALL(cudaMemcpy(d_img, h_img, sizeof(unsigned char)*3*width*height, cudaMemcpyHostToDevice));
}
void DataTerm::reset()
{
/*!
* Set selection map and pdf to 0.
*/
K_InitSelectionMap<<<numBlocks_img, threadsPerBlock>>>(d_selection_map, width);
K_InitColorSpace<<<numBlocks_3d, threadsPerBlock3d>>>(d_pdf, N_PDF);
}
void DataTerm::setSigmaGaussian(int sigma)
{
/*!
* Calculate gaussian array with given variance.
*/
K_InitGaussian<<<numBlocks_lin, threadsPerBlock>>>(sigma, d_gaussian);
}
void DataTerm::selectOnMap(int x, int y, int sigma)
{
/*!
* Select data points from image. For each point add a gaussian kernel, with variance set in setSigmaGaussian, to the pdf.
* Each datapoint is processed iterative. The update of the density estimation is run parallel.
*/
int x1, y1;
// select square around x,y with fixed sides
int size = 5;
for (int i=0;i<size; i++)
{
for (int j=0; j<size; j++)
{
x1 = x+i;
y1 = y+j;
K_SelectAndGauss<<<numBlocks_3d, threadsPerBlock3d>>>(d_selection_map, d_img, d_pdf, d_gaussian, x1, y1, 8, width);
}
}
float pdf[512];
CUDA_SAFE_CALL(cudaMemcpy(&pdf[0], d_pdf, sizeof(float)*512, cudaMemcpyDeviceToHost));
}
void DataTerm::getDataTermsMixture()
{
/*!
* Use the calculated pdf to calculate the data terms for a given image (set by setImage). To a pixel (x,y) corresponds the
* color vector c=(b(x,y), g(x,y), r(x,y)). The probability for the pixel belonging to the selected class is then pdf(c).
* Positive data term is p, negative is 1-p. Both are stored in d_pos and d_neg.
*/
K_CalcTerms<<<numBlocks_img, threadsPerBlock>>>(d_img, d_pdf, d_pos, d_neg, width);
}
void DataTerm::setSelection(int* h_select)
{
/*!
* Set selection map on device.
* @param[in] h_select Selection / labeling matrix.
*/
int* d_select;
CUDA_SAFE_CALL(cudaMalloc((void**)&(d_select), sizeof(int)*width*height));
CUDA_SAFE_CALL(cudaMemcpy(d_select, h_select, sizeof(int)*width*height, cudaMemcpyHostToDevice));
K_InitSelectionMap<<<numBlocks_img, threadsPerBlock>>>(d_selection_map, width);
K_SetMap<<<numBlocks_img, threadsPerBlock>>>(d_selection_map, d_select, width);
CUDA_SAFE_CALL(cudaFree(d_select));
}
void DataTerm::drawSelection(uchar* h_inp, uchar* h_out)
{
/*
* Highlight all pixels in input image data that correspond to a 1-entry in selection map.
* @param[in] h_inp Input image rawdata
* @param[out] h_out processed image data
*/
CUDA_SAFE_CALL(cudaMemcpy(d_img, h_inp, sizeof(unsigned char)*3*width*height, cudaMemcpyHostToDevice));
K_DrawMap<<<numBlocks_img, threadsPerBlock>>>(d_selection_map, d_img, width);
CUDA_SAFE_CALL(cudaMemcpy(h_out, d_img, sizeof(unsigned char)*3*width*height, cudaMemcpyDeviceToHost));
}