二値化の境界線を決める

二値化は離散化したデータをさらに0か1に決めるというものです。その境界線を決めるには手動でやってもいいのですが、やっぱりデータがあってパソコンを使ってしかもプログラミングを編むということでプログラムを書いてみました。あんまり出来は良くないかもしれないけれども、ここに公開してみます。

ここで後半の分散どうしの割り算のところが最大値になるiの値が求める境界線になります。

#include <stdio.h>
#include <stdlib.h>

/* 配列の要素数を数える */
#define NUMBER(array) (sizeof(array)/sizeof(array[0]))

double calc_average(int *data, int size)
{
	int i;
	double average = 0;
	
	for (i = 0; i < size; i++) {
		average += data[i];
	}
	return (average/size);
}

double calc_variance(int *data, int size)
{
	int i;
	double average = calc_average(data, size);
	double variance = 0;
	
	for (i = 0; i < size; i++) {
		variance += (average - data[i]) * (average - data[i]);
	}
	
	return variance/size;
}

int main(int argc, char *argv[])
{
	int i;
	int hairetsu[] = {1,2,6,7,11,15,12,5,6,7,13,15,7,5,2};
	double before_variance;
	double after_variance;
	
	printf("calc_average() = %lf\n", calc_average(hairetsu, NUMBER(hairetsu)));
	printf("calc_variance() = %lf\n", calc_variance(hairetsu, NUMBER(hairetsu)));
	
	for (i = 1; i < NUMBER(hairetsu); i++) {
		// printf("i = %d\n", i);
		printf("前半の分散 = %lf\n",
			before_variance = calc_variance(hairetsu, i));
		printf("後半の分散 = %lf\n",
			after_variance = calc_variance(hairetsu+i, NUMBER(hairetsu)-i));
		
		if (!(before_variance == 0
		 || after_variance == 0
		 || i < NUMBER(hairetsu)/4 
		 || i > 3*NUMBER(hairetsu)/4)) {
			printf("i = %d, before/after = %lf\n",
			 i, (before_variance/after_variance));
		}
	}
	
	exit(0);
}