From 2892a3d7522d6b758d3efb5825348d2cd0be91c5 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 31 Mar 2012 17:43:04 +0200 Subject: roi: Split do_roi into interval creation and matching --- roi.c | 96 +++++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/roi.c b/roi.c index 59eb57a..4c07a96 100644 --- a/roi.c +++ b/roi.c @@ -20,6 +20,10 @@ struct roi { struct { double x1, y1, x2, y2; } rubberband; + + struct match_interval { + gint min, max; + } interval[3]; }; static inline void @@ -44,45 +48,29 @@ pixbuf_get(GdkPixbuf *pixbuf, guchar **pixels, if (stride) *stride = gdk_pixbuf_get_rowstride(pixbuf); } -static gboolean -do_roi(struct roi *roi) +static void +calc_roi_interval(struct roi *roi, GdkPixbuf *match) { - GdkPixbuf *match; - cairo_rectangle_t area; gint i, s, x, y, width, height, nch, stride; - guchar *pix, *row; + guchar *p, *row; gint middle[3] = { 0, 0, 0 }; gint sigma[3] = { 0, 0, 0 }; - struct match_interval { gint min, max; } interval[3]; - - calc_rubberband_rect(roi, &area.x, &area.y, &area.width, &area.height); - - if (area.width < 1 || area.height < 1) - return FALSE; - match = gdk_pixbuf_new_subpixbuf(roi->input, area.x, area.y, - area.width, area.height); - s = area.width * area.height; - - pixbuf_get(match, &row, NULL, NULL, &nch, &stride); - for (y = 0; y < area.height; ++y, row += stride) { - for (x = 0, pix = row; x < area.width; ++x, pix += nch) { + pixbuf_get(match, &row, &width, &height, &nch, &stride); + for (y = 0; y < height; ++y, row += stride) + for (x = 0, p = row; x < width; ++x, p += nch) for (i = 0; i < 3; ++i) - middle[i] += pix[i]; - } - } + middle[i] += p[i]; + s = width * height; for (i = 0; i < 3; ++i) middle[i] /= s; - pixbuf_get(match, &row, NULL, NULL, NULL, NULL); - for (y = 0; y < area.height; ++y, row += stride) { - for (x = 0, pix = row; x < area.width; ++x, pix += nch) { + row = gdk_pixbuf_get_pixels(match); + for (y = 0; y < height; ++y, row += stride) + for (x = 0, p = row; x < width; ++x, p += nch) for (i = 0; i < 3; ++i) - sigma[i] += - (pix[i] - middle[i]) * - (pix[i] - middle[i]); - } - } + sigma[i] += ((p[i] - middle[i]) * + (p[i] - middle[i])); for (i = 0; i < 3; ++i) sigma[i] = sqrt(sigma[i] / (s - 1)); @@ -90,32 +78,54 @@ do_roi(struct roi *roi) printf("sigma: %3d, %3d, %3d\n", sigma[0], sigma[1], sigma[2]); for (i = 0; i < 3; ++i) { - interval[i].min = middle[i] - 3 * sigma[i]; - interval[i].max = middle[i] + 3 * sigma[i]; + roi->interval[i].min = middle[i] - 3 * sigma[i]; + roi->interval[i].max = middle[i] + 3 * sigma[i]; printf("interval %d: [%3d - %3d]\n", - i, interval[i].min, interval[i].max); + i, roi->interval[i].min, roi->interval[i].max); } +} - if (roi->modified_input) - g_object_unref(roi->modified_input); - roi->modified_input = gdk_pixbuf_copy(roi->input); +static void +mark_matching_pixels(struct roi *roi, GdkPixbuf *image) +{ + gint i, x, y, width, height, nch, stride; + guchar *p, *row; - pixbuf_get(roi->modified_input, &row, &width, &height, &nch, &stride); + pixbuf_get(image, &row, &width, &height, &nch, &stride); for (y = 0; y < height; ++y, row += stride) { - for (x = 0, pix = row; x < width; ++x, pix += nch) { - int H = 1; + for (x = 0, p = row; x < width; ++x, p += nch) { + gboolean H = TRUE; for (i = 0; i < 3; ++i) { - if (!(pix[i] >= interval[i].min && - pix[i] <= interval[i].max)) - H = 0; + if (!(p[i] >= roi->interval[i].min && + p[i] <= roi->interval[i].max)) + H = FALSE; } - if (H) - pix[0] = pix[1] = pix[2] = 0; + if (H) p[0] = p[1] = p[2] = 0; } } +} +static gboolean +do_roi(struct roi *roi) +{ + GdkPixbuf *match; + cairo_rectangle_t area; + + calc_rubberband_rect(roi, &area.x, &area.y, &area.width, &area.height); + if (area.width < 1 || area.height < 1) + return FALSE; + + match = gdk_pixbuf_new_subpixbuf(roi->input, area.x, area.y, + area.width, area.height); + calc_roi_interval(roi, match); g_object_unref(match); + if (roi->modified_input) + g_object_unref(roi->modified_input); + roi->modified_input = gdk_pixbuf_copy(roi->input); + + mark_matching_pixels(roi, roi->modified_input); + return TRUE; } -- cgit