/*
* PROJECT: NyARToolkit(Extension)
* --------------------------------------------------------------------------------
* The NyARToolkit is Java edition ARToolKit class library.
* Copyright (C)2008-2009 Ryo Iizuka
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For further information please contact.
* http://nyatla.jp/nyatoolkit/
* <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
*
*/
package jp.nyatla.nyartoolkit.core.analyzer.histogram;
import jp.nyatla.nyartoolkit.core.types.NyARHistogram;
/**
* このクラスは、kittlerThresholdを用いて敷居値を求める機能を提供します。
*/
public class NyARHistogramAnalyzer_KittlerThreshold implements INyARHistogramAnalyzer_Threshold
{
/**
* この関数は、kittlerThresholdを用いて敷居値を1個求めます。敷居値の範囲は、i_histogram引数の範囲と同じです。
*/
public int getThreshold(NyARHistogram i_histogram)
{
int i;
double min=Double.MAX_VALUE;
int th=0;
int da,sa,db,sb,pa,pb;
double oa,ob;
int[] hist=i_histogram.data;
int n=i_histogram.length;
//Low側
da=pa=0;
int h;
for(i=0;i<n;i++){
h=hist[i];
da+=h*i; //i*h[i]
pa+=h*i*i; //i*i*h[i]
}
sa=i_histogram.total_of_data;
//High側(i=n-1)
db=0;
sb=0;
pb=0;
for(i=n-1;i>0;i--){
//次のヒストグラムを計算
int hist_count=hist[i];//h[i]
int hist_val =hist_count*i; //h[i]*i
int hist_val2=hist_val*i; //h[i]*i*i
da-=hist_val;
sa-=hist_count;
pa-=hist_val2;
db+=hist_val;
sb+=hist_count;
pb+=hist_val2;
//初期化
double wa=(double)sa/(sa+sb);
double wb=(double)sb/(sa+sb);
if(wa==0 || wb==0){
continue;
}
oa=ob=0;
double ma=sa!=0?(double)da/sa:0;
//Σ(i-ma)^2*h[i]=Σ(i^2*h[i])+Σ(ma^2*h[i])-Σ(2*i*ma*h[i])
oa=((double)(pa+ma*ma*sa-2*ma*da))/sa;
double mb=sb!=0?(double)db/sb:0;
//Σ(i-mb)^2*h[i]=Σ(i^2*h[i])+Σ(mb^2*h[i])-Σ(2*i*mb*h[i])
ob=((double)(pb+mb*mb*sb-2*mb*db))/sb;
double kai=wa*Math.log(oa/wa)+wb*Math.log(ob/wb);
if(kai>0 && min>kai){
min=kai;
th=i;
}
//System.out.println(kai);
}
return th;//129//7.506713872738873
}
/**
* デバック用関数
* @param args
* main関数引数
*/
public static void main(String[] args)
{
NyARHistogram data=new NyARHistogram(256);
for(int i=0;i<256;i++){
data.data[i]=128-i>0?128-i:i-128;
}
data.total_of_data=data.getTotal(0,255);
NyARHistogramAnalyzer_KittlerThreshold an=new NyARHistogramAnalyzer_KittlerThreshold();
int th=an.getThreshold(data);
System.out.print(th);
return;
}
}