001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.pub.threshold; 011 012public abstract class Thresholder { 013 014 // compute the sum of a histogram array 015 protected int sum(int[] h) { 016 int cnt = 0; 017 for (int i=0; i<h.length; i++) { 018 cnt += h[i]; 019 } 020 return cnt; 021 } 022 023 protected int count(int[] h) { 024 return count(h,0,h.length-1); 025 } 026 027 // compute the population of a histogram from index lo...hi 028 protected int count(int[] h, int lo, int hi) { 029 if (lo < 0) lo = 0; 030 if (hi >= h.length) hi = h.length-1; 031 int cnt = 0; 032 for (int i = lo; i <= hi; i++) { 033 cnt += h[i]; 034 } 035 return cnt; 036 } 037 038 protected double mean(int[] h) { 039 return mean(h,0,h.length-1); 040 } 041 042 protected double mean(int[] h, int lo, int hi) { 043 if (lo < 0) lo = 0; 044 if (hi >= h.length) hi = h.length-1; 045 long cnt = 0; 046 long sum = 0; 047 for (int i=lo; i<=hi; i++) { 048 cnt = cnt + h[i]; 049 sum = sum + i * h[i]; 050 } 051 if (cnt > 0) 052 return ((double)sum) / cnt; 053 else 054 return 0; 055 } 056 057 protected double sigma2(int[] h) { 058 return sigma2(h, 0, h.length-1); 059 } 060 061 // this is a slow version, only for testing: 062// protected double sigma2(int[] h, int lo, int hi) { 063// if (lo < 0) lo = 0; 064// if (hi >= h.length) hi = h.length-1; 065// double mu = mean(h,lo,hi); 066// long cnt = 0; 067// double sum = 0; 068// for (int i=lo; i<=hi; i++) { 069// cnt = cnt + h[i]; 070// sum = sum + (i - mu) * (i - mu) * h[i]; 071// } 072// if (cnt > 0) 073// return ((double)sum) / cnt; 074// else 075// return 0; 076// } 077 078 // fast version 079 protected double sigma2(int[] h, int lo, int hi) { 080 if (lo < 0) lo = 0; 081 if (hi >= h.length) hi = h.length-1; 082 long A = 0; 083 long B = 0; 084 long N = 0; 085 for (int i=lo; i<=hi; i++) { 086 int ni = h[i]; 087 A = A + i * ni; 088 B = B + i * i * ni; 089 N = N + ni; 090 } 091 if (N > 0) 092 return ((double)B - (double)A*A / N) / N; 093 else 094 return 0; 095 } 096 097 098 // --- utility methods ----------------------------- 099 100 // compute the median of a histogram 101 protected int median(int[] h) { 102 int K = h.length; 103 int N = sum(h); 104 int m = N / 2; 105 int i = 0; 106 int sum = h[0]; 107 while (sum <= m && i < K) { 108 i++; 109 sum += h[i]; 110 } 111 return i; 112 } 113 114 public double[] normalize(int[] h) { 115 int K = h.length; 116 int N = count(h); 117 double[] nh = new double[K]; 118 for (int i=0; i<K; i++) { 119 nh[i] = ((double) h[i]) / N; 120 } 121 return nh; 122 } 123 124 public double[] normalize(double[] h) { 125 double[] nh = new double[h.length]; 126 double hmax = max(h); 127 for (int i=0; i<h.length; i++) { 128 nh[i] = (double) h[i] / hmax; 129 } 130 return nh; 131 } 132 133 public double max(double[] h) { 134 double hmax = Double.NEGATIVE_INFINITY; 135 for (int i=0; i<h.length; i++) { 136 double n = h[i]; 137 if (n>hmax) hmax = n; 138 } 139 return hmax; 140 141 } 142 143}