OSDN Git Service

244c05fa613d3e3110cdf178471a8c375ae0d3ad
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core / analyzer / histgram / NyARHistgramAnalyzer_DiscriminantThreshold.java
1 package jp.nyatla.nyartoolkit.core.analyzer.histgram;\r
2 \r
3 import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
4 \r
5 /**\r
6  * 判別法で閾値を求めます。\r
7  * 画素数が2048^2に満たない場合は、fixedint(24-8)で計算できます。\r
8  * @param i_histgram\r
9  * @param o_value\r
10  * @return\r
11  */\r
12 public class NyARHistgramAnalyzer_DiscriminantThreshold implements INyARHistgramAnalyzer_Threshold\r
13 {\r
14         private double _score;\r
15 \r
16         public int getThreshold(NyARHistgram i_histgram)\r
17         {\r
18                 int[] hist=i_histgram.data;\r
19                 int n=i_histgram.length;\r
20                 int da,sa,db,sb,dt,pt,st;\r
21                 int i;          \r
22                 int th=0;\r
23                 //後で使う\r
24                 dt=pt=0;\r
25                 for(i=0;i<n;i++){\r
26                         int h=hist[i];\r
27                         dt+=h*i;\r
28                         pt+=h*i*i;//正規化の時に使う定数\r
29                 }\r
30                 st=i_histgram.total_of_data;\r
31                 //Low側(0<=i<=n-2)\r
32                 da=dt;\r
33                 sa=st;\r
34                 //High側(i=n-1)\r
35                 db=sb=0;                \r
36                 \r
37                 double max=-1;\r
38                 double max_mt=0;\r
39                 //各ヒストグラムの分離度を計算する(1<=i<=n-1の範囲で評価)\r
40                 for(i=n-1;i>0;i--){\r
41                         //次のヒストグラムを計算\r
42                         int hist_count=hist[i];\r
43                         int hist_val=hist_count*i;\r
44                         da-=hist_val;\r
45                         sa-=hist_count;\r
46                         db+=hist_val;\r
47                         sb+=hist_count;\r
48                         \r
49                         //クラス間分散を計算\r
50                         double dv=(sa+sb);\r
51                         double mt=(double)(da+db)/dv;\r
52                         double ma=(sa!=0?((double)da/(double)sa):0)-mt;\r
53                         double mb=(sb!=0?((double)db/(double)sb):0)-mt;\r
54                         double kai=((double)(sa*(ma*ma)+sb*(mb*mb)))/dv;\r
55                         if(max<kai){\r
56                                 max_mt=mt;\r
57                                 max=kai;\r
58                                 th=i;\r
59                         }\r
60                         //System.out.println(kai);\r
61                 }\r
62                 //max_mtを元に正規化\r
63                 this._score=max/((double)(pt+max_mt*max_mt*st-2*max_mt*dt)/st);//129,0.8888888888888887\r
64                 return th;\r
65         }\r
66         /**\r
67          * 最後に実行したgetThresholdのスコアを返します。\r
68          * スコアは正規化された分離度。1.0-0.0の範囲を取る。0.7以上なら概ね双峰的です。\r
69          * @return\r
70          */\r
71         public final double getLastScore()\r
72         {\r
73                 return this._score;\r
74         }\r
75         /**\r
76          * Debug\r
77          */\r
78         public static void main(String[] args)\r
79         {\r
80                 NyARHistgram data=new NyARHistgram(256);\r
81                 for(int i=0;i<256;i++){\r
82                         data.data[i]=128-i>0?128-i:i-128;\r
83                 }\r
84                 data.total_of_data=data.getTotal(0,255);\r
85                 NyARHistgramAnalyzer_DiscriminantThreshold an=new NyARHistgramAnalyzer_DiscriminantThreshold();\r
86                 int th=an.getThreshold(data);\r
87                 System.out.print(th);\r
88                 return;\r
89         }\r
90 }\r