/* * 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; /** * このクラスは、判別法を用いて敷居値を求める機能を提供します。 * <p>memo:画素数が2048^2に満たない場合は、fixedint(24-8)で計算できます。</p> */ public class NyARHistogramAnalyzer_DiscriminantThreshold implements INyARHistogramAnalyzer_Threshold { private double _score; /** * この関数は、判別法を用いて敷居値を1個求めます。敷居値の範囲は、i_histogram引数の範囲と同じです。 * 関数は、thisのプロパティを更新します。 */ public int getThreshold(NyARHistogram i_histogram) { int[] hist=i_histogram.data; int n=i_histogram.length; int da,sa,db,sb,dt,pt,st; int i; int th=0; //後で使う dt=pt=0; for(i=0;i<n;i++){ int h=hist[i]; dt+=h*i; pt+=h*i*i;//正規化の時に使う定数 } st=i_histogram.total_of_data; //Low側(0<=i<=n-2) da=dt; sa=st; //High側(i=n-1) db=sb=0; double max=-1; double max_mt=0; //各ヒストグラムの分離度を計算する(1<=i<=n-1の範囲で評価) for(i=n-1;i>0;i--){ //次のヒストグラムを計算 int hist_count=hist[i]; int hist_val=hist_count*i; da-=hist_val; sa-=hist_count; db+=hist_val; sb+=hist_count; //クラス間分散を計算 double dv=(sa+sb); double mt=(double)(da+db)/dv; double ma=(sa!=0?((double)da/(double)sa):0)-mt; double mb=(sb!=0?((double)db/(double)sb):0)-mt; double kai=((double)(sa*(ma*ma)+sb*(mb*mb)))/dv; if(max<kai){ max_mt=mt; max=kai; th=i; } //System.out.println(kai); } //max_mtを元に正規化 this._score=max/((double)(pt+max_mt*max_mt*st-2*max_mt*dt)/st);//129,0.8888888888888887 return th; } /** * 最後に実行した{@link #getThreshold}のスコアを返却します。 * @return * スコア値。範囲は0<=n<=1.0の間です。 */ public final double getLastScore() { return this._score; } /** * デバック用関数 * @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_DiscriminantThreshold an=new NyARHistogramAnalyzer_DiscriminantThreshold(); int th=an.getThreshold(data); System.out.print(th); return; } }