Properly implement gaussian blur kernel

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-06-08 23:56:47 +01:00
parent fa8faaf91d
commit 2239181551
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47

View File

@ -280,15 +280,16 @@ default_backend_render_shadow(backend_t *backend_data, int width, int height,
return ret; return ret;
} }
static struct conv ** static struct conv **generate_box_blur_kernel(int blur_size) {
generate_box_blur_kernel(int blur_size) {
int r = blur_size * 2 + 1; int r = blur_size * 2 + 1;
assert(r > 0); assert(r > 0);
auto ret = ccalloc(3, struct conv *); auto ret = ccalloc(3, struct conv *);
ret[0] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r); ret[0] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r);
ret[1] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r); ret[1] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r);
ret[0]->w = r; ret[0]->h = 1; ret[0]->w = r;
ret[1]->w = 1; ret[1]->h = r; ret[0]->h = 1;
ret[1]->w = 1;
ret[1]->h = r;
for (int i = 0; i < r; i++) { for (int i = 0; i < r; i++) {
ret[0]->data[i] = 1; ret[0]->data[i] = 1;
ret[1]->data[i] = 1; ret[1]->data[i] = 1;
@ -296,18 +297,22 @@ generate_box_blur_kernel(int blur_size) {
return ret; return ret;
} }
static struct conv ** static struct conv **generate_gaussian_blur_kernel(int blur_size, double blur_deviation) {
generate_gaussian_blur_kernel(int blur_size, double blur_deviation) {
int r = blur_size * 2 + 1; int r = blur_size * 2 + 1;
assert(r > 0); assert(r > 0);
auto ret = ccalloc(3, struct conv *); auto ret = ccalloc(3, struct conv *);
ret[0] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r); ret[0] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r);
ret[1] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r); ret[1] = cvalloc(sizeof(struct conv) + sizeof(double) * (size_t)r);
ret[0]->w = r; ret[0]->h = 1; ret[0]->w = r;
ret[1]->w = 1; ret[1]->h = r; ret[0]->h = 1;
for (int i = 0; i < r; i++) { ret[1]->w = 1;
ret[0]->data[i] = 1; ret[1]->h = r;
ret[1]->data[i] = 1; for (int i = 0; i < blur_size; i++) {
ret[0]->data[i] = ret[0]->data[r - i - 1] =
1.0 / (sqrt(2.0 * M_PI) * blur_deviation) *
exp(-(blur_size - i) * (blur_size - i) /
(2 * blur_deviation * blur_deviation));
ret[1]->data[i] = ret[1]->data[r - i - 1] = ret[0]->data[0];
} }
return ret; return ret;
} }
@ -318,12 +323,10 @@ struct conv **
generate_blur_kernel(enum blur_method method, int blur_size, double blur_deviation) { generate_blur_kernel(enum blur_method method, int blur_size, double blur_deviation) {
assert(blur_size >= 0); assert(blur_size >= 0);
switch (method) { switch (method) {
case BLUR_METHOD_BOX: case BLUR_METHOD_BOX: return generate_box_blur_kernel(blur_size);
return generate_box_blur_kernel(blur_size);
case BLUR_METHOD_GAUSSIAN: case BLUR_METHOD_GAUSSIAN:
return generate_gaussian_blur_kernel(blur_size, blur_deviation); return generate_gaussian_blur_kernel(blur_size, blur_deviation);
default: default: break;
break;
} }
return NULL; return NULL;
} }