From de68db7b690719fc780fcb8308c5715267e67ed6 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Apr 2021 13:24:32 +0900 Subject: [PATCH 1/2] otsu: Use double for weighted sums My phone camera produces 12M-pixel images. They can easily overflow an int. --- lib/identify.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/identify.c b/lib/identify.c index b725fea..584994f 100644 --- a/lib/identify.c +++ b/lib/identify.c @@ -190,14 +190,14 @@ static uint8_t otsu(const struct quirc *q) } // Calculate weighted sum of histogram values - unsigned int sum = 0; + double sum = 0; unsigned int i = 0; for (i = 0; i <= UINT8_MAX; ++i) { sum += i * histogram[i]; } // Compute threshold - int sumB = 0; + double sumB = 0; int q1 = 0; double max = 0; uint8_t threshold = 0; @@ -213,8 +213,8 @@ static uint8_t otsu(const struct quirc *q) break; sumB += i * histogram[i]; - const double m1 = (double)sumB / q1; - const double m2 = ((double)sum - sumB) / q2; + const double m1 = sumB / q1; + const double m2 = (sum - sumB) / q2; const double m1m2 = m1 - m2; const double variance = m1m2 * m1m2 * q1 * q2; if (variance >= max) { From ea9b6ee5efbcff60b2737dd1378b3dbf22c6f93c Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 8 Apr 2021 13:35:12 +0900 Subject: [PATCH 2/2] otsu: Use unsigned for the pixel numbers Because singed numbers don't make sense here. --- lib/identify.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/identify.c b/lib/identify.c index 584994f..5c66865 100644 --- a/lib/identify.c +++ b/lib/identify.c @@ -177,13 +177,13 @@ static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to, static uint8_t otsu(const struct quirc *q) { - int numPixels = q->w * q->h; + unsigned int numPixels = q->w * q->h; // Calculate histogram unsigned int histogram[UINT8_MAX + 1]; (void)memset(histogram, 0, sizeof(histogram)); uint8_t* ptr = q->image; - int length = numPixels; + unsigned int length = numPixels; while (length--) { uint8_t value = *ptr++; histogram[value]++; @@ -198,7 +198,7 @@ static uint8_t otsu(const struct quirc *q) // Compute threshold double sumB = 0; - int q1 = 0; + unsigned int q1 = 0; double max = 0; uint8_t threshold = 0; for (i = 0; i <= UINT8_MAX; ++i) { @@ -208,7 +208,7 @@ static uint8_t otsu(const struct quirc *q) continue; // Weighted foreground - const int q2 = numPixels - q1; + const unsigned int q2 = numPixels - q1; if (q2 == 0) break;