darknet  v3
crop_layer_kernels.cu
Go to the documentation of this file.
1 #include "cuda_runtime.h"
2 #include "curand.h"
3 #include "cublas_v2.h"
4 
5 extern "C" {
6 #include "crop_layer.h"
7 #include "utils.h"
8 #include "cuda.h"
9 #include "image.h"
10 }
11 
12 __device__ float get_pixel_kernel(float *image, int w, int h, int x, int y, int c)
13 {
14  if(x < 0 || x >= w || y < 0 || y >= h) return 0;
15  return image[x + w*(y + c*h)];
16 }
17 
18 __device__ float3 rgb_to_hsv_kernel(float3 rgb)
19 {
20  float r = rgb.x;
21  float g = rgb.y;
22  float b = rgb.z;
23 
24  float h, s, v;
25  float max = (r > g) ? ( (r > b) ? r : b) : ( (g > b) ? g : b);
26  float min = (r < g) ? ( (r < b) ? r : b) : ( (g < b) ? g : b);
27  float delta = max - min;
28  v = max;
29  if(max == 0){
30  s = 0;
31  h = -1;
32  }else{
33  s = delta/max;
34  if(r == max){
35  h = (g - b) / delta;
36  } else if (g == max) {
37  h = 2 + (b - r) / delta;
38  } else {
39  h = 4 + (r - g) / delta;
40  }
41  if (h < 0) h += 6;
42  }
43  return make_float3(h, s, v);
44 }
45 
46 __device__ float3 hsv_to_rgb_kernel(float3 hsv)
47 {
48  float h = hsv.x;
49  float s = hsv.y;
50  float v = hsv.z;
51 
52  float r, g, b;
53  float f, p, q, t;
54 
55  if (s == 0) {
56  r = g = b = v;
57  } else {
58  int index = (int) floorf(h);
59  f = h - index;
60  p = v*(1-s);
61  q = v*(1-s*f);
62  t = v*(1-s*(1-f));
63  if(index == 0){
64  r = v; g = t; b = p;
65  } else if(index == 1){
66  r = q; g = v; b = p;
67  } else if(index == 2){
68  r = p; g = v; b = t;
69  } else if(index == 3){
70  r = p; g = q; b = v;
71  } else if(index == 4){
72  r = t; g = p; b = v;
73  } else {
74  r = v; g = p; b = q;
75  }
76  }
77  r = (r < 0) ? 0 : ((r > 1) ? 1 : r);
78  g = (g < 0) ? 0 : ((g > 1) ? 1 : g);
79  b = (b < 0) ? 0 : ((b > 1) ? 1 : b);
80  return make_float3(r, g, b);
81 }
82 
83 __device__ float bilinear_interpolate_kernel(float *image, int w, int h, float x, float y, int c)
84 {
85  int ix = (int) floorf(x);
86  int iy = (int) floorf(y);
87 
88  float dx = x - ix;
89  float dy = y - iy;
90 
91  float val = (1-dy) * (1-dx) * get_pixel_kernel(image, w, h, ix, iy, c) +
92  dy * (1-dx) * get_pixel_kernel(image, w, h, ix, iy+1, c) +
93  (1-dy) * dx * get_pixel_kernel(image, w, h, ix+1, iy, c) +
94  dy * dx * get_pixel_kernel(image, w, h, ix+1, iy+1, c);
95  return val;
96 }
97 
98 __global__ void levels_image_kernel(float *image, float *rand, int batch, int w, int h, int train, float saturation, float exposure, float translate, float scale, float shift)
99 {
100  int size = batch * w * h;
101  int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
102  if(id >= size) return;
103  int x = id % w;
104  id /= w;
105  int y = id % h;
106  id /= h;
107  float rshift = rand[0];
108  float gshift = rand[1];
109  float bshift = rand[2];
110  float r0 = rand[8*id + 0];
111  float r1 = rand[8*id + 1];
112  float r2 = rand[8*id + 2];
113  float r3 = rand[8*id + 3];
114 
115  saturation = r0*(saturation - 1) + 1;
116  saturation = (r1 > .5f) ? 1.f/saturation : saturation;
117  exposure = r2*(exposure - 1) + 1;
118  exposure = (r3 > .5f) ? 1.f/exposure : exposure;
119 
120  size_t offset = id * h * w * 3;
121  image += offset;
122  float r = image[x + w*(y + h*0)];
123  float g = image[x + w*(y + h*1)];
124  float b = image[x + w*(y + h*2)];
125  float3 rgb = make_float3(r,g,b);
126  if(train){
127  float3 hsv = rgb_to_hsv_kernel(rgb);
128  hsv.y *= saturation;
129  hsv.z *= exposure;
130  rgb = hsv_to_rgb_kernel(hsv);
131  } else {
132  shift = 0;
133  }
134  image[x + w*(y + h*0)] = rgb.x*scale + translate + (rshift - .5f)*shift;
135  image[x + w*(y + h*1)] = rgb.y*scale + translate + (gshift - .5f)*shift;
136  image[x + w*(y + h*2)] = rgb.z*scale + translate + (bshift - .5f)*shift;
137 }
138 
139 __global__ void forward_crop_layer_kernel(float *input, float *rand, int size, int c, int h, int w, int crop_height, int crop_width, int train, int flip, float angle, float *output)
140 {
141  int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
142  if(id >= size) return;
143 
144  float cx = w/2.f;
145  float cy = h/2.f;
146 
147  int count = id;
148  int j = id % crop_width;
149  id /= crop_width;
150  int i = id % crop_height;
151  id /= crop_height;
152  int k = id % c;
153  id /= c;
154  int b = id;
155 
156  float r4 = rand[8*b + 4];
157  float r5 = rand[8*b + 5];
158  float r6 = rand[8*b + 6];
159  float r7 = rand[8*b + 7];
160 
161  float dw = (w - crop_width)*r4;
162  float dh = (h - crop_height)*r5;
163  flip = (flip && (r6 > .5f));
164  angle = 2*angle*r7 - angle;
165  if(!train){
166  dw = (w - crop_width)/2.f;
167  dh = (h - crop_height)/2.f;
168  flip = 0;
169  angle = 0;
170  }
171 
172  input += w*h*c*b;
173 
174  float x = (flip) ? w - dw - j - 1 : j + dw;
175  float y = i + dh;
176 
177  float rx = cosf(angle)*(x-cx) - sinf(angle)*(y-cy) + cx;
178  float ry = sinf(angle)*(x-cx) + cosf(angle)*(y-cy) + cy;
179 
180  output[count] = bilinear_interpolate_kernel(input, w, h, rx, ry, k);
181 }
182 
184 {
185  cuda_random(layer.rand_gpu, layer.batch*8);
186 
187  float radians = layer.angle*3.14159265f/180.f;
188 
189  float scale = 2;
190  float translate = -1;
191  if(layer.noadjust){
192  scale = 1;
193  translate = 0;
194  }
195 
196  int size = layer.batch * layer.w * layer.h;
197 
198  levels_image_kernel<<<cuda_gridsize(size), BLOCK>>>(net.input_gpu, layer.rand_gpu, layer.batch, layer.w, layer.h, net.train, layer.saturation, layer.exposure, translate, scale, layer.shift);
199  check_error(cudaPeekAtLastError());
200 
201  size = layer.batch*layer.c*layer.out_w*layer.out_h;
202 
203  forward_crop_layer_kernel<<<cuda_gridsize(size), BLOCK>>>(net.input_gpu, layer.rand_gpu, size, layer.c, layer.h, layer.w, layer.out_h, layer.out_w, net.train, layer.flip, radians, layer.output_gpu);
204  check_error(cudaPeekAtLastError());
205 
206 /*
207  cuda_pull_array(layer.output_gpu, layer.output, size);
208  image im = float_to_image(layer.crop_width, layer.crop_height, layer.c, layer.output + 0*(size/layer.batch));
209  image im2 = float_to_image(layer.crop_width, layer.crop_height, layer.c, layer.output + 1*(size/layer.batch));
210  image im3 = float_to_image(layer.crop_width, layer.crop_height, layer.c, layer.output + 2*(size/layer.batch));
211 
212  translate_image(im, -translate);
213  scale_image(im, 1/scale);
214  translate_image(im2, -translate);
215  scale_image(im2, 1/scale);
216  translate_image(im3, -translate);
217  scale_image(im3, 1/scale);
218 
219  show_image(im, "cropped");
220  show_image(im2, "cropped2");
221  show_image(im3, "cropped3");
222  cvWaitKey(0);
223  */
224 }
225 
__global__ void levels_image_kernel(float *image, float *rand, int batch, int w, int h, int train, float saturation, float exposure, float translate, float scale, float shift)
int flip
Definition: darknet.h:153
int w
Definition: darknet.h:140
__device__ float get_pixel_kernel(float *image, int w, int h, int x, int y, int c)
void forward_crop_layer_gpu(crop_layer layer, network net)
Definition: darknet.h:512
int out_w
Definition: darknet.h:141
__device__ float3 hsv_to_rgb_kernel(float3 hsv)
float shift
Definition: darknet.h:166
int train
Definition: darknet.h:488
float exposure
Definition: darknet.h:165
int h
Definition: darknet.h:140
int out_h
Definition: darknet.h:141
int noadjust
Definition: darknet.h:178
int batch
Definition: darknet.h:131
__device__ float bilinear_interpolate_kernel(float *image, int w, int h, float x, float y, int c)
float angle
Definition: darknet.h:162
int c
Definition: darknet.h:140
float saturation
Definition: darknet.h:164
__global__ void forward_crop_layer_kernel(float *input, float *rand, int size, int c, int h, int w, int crop_height, int crop_width, int train, int flip, float angle, float *output)
__device__ float3 rgb_to_hsv_kernel(float3 rgb)
Definition: darknet.h:119