This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via d2feca863b6d28d6b7a494ce16621c434d53aa41 (commit) via f5eccc5a040a1f2423a399d3bc8ee0161899f2bc (commit) via d72f3d729af93136c09cc881ede6449826c87889 (commit) via 7de86b4f90000c336361314916ba2b1bc631bba5 (commit) from 18ebb6623592780a57e7eea4f2e646c9a4c8dd99 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/d2feca863b6d28d6b7a494ce16621c434d53a...
commit d2feca863b6d28d6b7a494ce16621c434d53aa41 Author: Cyril Hrubis metan@ucw.cz Date: Fri Jul 27 19:25:02 2012 +0200
demos: grinder: Fix the wrong invalid output error.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index ec1f812..fbf0e21 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -654,6 +654,8 @@ static GP_RetCode sigma_mean(GP_Context **c, const char *params) if (rad_x < 0 || rad_y < 0) return GP_EINVAL;
+ (*c)->gamma = GP_GammaAcquire((*c)->pixel_type, 1.2); + GP_Context *ret = GP_FilterSigmaAlloc(*c, rad_x, rad_y, min, sigma, progress_callback);
if (ret == NULL) @@ -946,9 +948,10 @@ static void check_fmt(const char *fmt)
for (i = 0; out_fmts[i] != NULL; i++) if (!strcmp(out_fmts[i], fmt)) - break; + return;
fprintf(stderr, "Invalid output format '%s'n", fmt); + exit(1); }
static void save_by_fmt(struct GP_Context *bitmap, const char *name, const char *fmt)
http://repo.or.cz/w/gfxprim.git/commit/f5eccc5a040a1f2423a399d3bc8ee0161899f...
commit f5eccc5a040a1f2423a399d3bc8ee0161899f2bc Author: Cyril Hrubis metan@ucw.cz Date: Fri Jul 27 18:52:41 2012 +0200
pywrap: Update filters pywrap.i
diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i index caecd35..d2d9618 100644 --- a/pylib/gfxprim/filters/filters.i +++ b/pylib/gfxprim/filters/filters.i @@ -60,3 +60,7 @@ %newobject GP_FilterMedianAlloc; %newobject GP_FilterMedianExAlloc; %include "GP_Median.h" + +%newobject GP_FilterSigmaAlloc; +%newobject GP_FilterSigmaExAlloc; +%include "GP_Sigma.h"
http://repo.or.cz/w/gfxprim.git/commit/d72f3d729af93136c09cc881ede6449826c87...
commit d72f3d729af93136c09cc881ede6449826c87889 Author: Cyril Hrubis metan@ucw.cz Date: Fri Jul 27 18:51:23 2012 +0200
demos: grinder: Add more filters.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index f001ff6..ec1f812 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -47,13 +47,13 @@ static int param_err(const struct param *self, const char *val, void *priv) { /* invalid parameter name */ if (self == NULL) { - fprintf(stderr, "ERROR: %s: invalid parameter '%s'n", + fprintf(stderr, "ERROR: %s: Unknown parameter name '%s'n", (char*)priv, val); return 1; } /* just regular error */ - fprintf(stderr, "ERROR: %s: invalid %s parameter %s = '%s'", + fprintf(stderr, "ERROR: %s: Invalid %s parameter value %s = '%s'", (char *)priv, param_type_name(self->type), self->name, val); if (self->type == PARAM_ENUM) { @@ -626,6 +626,69 @@ static GP_RetCode median(GP_Context **c, const char *params) return GP_ESUCCESS; }
+/* sigma mean filter */ + +static struct param sigma_mean_params[] = { + {"radius", PARAM_INT, "median radius for both x and y", NULL, NULL}, + {"min", PARAM_INT, "minimal number of pixels to use for the mean", NULL, NULL}, + {"sigma", PARAM_FLOAT, "sigma scaled to [0,1] interval", NULL, NULL}, + {"radius_x", PARAM_INT, "median radius for x", NULL, NULL}, + {"radius_y", PARAM_INT, "median radius for y", NULL, NULL}, + {NULL, 0, NULL, NULL, NULL} +}; + +static GP_RetCode sigma_mean(GP_Context **c, const char *params) +{ + int rad = -1, rad_x, rad_y, min = 0; + float sigma = 0.1; + + if (param_parse(params, sigma_mean_params, "sigma", param_err, + &rad, &min, &sigma, &rad_x, &rad_y)) + return GP_EINVAL; + + if (rad != -1) { + rad_x = rad; + rad_y = rad; + } + + if (rad_x < 0 || rad_y < 0) + return GP_EINVAL; + + GP_Context *ret = GP_FilterSigmaAlloc(*c, rad_x, rad_y, min, sigma, progress_callback); + + if (ret == NULL) + return GP_ENOMEM; + + GP_ContextFree(*c); + *c = ret; + + return GP_ESUCCESS; +} + +/* laplacian edge sharpening filter */ + +static struct param sharpen_params[] = { + {"weight", PARAM_FLOAT, "sharpening weight from [0,1] interval", NULL, NULL}, + {NULL, 0, NULL, NULL, NULL} +}; + +static GP_RetCode sharpen(GP_Context **c, const char *params) +{ + float weight = 0.1; + + if (param_parse(params, sharpen_params, "sigma", param_err, &weight)) + return GP_EINVAL; + + GP_Context *ret = GP_FilterEdgeSharpeningAlloc(*c, weight, progress_callback); + + if (ret == NULL) + return GP_ENOMEM; + + GP_ContextFree(*c); + *c = ret; + + return GP_ESUCCESS; +}
/* arithmetics */
@@ -739,6 +802,8 @@ static struct filter filter_table[] = { {"arithmetic", "arithmetic operation", arithmetic_params, arithmetic}, {"histogram", "save histogram into image file", histogram_params, histogram}, {"median", "median filter", median_params, median}, + {"sigma", "sigma (mean) filter", sigma_mean_params, sigma_mean}, + {"sharpen", "laplacian edge sharpening", sharpen_params, sharpen}, {"jpg", "save jpg image", save_jpg_params, save_jpg}, {"png", "save png image", save_png_params, save_png}, {NULL, NULL, NULL, NULL}
http://repo.or.cz/w/gfxprim.git/commit/7de86b4f90000c336361314916ba2b1bc631b...
commit 7de86b4f90000c336361314916ba2b1bc631bba5 Author: Cyril Hrubis metan@ucw.cz Date: Fri Jul 27 18:51:00 2012 +0200
filtes: Add Sigma Mean filter.
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h index 451ec8c..e685ec3 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_Filters.h @@ -68,7 +68,10 @@ /* Median filter */ #include "filters/GP_Median.h"
-/* Median filter */ +/* Weighted Median filter */ #include "filters/GP_WeightedMedian.h"
+/* Sigma Mean filter */ +#include "filters/GP_Sigma.h" + #endif /* GP_FILTERS_H */ diff --git a/include/filters/GP_Sigma.h b/include/filters/GP_Sigma.h new file mode 100644 index 0000000..1660e5b --- /dev/null +++ b/include/filters/GP_Sigma.h @@ -0,0 +1,77 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + + /* + + Sigma Lee filter. + + The xrad and yrad denotes radius the filter works on. The number of neighbor + pixels is exactly 2 * rad + 1 for both directions. + + The sigma denotes maximal symetric difference of pixels scaled to [0,1] + interval. Greater sigma causes results to be closer to mean linear filter. + + The min parameter defines minimial number of pixels that must be in the two + sigma iterval, if there is a less pixels in this interval the new pixel + value is computed as mean of the surrounding pixels (not including the + center one). + + */ + +#ifndef GP_FILTERS_SIGMA_H +#define GP_FILTERS_SIGMA_H + +#include "GP_Filter.h" + +int GP_FilterSigmaEx(const GP_Context *src, + GP_Coord x_src, GP_Coord y_src, + GP_Size w_src, GP_Size h_src, + GP_Context *dst, + GP_Coord x_dst, GP_Coord y_dst, + int xrad, int yrad, int min, float sigma, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterSigmaExAlloc(const GP_Context *src, + GP_Coord x_src, GP_Coord y_src, + GP_Size w_src, GP_Size h_src, + int xrad, int yrad, int min, float sigma, + GP_ProgressCallback *callback); + +static inline int GP_FilterSigma(const GP_Context *src, + GP_Context *dst, + int xrad, int yrad, int min, float sigma, + GP_ProgressCallback *callback) +{ + return GP_FilterSigmaEx(src, 0, 0, src->w, src->h, + dst, 0, 0, xrad, yrad, min, sigma, callback); +} + +static inline GP_Context *GP_FilterSigmaAlloc(const GP_Context *src, + int xrad, int yrad, + int min, float sigma, + GP_ProgressCallback *callback) +{ + return GP_FilterSigmaExAlloc(src, 0, 0, src->w, src->h, + xrad, yrad, min, sigma, callback); +} + +#endif /* GP_FILTERS_SIGMA_H */ diff --git a/libs/filters/GP_Sigma.c b/libs/filters/GP_Sigma.c new file mode 100644 index 0000000..876e21d --- /dev/null +++ b/libs/filters/GP_Sigma.c @@ -0,0 +1,249 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include "core/GP_Context.h" +#include "core/GP_GetPutPixel.h" +#include "core/GP_TempAlloc.h" +#include "core/GP_Clamp.h" +#include "core/GP_Common.h" + +#include "core/GP_Debug.h" + +#include "GP_Sigma.h" + +#include <string.h> + +static int GP_FilterSigma_Raw(const GP_Context *src, + GP_Coord x_src, GP_Coord y_src, + GP_Size w_src, GP_Size h_src, + GP_Context *dst, + GP_Coord x_dst, GP_Coord y_dst, + int xrad, int yrad, int min, float sigma, + GP_ProgressCallback *callback) +{ + int x, y; + unsigned int x1, y1; + + GP_CHECK(src->pixel_type == GP_PIXEL_RGB888); + + GP_DEBUG(1, "Sigma Mean filter size %ux%u xrad=%u yrad=%u sigma=%.2f", + w_src, h_src, xrad, yrad, sigma); + + unsigned int R_sigma = 255 * sigma; + unsigned int G_sigma = 255 * sigma; + unsigned int B_sigma = 255 * sigma; + + unsigned int xdiam = 2 * xrad + 1; + unsigned int ydiam = 2 * yrad + 1; + + unsigned int w = w_src + xdiam; + unsigned int size = w * ydiam; + + GP_TempAllocCreate(temp, 3 * size * sizeof(unsigned int)); + + unsigned int *R = GP_TempAllocGet(temp, size * sizeof(unsigned int)); + unsigned int *G = GP_TempAllocGet(temp, size * sizeof(unsigned int)); + unsigned int *B = GP_TempAllocGet(temp, size * sizeof(unsigned int)); + + /* prefil the sampled array */ + for (x = 0; x < (int)w; x++) { + int xi = GP_CLAMP(x_src + x - xrad, 0, (int)src->w - 1); + + for (y = 0; y < ydiam; y++) { + int yi = GP_CLAMP(y_src + y - yrad, 0, (int)src->h - 1); + + GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi); + + R[y * w + x] = GP_Pixel_GET_R_RGB888(pix); + G[y * w + x] = GP_Pixel_GET_G_RGB888(pix); + B[y * w + x] = GP_Pixel_GET_B_RGB888(pix); + } + } + + unsigned int R_sum; + unsigned int G_sum; + unsigned int B_sum; + + unsigned int R_ssum; + unsigned int G_ssum; + unsigned int B_ssum; + + unsigned int R_cnt; + unsigned int G_cnt; + unsigned int B_cnt; + + unsigned int cnt = xdiam * ydiam - 1; + + /* center pixel ypsilon in the buffer */ + unsigned int yc = yrad; + /* last sampled ypsilon in the buffer */ + unsigned int yl = 0; + + /* Apply the sigma mean filter */ + for (y = 0; y < (int)h_src; y++) { + for (x = 0; x < (int)w_src; x++) { + /* Get center pixel */ + unsigned int R_center = R[yc * w + x + xrad]; + unsigned int G_center = G[yc * w + x + xrad]; + unsigned int B_center = B[yc * w + x + xrad]; + + /* Reset sum counters */ + R_sum = 0; + G_sum = 0; + B_sum = 0; + + R_ssum = 0; + G_ssum = 0; + B_ssum = 0; + + R_cnt = 0; + G_cnt = 0; + B_cnt = 0; + + for (x1 = 0; x1 < xdiam; x1++) { + for (y1 = 0; y1 < ydiam; y1++) { + unsigned int R_cur = R[y1 * w + x + x1]; + unsigned int G_cur = G[y1 * w + x + x1]; + unsigned int B_cur = B[y1 * w + x + x1]; + + R_sum += R_cur; + G_sum += G_cur; + B_sum += B_cur; + + if (abs(R_cur - R_center) < R_sigma) { + R_ssum += R_cur; + R_cnt++; + } + + if (abs(G_cur - G_center) < G_sigma) { + G_ssum += G_cur; + G_cnt++; + } + + if (abs(B_cur - B_center) < B_sigma) { + B_ssum += B_cur; + B_cnt++; + } + } + } + + R_sum -= R_center; + G_sum -= G_center; + B_sum -= B_center; + + unsigned int r; + unsigned int g; + unsigned int b; + + if (R_cnt >= min) + r = R_ssum / R_cnt; + else + r = R_sum / cnt; + + if (G_cnt >= min) + g = G_ssum / G_cnt; + else + g = G_sum / cnt; + + if (B_cnt >= min) + b = B_ssum / B_cnt; + else + b = B_sum / cnt; + + GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y, + GP_Pixel_CREATE_RGB888(r, g, b)); + } + + int yi = GP_CLAMP(y_src + y + yrad + 1, 0, (int)src->h - 1); + + for (x = 0; x < (int)w; x++) { + int xi = GP_CLAMP(x_src + x - xrad, 0, (int)src->w - 1); + + GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi); + + R[yl * w + x] = GP_Pixel_GET_R_RGB888(pix); + G[yl * w + x] = GP_Pixel_GET_G_RGB888(pix); + B[yl * w + x] = GP_Pixel_GET_B_RGB888(pix); + + } + + yc = (yc+1) % ydiam; + yl = (yl+1) % ydiam; + + if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) { + GP_TempAllocFree(temp); + return 1; + } + } + + GP_TempAllocFree(temp); + GP_ProgressCallbackDone(callback); + + return 0; +} + +int GP_FilterSigmaEx(const GP_Context *src, + GP_Coord x_src, GP_Coord y_src, + GP_Size w_src, GP_Size h_src, + GP_Context *dst, + GP_Coord x_dst, GP_Coord y_dst, + int xrad, int yrad, int min, float sigma, + GP_ProgressCallback *callback) +{ + GP_CHECK(src->pixel_type == dst->pixel_type); + + /* Check that destination is large enough */ + GP_CHECK(x_dst + (GP_Coord)w_src <= (GP_Coord)dst->w); + GP_CHECK(y_dst + (GP_Coord)h_src <= (GP_Coord)dst->h); + + GP_CHECK(xrad >= 0 && yrad >= 0); + + return GP_FilterSigma_Raw(src, x_src, y_src, w_src, h_src, + dst, x_dst, y_dst, xrad, yrad, min, sigma, + callback); +} + +GP_Context *GP_FilterSigmaExAlloc(const GP_Context *src, + GP_Coord x_src, GP_Coord y_src, + GP_Size w_src, GP_Size h_src, + int xrad, int yrad, int min, float sigma, + GP_ProgressCallback *callback) +{ + int ret; + + GP_CHECK(xrad >= 0 && yrad >= 0); + + GP_Context *dst = GP_ContextAlloc(w_src, h_src, src->pixel_type); + + if (dst == NULL) + return NULL; + + ret = GP_FilterSigma_Raw(src, x_src, y_src, w_src, h_src, + dst, 0, 0, xrad, yrad, min, sigma, callback); + + if (ret) { + GP_ContextFree(dst); + return NULL; + } + + return dst; +}
-----------------------------------------------------------------------
Summary of changes: demos/grinder/grinder.c | 74 ++++++++- include/filters/GP_Filters.h | 5 +- include/filters/{GP_Median.h => GP_Sigma.h} | 51 +++--- libs/filters/GP_Sigma.c | 249 +++++++++++++++++++++++++++ pylib/gfxprim/filters/filters.i | 4 + 5 files changed, 357 insertions(+), 26 deletions(-) copy include/filters/{GP_Median.h => GP_Sigma.h} (58%) create mode 100644 libs/filters/GP_Sigma.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.