[gegl/wip/rishi/operation-shadhi] algorithms: improve boxfilter accuracy
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/wip/rishi/operation-shadhi] algorithms: improve boxfilter accuracy
- Date: Sat, 11 Nov 2017 14:56:06 +0000 (UTC)
commit 6eed0d499e60c976e2ec7d107d8fa63b66752c33
Author: Ell <ell_se yahoo com>
Date: Fri Nov 10 13:49:32 2017 -0500
algorithms: improve boxfilter accuracy
Don't multiply individual pixels by combined row/column weights.
Instead, calculate the columns separately, using only the row
weights, and then combine them using the column weights. This
improves accuracy sufficiently so that when all the input value
are 1, the result is not greater than 1, which could previously
happen (or at least it's far less likely to happen now.)
Performance should be at most marginally worse for 4-component
pixels, about the same for 3-component pixels, and slightly better
for 2- and 1-component pixels.
gegl/gegl-algorithms-boxfilter.inc | 160 +++++++++++++++++-------------------
1 files changed, 77 insertions(+), 83 deletions(-)
---
diff --git a/gegl/gegl-algorithms-boxfilter.inc b/gegl/gegl-algorithms-boxfilter.inc
index db2eb5b..f8a0f14 100644
--- a/gegl/gegl-algorithms-boxfilter.inc
+++ b/gegl/gegl-algorithms-boxfilter.inc
@@ -73,32 +73,30 @@ BOXFILTER_FUNCNAME (guchar *dest_buf,
}
else
{
- const gfloat lt = left_weight[x] * top_weight;
- const gfloat lm = left_weight[x] * middle_weight;
- const gfloat lb = left_weight[x] * bottom_weight;
- const gfloat ct = center_weight[x] * top_weight;
- const gfloat cm = center_weight[x] * middle_weight;
- const gfloat cb = center_weight[x] * bottom_weight;
- const gfloat rt = right_weight[x] * top_weight;
- const gfloat rm = right_weight[x] * middle_weight;
- const gfloat rb = right_weight[x] * bottom_weight;
-
- dst[0] = BOXFILTER_ROUND(
- src[0][0] * lt + src[3][0] * lm + src[6][0] * lb +
- src[1][0] * ct + src[4][0] * cm + src[7][0] * cb +
- src[2][0] * rt + src[5][0] * rm + src[8][0] * rb);
- dst[1] = BOXFILTER_ROUND(
- src[0][1] * lt + src[3][1] * lm + src[6][1] * lb +
- src[1][1] * ct + src[4][1] * cm + src[7][1] * cb +
- src[2][1] * rt + src[5][1] * rm + src[8][1] * rb);
- dst[2] = BOXFILTER_ROUND(
- src[0][2] * lt + src[3][2] * lm + src[6][2] * lb +
- src[1][2] * ct + src[4][2] * cm + src[7][2] * cb +
- src[2][2] * rt + src[5][2] * rm + src[8][2] * rb);
- dst[3] = BOXFILTER_ROUND(
- src[0][3] * lt + src[3][3] * lm + src[6][3] * lb +
- src[1][3] * ct + src[4][3] * cm + src[7][3] * cb +
- src[2][3] * rt + src[5][3] * rm + src[8][3] * rb);
+ const gfloat l = left_weight[x];
+ const gfloat c = center_weight[x];
+ const gfloat r = right_weight[x];
+
+ const gfloat t = top_weight;
+ const gfloat m = middle_weight;
+ const gfloat b = bottom_weight;
+
+ dst[0] = BOXFILTER_ROUND(
+ (src[0][0] * t + src[3][0] * m + src[6][0] * b) * l +
+ (src[1][0] * t + src[4][0] * m + src[7][0] * b) * c +
+ (src[2][0] * t + src[5][0] * m + src[8][0] * b) * r);
+ dst[1] = BOXFILTER_ROUND(
+ (src[0][1] * t + src[3][1] * m + src[6][1] * b) * l +
+ (src[1][1] * t + src[4][1] * m + src[7][1] * b) * c +
+ (src[2][1] * t + src[5][1] * m + src[8][1] * b) * r);
+ dst[2] = BOXFILTER_ROUND(
+ (src[0][2] * t + src[3][2] * m + src[6][2] * b) * l +
+ (src[1][2] * t + src[4][2] * m + src[7][2] * b) * c +
+ (src[2][2] * t + src[5][2] * m + src[8][2] * b) * r);
+ dst[3] = BOXFILTER_ROUND(
+ (src[0][3] * t + src[3][3] * m + src[6][3] * b) * l +
+ (src[1][3] * t + src[4][3] * m + src[7][3] * b) * c +
+ (src[2][3] * t + src[5][3] * m + src[8][3] * b) * r);
}
dst += 4;
}
@@ -116,27 +114,26 @@ BOXFILTER_FUNCNAME (guchar *dest_buf,
src[3] = src[4] - 3;
src[6] = src[7] - 3;
{
- const gfloat lt = left_weight[x] * top_weight;
- const gfloat lm = left_weight[x] * middle_weight;
- const gfloat lb = left_weight[x] * bottom_weight;
- const gfloat ct = center_weight[x] * top_weight;
- const gfloat cm = center_weight[x] * middle_weight;
- const gfloat cb = center_weight[x] * bottom_weight;
- const gfloat rt = right_weight[x] * top_weight;
- const gfloat rm = right_weight[x] * middle_weight;
- const gfloat rb = right_weight[x] * bottom_weight;
+ const gfloat l = left_weight[x];
+ const gfloat c = center_weight[x];
+ const gfloat r = right_weight[x];
+
+ const gfloat t = top_weight;
+ const gfloat m = middle_weight;
+ const gfloat b = bottom_weight;
+
dst[0] = BOXFILTER_ROUND(
- src[0][0] * lt + src[3][0] * lm + src[6][0] * lb +
- src[1][0] * ct + src[4][0] * cm + src[7][0] * cb +
- src[2][0] * rt + src[5][0] * rm + src[8][0] * rb);
+ (src[0][0] * t + src[3][0] * m + src[6][0] * b) * l +
+ (src[1][0] * t + src[4][0] * m + src[7][0] * b) * c +
+ (src[2][0] * t + src[5][0] * m + src[8][0] * b) * r);
dst[1] = BOXFILTER_ROUND(
- src[0][1] * lt + src[3][1] * lm + src[6][1] * lb +
- src[1][1] * ct + src[4][1] * cm + src[7][1] * cb +
- src[2][1] * rt + src[5][1] * rm + src[8][1] * rb);
+ (src[0][1] * t + src[3][1] * m + src[6][1] * b) * l +
+ (src[1][1] * t + src[4][1] * m + src[7][1] * b) * c +
+ (src[2][1] * t + src[5][1] * m + src[8][1] * b) * r);
dst[2] = BOXFILTER_ROUND(
- src[0][2] * lt + src[3][2] * lm + src[6][2] * lb +
- src[1][2] * ct + src[4][2] * cm + src[7][2] * cb +
- src[2][2] * rt + src[5][2] * rm + src[8][2] * rb);
+ (src[0][2] * t + src[3][2] * m + src[6][2] * b) * l +
+ (src[1][2] * t + src[4][2] * m + src[7][2] * b) * c +
+ (src[2][2] * t + src[5][2] * m + src[8][2] * b) * r);
}
dst += 3;
}
@@ -154,23 +151,22 @@ BOXFILTER_FUNCNAME (guchar *dest_buf,
src[3] = src[4] - 2;
src[6] = src[7] - 2;
{
- const gfloat lt = left_weight[x] * top_weight;
- const gfloat lm = left_weight[x] * middle_weight;
- const gfloat lb = left_weight[x] * bottom_weight;
- const gfloat ct = center_weight[x] * top_weight;
- const gfloat cm = center_weight[x] * middle_weight;
- const gfloat cb = center_weight[x] * bottom_weight;
- const gfloat rt = right_weight[x] * top_weight;
- const gfloat rm = right_weight[x] * middle_weight;
- const gfloat rb = right_weight[x] * bottom_weight;
+ const gfloat l = left_weight[x];
+ const gfloat c = center_weight[x];
+ const gfloat r = right_weight[x];
+
+ const gfloat t = top_weight;
+ const gfloat m = middle_weight;
+ const gfloat b = bottom_weight;
+
dst[0] = BOXFILTER_ROUND(
- src[0][0] * lt + src[3][0] * lm + src[6][0] * lb +
- src[1][0] * ct + src[4][0] * cm + src[7][0] * cb +
- src[2][0] * rt + src[5][0] * rm + src[8][0] * rb);
+ (src[0][0] * t + src[3][0] * m + src[6][0] * b) * l +
+ (src[1][0] * t + src[4][0] * m + src[7][0] * b) * c +
+ (src[2][0] * t + src[5][0] * m + src[8][0] * b) * r);
dst[1] = BOXFILTER_ROUND(
- src[0][1] * lt + src[3][1] * lm + src[6][1] * lb +
- src[1][1] * ct + src[4][1] * cm + src[7][1] * cb +
- src[2][1] * rt + src[5][1] * rm + src[8][1] * rb);
+ (src[0][1] * t + src[3][1] * m + src[6][1] * b) * l +
+ (src[1][1] * t + src[4][1] * m + src[7][1] * b) * c +
+ (src[2][1] * t + src[5][1] * m + src[8][1] * b) * r);
}
dst += 2;
}
@@ -188,19 +184,18 @@ BOXFILTER_FUNCNAME (guchar *dest_buf,
src[3] = src[4] - 1;
src[6] = src[7] - 1;
{
- const gfloat lt = left_weight[x] * top_weight;
- const gfloat lm = left_weight[x] * middle_weight;
- const gfloat lb = left_weight[x] * bottom_weight;
- const gfloat ct = center_weight[x] * top_weight;
- const gfloat cm = center_weight[x] * middle_weight;
- const gfloat cb = center_weight[x] * bottom_weight;
- const gfloat rt = right_weight[x] * top_weight;
- const gfloat rm = right_weight[x] * middle_weight;
- const gfloat rb = right_weight[x] * bottom_weight;
+ const gfloat l = left_weight[x];
+ const gfloat c = center_weight[x];
+ const gfloat r = right_weight[x];
+
+ const gfloat t = top_weight;
+ const gfloat m = middle_weight;
+ const gfloat b = bottom_weight;
+
dst[0] = BOXFILTER_ROUND(
- src[0][0] * lt + src[3][0] * lm + src[6][0] * lb +
- src[1][0] * ct + src[4][0] * cm + src[7][0] * cb +
- src[2][0] * rt + src[5][0] * rm + src[8][0] * rb);
+ (src[0][0] * t + src[3][0] * m + src[6][0] * b) * l +
+ (src[1][0] * t + src[4][0] * m + src[7][0] * b) * c +
+ (src[2][0] * t + src[5][0] * m + src[8][0] * b) * r);
}
dst += 1;
}
@@ -218,21 +213,20 @@ BOXFILTER_FUNCNAME (guchar *dest_buf,
src[3] = src[4] - components;
src[6] = src[7] - components;
{
- const gfloat lt = left_weight[x] * top_weight;
- const gfloat lm = left_weight[x] * middle_weight;
- const gfloat lb = left_weight[x] * bottom_weight;
- const gfloat ct = center_weight[x] * top_weight;
- const gfloat cm = center_weight[x] * middle_weight;
- const gfloat cb = center_weight[x] * bottom_weight;
- const gfloat rt = right_weight[x] * top_weight;
- const gfloat rm = right_weight[x] * middle_weight;
- const gfloat rb = right_weight[x] * bottom_weight;
+ const gfloat l = left_weight[x];
+ const gfloat c = center_weight[x];
+ const gfloat r = right_weight[x];
+
+ const gfloat t = top_weight;
+ const gfloat m = middle_weight;
+ const gfloat b = bottom_weight;
+
for (gint i = 0; i < components; ++i)
{
dst[i] = BOXFILTER_ROUND(
- src[0][i] * lt + src[3][i] * lm + src[6][i] * lb +
- src[1][i] * ct + src[4][i] * cm + src[7][i] * cb +
- src[2][i] * rt + src[5][i] * rm + src[8][i] * rb);
+ (src[0][i] * t + src[3][i] * m + src[6][i] * b) * l +
+ (src[1][i] * t + src[4][i] * m + src[7][i] * b) * c +
+ (src[2][i] * t + src[5][i] * m + src[8][i] * b) * r);
}
}
dst += components;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]