「Niblackの手法」という二値化のアルゴリズムをコーディングしていたのですが、その中では平均と標準偏差を求める処理が必要になります。ものすごく端折って書くと、最初はこのような感じで求めていました。
int[] array = new int[]{1, 7, 3, 8, 9, 4}; double sum = 0; foreach(int i in array){ sum += i; } double mean = sum / array.Length; // 平均 sum = 0; foreach(int i in array){ sum += Math.Pow(i - mean, 2); } double variance = sum / array.Length; // 分散 double stddev = Math.Sqrt(variance); // 標準偏差
分散の式
を直訳した形ですが、これだとループが2つあるので効率が悪いです。実際、このときは画像処理に8秒程もかかりました。
統計学の本などで分散の式が載っている場合、大抵式が2通りぐらい載っている気がします。そのもう一つの方で以下のように書き換えることで、ループは1つで済みます。
int[] array = new int[]{1, 7, 3, 8, 9, 4}; double sum_m = 0, sum_v = 0; foreach(int i in array){ sum_m += i; sum_v += i*i; } double mean = sum_m / array.Length; double variance = (sum_v / array.Length) - (mean * mean); double stddev = Math.Sqrt(variance);
こちらの場合、画像処理は2秒程にまで高速化されました。