summaryrefslogtreecommitdiff
path: root/roi.c
diff options
context:
space:
mode:
Diffstat (limited to 'roi.c')
-rw-r--r--roi.c96
1 files 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;
}