大津の方法による閾値の計算

判別分別法を用いた大津の方法によって、二値化処理を行うための閾値を求めてみます。
あまり詳しくありませんが、閾値を求める方法の中でもこれが一番ポピュラーな方法らしいです。
大津の方法に関してはこのサイトを参考にしました。

以前と同じように、画像はグレー画像であらかじめ二次元配列imageに読み込まれているものとします。

void DiscriminantAnalysis(void)
{
	 
	int histgram[256] = {0};//ヒストグラム
	int sum = 0;
	int max_no;
	long data = 0;
	double average, average1, average2;
	double max = 0.0;
	int count1, count2;
	double breakup1, breakup2;
	double class1, class2;
	double tmp;
	

	for(int i=0;i<y_size;i++){	//y_sizeは画像の縦幅
		for(int j=0;j<x_size;j++){	//x_sizeは画像の横幅
			/*各画素値が画像中にどれくらいあるのか算出する*/
			histgram[image[i][j]]++;	
			sum += image[i][j];
		}
	}
	average = sum / (x_size * y_size);
	
	for(int i=0;i<256;i++){
		count1 = count2 = 0;
		data = 0;
		breakup1 = breakup2 = 0.0;	
		tmp = 0;
		
		for(int j=0;j<i;j++){
			count1 += histgram[j];
			data += histgram[j] * j;
		}
		
		/*クラス1の平均*/
		/*平均 =(データの総和 / 個数)*/
		if(count1 != 0){
			average1 = (double)data / (double)count1;

			/*分散*/
			/*分散=(データ - 平均値)^2の総和/個数 */
			for(int j=0;j<i;j++){
				breakup1 += pow( (j- average1), 2 ) * histgram[j];
			}
			breakup1 /= (double)count1; 
		}
		
		data = 0;
		
		for(int j=i;j<256;j++){
			count2 += histgram[j];
			data += histgram[j] * j;
		}
		if(count2 != 0){
			average2 = (double)data / (double)count2;

			for(int j=i;j<256;j++){
				breakup2 += pow( (j - average2), 2 ) * histgram[j];
			}
		
			breakup2 /= (double)count2;
		}
		
		/*クラス内分散*/
		class1 = (count1 * breakup1 + count2 * breakup2);
		/*クラス間分散*/
		class2 = count1 * pow( (average1 - average), 2 ) + count2 * pow( (average2 - average), 2 );
		
		tmp = class2 / class1;
		
		
		if(max < tmp){
			max = tmp;
			max_no = i;
		}
	}
	printf("閾値 = %d\n",max_no);
}

これで閾値が求められます。この閾値を用いて二値化処理を行います。