OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@793 7cac0...
[nyartoolkit-and/nyartoolkit-and.git] / lib / src / jp / nyatla / nyartoolkit / core / analyzer / histogram / NyARHistogramAnalyzer_KittlerThreshold.java
1 /* \r
2  * PROJECT: NyARToolkit(Extension)\r
3  * --------------------------------------------------------------------------------\r
4  * The NyARToolkit is Java edition ARToolKit class library.\r
5  * Copyright (C)2008-2009 Ryo Iizuka\r
6  *\r
7  * This program is free software: you can redistribute it and/or modify\r
8  * it under the terms of the GNU General Public License as published by\r
9  * the Free Software Foundation, either version 3 of the License, or\r
10  * (at your option) any later version.\r
11  * \r
12  * This program is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  * GNU General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU General Public License\r
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
19  * \r
20  * For further information please contact.\r
21  *      http://nyatla.jp/nyatoolkit/\r
22  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
23  * \r
24  */\r
25 package jp.nyatla.nyartoolkit.core.analyzer.histogram;\r
26 \r
27 import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
28 \r
29 \r
30 /**\r
31  * このクラスは、kittlerThresholdを用いて敷居値を求める機能を提供します。\r
32  */\r
33 public class NyARHistogramAnalyzer_KittlerThreshold implements INyARHistogramAnalyzer_Threshold\r
34 {\r
35         /**\r
36          * この関数は、kittlerThresholdを用いて敷居値を1個求めます。敷居値の範囲は、i_histogram引数の範囲と同じです。\r
37          */\r
38         public int getThreshold(NyARHistogram i_histogram)\r
39         {\r
40                 int i;          \r
41                 double min=Double.MAX_VALUE;\r
42                 int th=0;\r
43                 int da,sa,db,sb,pa,pb;\r
44                 double oa,ob;\r
45                 \r
46                 int[] hist=i_histogram.data;\r
47                 int n=i_histogram.length;\r
48                 //Low側\r
49                 da=pa=0;\r
50                 int h;\r
51                 for(i=0;i<n;i++){\r
52                         h=hist[i];\r
53                         da+=h*i;        //i*h[i]\r
54                         pa+=h*i*i;      //i*i*h[i]\r
55                 }\r
56                 sa=i_histogram.total_of_data;\r
57                 //High側(i=n-1)\r
58                 db=0;\r
59                 sb=0;\r
60                 pb=0;\r
61                 \r
62                 \r
63                 for(i=n-1;i>0;i--){\r
64                         //次のヒストグラムを計算\r
65                         int hist_count=hist[i];//h[i]\r
66                         int hist_val =hist_count*i;  //h[i]*i\r
67                         int hist_val2=hist_val*i;    //h[i]*i*i\r
68                         da-=hist_val;\r
69                         sa-=hist_count;\r
70                         pa-=hist_val2;\r
71                         db+=hist_val;\r
72                         sb+=hist_count;                 \r
73                         pb+=hist_val2;\r
74 \r
75                         //初期化\r
76                         double wa=(double)sa/(sa+sb);\r
77                         double wb=(double)sb/(sa+sb);\r
78                         if(wa==0 || wb==0){\r
79                                 continue;\r
80                         }\r
81 \r
82                         oa=ob=0;\r
83                         double ma=sa!=0?(double)da/sa:0;\r
84                         //Σ(i-ma)^2*h[i]=Σ(i^2*h[i])+Σ(ma^2*h[i])-Σ(2*i*ma*h[i])\r
85                         oa=((double)(pa+ma*ma*sa-2*ma*da))/sa;\r
86 \r
87                         double mb=sb!=0?(double)db/sb:0;\r
88                         //Σ(i-mb)^2*h[i]=Σ(i^2*h[i])+Σ(mb^2*h[i])-Σ(2*i*mb*h[i])\r
89                         ob=((double)(pb+mb*mb*sb-2*mb*db))/sb;\r
90 \r
91                         double kai=wa*Math.log(oa/wa)+wb*Math.log(ob/wb);\r
92                         if(kai>0 && min>kai){\r
93                                 min=kai;\r
94                                 th=i;\r
95                         }\r
96                         //System.out.println(kai);\r
97 \r
98                 }\r
99                 return th;//129//7.506713872738873\r
100         }\r
101         /**\r
102          * デバック用関数\r
103          * @param args\r
104          * main関数引数\r
105          */     \r
106         public static void main(String[] args)\r
107         {\r
108                 NyARHistogram data=new NyARHistogram(256);\r
109                 for(int i=0;i<256;i++){\r
110                         data.data[i]=128-i>0?128-i:i-128;\r
111                 }\r
112                 data.total_of_data=data.getTotal(0,255);\r
113                 NyARHistogramAnalyzer_KittlerThreshold an=new NyARHistogramAnalyzer_KittlerThreshold();\r
114                 int th=an.getThreshold(data);\r
115                 System.out.print(th);\r
116                 return;\r
117         }\r
118 }\r