*/\r
public class NyARSquareDetector_X2 implements INyARSquareDetector\r
{\r
- private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
-\r
- private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
private final int _width;\r
private final int _height;\r
\r
{\r
this._width = i_size.w;\r
this._height = i_size.h;\r
- this._labeling = new NyARLabeling_Rle(this._width);\r
+ this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
this._sqconvertor=new SquareContourDetector_X2(i_size,i_dist_factor_ref);\r
this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
\r
if (label_num < 1) {\r
return;\r
}\r
-\r
+ //ラベルをソートしておく\r
+ flagment.sortByArea();\r
RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
\r
- // デカいラベルを読み飛ばし\r
- int i;\r
- for (i = 0; i < label_num; i++) {\r
- // 検査対象内のラベルサイズになるまで無視\r
- if (labels[i].area <= AR_AREA_MAX) {\r
- break;\r
- }\r
- }\r
\r
final int xsize = this._width;\r
final int ysize = this._height;\r
//重なりチェッカの最大数を設定\r
overlap.setMaxLabels(label_num);\r
\r
- for (; i < label_num; i++) {\r
+ for (int i=0; i < label_num; i++) {\r
final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
final int label_area = label_pt.area;\r
- // 検査対象サイズよりも小さくなったら終了\r
- if (label_pt.area < AR_AREA_MIN) {\r
- break;\r
- }\r
- \r
+\r
// クリップ領域が画面の枠に接していれば除外\r
if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
continue;\r
\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.utils.*;\r
\r
+class RleInfoStack extends NyObjectStack<RleInfoStack.RleInfo>\r
+{\r
+ public class RleInfo\r
+ {\r
+ //継承メンバ\r
+ public int entry_x; // フラグメントラベルの位置\r
+ public int area;\r
+ public int clip_r;\r
+ public int clip_l;\r
+ public int clip_b;\r
+ public int clip_t;\r
+ public long pos_x;\r
+ public long pos_y; \r
+ } \r
+ public RleInfoStack(int i_length)\r
+ {\r
+ super(i_length, RleInfoStack.RleInfo.class);\r
+ return;\r
+ }\r
\r
-\r
+ protected RleInfoStack.RleInfo createElement()\r
+ {\r
+ return new RleInfoStack.RleInfo();\r
+ }\r
+}\r
/**\r
* [strage class]\r
*/\r
// RleImageをラベリングする。\r
public class NyARLabeling_Rle\r
{\r
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+ \r
+ private RleInfoStack _rlestack;\r
private RleElement[] _rle1;\r
-\r
private RleElement[] _rle2;\r
+ private int _max_area;\r
+ private int _min_area;\r
\r
- public NyARLabeling_Rle(int i_width)\r
+ public NyARLabeling_Rle(int i_width,int i_height)\r
{\r
+ this._rlestack=new RleInfoStack(i_width*i_height*2048/(320*240)+32);\r
this._rle1 = RleElement.createArray(i_width/2+1);\r
this._rle2 = RleElement.createArray(i_width/2+1);\r
+ setAreaRange(AR_AREA_MAX,AR_AREA_MIN);\r
+\r
+ return;\r
+ }\r
+ /**\r
+ * 対象サイズ\r
+ * @param i_max\r
+ * @param i_min\r
+ */\r
+ public void setAreaRange(int i_max,int i_min)\r
+ {\r
+ this._max_area=i_max;\r
+ this._min_area=i_min;\r
return;\r
}\r
\r
return current;\r
}\r
\r
- private void addFragment(RleElement i_rel_img, int i_nof, int i_row_index, int i_rel_index,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+ private void addFragment(RleElement i_rel_img, int i_nof, int i_row_index, int i_rel_index,RleInfoStack o_stack) throws NyARException\r
{\r
int l=i_rel_img.l;\r
final int len=i_rel_img.r - l;\r
i_rel_img.fid = i_nof;// REL毎の固有ID\r
- RleLabelFragmentInfoStack.RleLabelFragmentInfo v = o_stack.prePush();\r
+ RleInfoStack.RleInfo v = o_stack.prePush();\r
v.entry_x = l;\r
v.area =len;\r
v.clip_l=l;\r
public int labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
{\r
// リセット処理\r
- o_stack.clear();\r
+ final RleInfoStack rlestack=this._rlestack;\r
+ rlestack.clear();\r
+\r
//\r
RleElement[] rle_prev = this._rle1;\r
RleElement[] rle_current = this._rle2;\r
len_prev = toRel(in_buf, i_top, width, rle_prev);\r
for (int i = 0; i < len_prev; i++) {\r
// フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行\r
- addFragment(rle_prev[i], id_max, i_top, i,o_stack);\r
+ addFragment(rle_prev[i], id_max, i_top, i,rlestack);\r
id_max++;\r
// nofの最大値チェック\r
label_count++;\r
}\r
- RleLabelFragmentInfoStack.RleLabelFragmentInfo[] f_array = o_stack.getArray();\r
+ RleInfoStack.RleInfo[] f_array = rlestack.getArray();\r
// 次段結合\r
for (int y = i_top + 1; y < i_bottom; y++) {\r
// カレント行の読込\r
continue;\r
} else if (rle_prev[index_prev].l - rle_current[i].r > 0) {// 0なら8方位ラベリングになる\r
// prevがcur右方にある→独立フラグメント\r
- addFragment(rle_current[i], id_max, y, i,o_stack);\r
+ addFragment(rle_current[i], id_max, y, i,rlestack);\r
id_max++;\r
label_count++;\r
// 次のindexをしらべる\r
continue SCAN_CUR;\r
}\r
id=rle_prev[index_prev].fid;//ルートフラグメントid\r
- RleLabelFragmentInfoStack.RleLabelFragmentInfo id_ptr = f_array[id];\r
+ RleInfoStack.RleInfo id_ptr = f_array[id];\r
//結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新\r
rle_current[i].fid = id;//フラグメントIDを保存\r
//\r
\r
//結合するルートフラグメントを取得\r
final int prev_id =rle_prev[index_prev].fid;\r
- RleLabelFragmentInfoStack.RleLabelFragmentInfo prev_ptr = f_array[prev_id];\r
+ RleInfoStack.RleInfo prev_ptr = f_array[prev_id];\r
if (id != prev_id){\r
label_count--;\r
//prevとcurrentのフラグメントidを書き換える。\r
// curにidが割り当てられたかを確認\r
// 右端独立フラグメントを追加\r
if (id < 0){\r
- addFragment(rle_current[i], id_max, y, i,o_stack);\r
+ addFragment(rle_current[i], id_max, y, i,rlestack);\r
id_max++;\r
label_count++;\r
}\r
len_prev = len_current;\r
rle_current = tmp;\r
}\r
- //ソートする。\r
- o_stack.sortByArea();\r
- //ラベル数を再設定\r
+ //対象のラベルだけ転写\r
o_stack.reserv(label_count);\r
- //posを計算\r
- for(int i=0;i<label_count;i++){\r
- final RleLabelFragmentInfoStack.RleLabelFragmentInfo tmp=f_array[i];\r
- tmp.pos_x/=tmp.area;\r
- tmp.pos_y/=tmp.area;\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo[] o_dest_array=o_stack.getArray();\r
+ final int max=this._max_area;\r
+ final int min=this._min_area;\r
+ int active_labels=0;\r
+ for(int i=id_max-1;i>=0;i--){\r
+ final int area=f_array[i].area;\r
+ if(area<min || area>max){//対象外のエリア0のもminではじく\r
+ continue;\r
+ }\r
+ //\r
+ final RleInfoStack.RleInfo src_info=f_array[i];\r
+ final RleLabelFragmentInfoStack.RleLabelFragmentInfo dest_info=o_dest_array[active_labels];\r
+ dest_info.area=area;\r
+ dest_info.clip_b=src_info.clip_b;\r
+ dest_info.clip_r=src_info.clip_r;\r
+ dest_info.clip_t=src_info.clip_t;\r
+ dest_info.clip_l=src_info.clip_l;\r
+ dest_info.entry_x=src_info.entry_x;\r
+ dest_info.pos_x=src_info.pos_x/src_info.area;\r
+ dest_info.pos_y=src_info.pos_y/src_info.area;\r
+ active_labels++;\r
}\r
+ //ラベル数を再設定\r
+ o_stack.pops(label_count-active_labels);\r
//ラベル数を返却\r
- return label_count;\r
+ return active_labels;\r
} \r
}\r
\r
{\r
this._width = i_size.w;\r
this._height = i_size.h;\r
- //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。\r
- //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
- this._labeling = new NyARLabeling_Rle(this._width);\r
+ //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
+ this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
+ this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN);\r
this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
\r
// マーカーホルダをリセット\r
o_square_stack.clear();\r
\r
- // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
+ // ラベル数が0ならここまで\r
final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
if (label_num < 1) {\r
return;\r
}\r
- // ラベルを大きい順に整列\r
+ //ラベルをソートしておく\r
+ flagment.sortByArea();\r
+ //ラベルリストを取得\r
RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
\r
- // デカいラベルを読み飛ばし\r
- int i;\r
- for (i = 0; i < label_num; i++) {\r
- // 検査対象内のラベルサイズになるまで無視\r
- if (labels[i].area <= AR_AREA_MAX) {\r
- break;\r
- }\r
- }\r
-\r
final int xsize = this._width;\r
final int ysize = this._height;\r
final int[] xcoord = this._xcoord;\r
final int[] ycoord = this._ycoord;\r
final int coord_max = this._max_coord;\r
\r
+\r
//重なりチェッカの最大数を設定\r
overlap.setMaxLabels(label_num);\r
\r
- for (; i < label_num; i++) {\r
+ for (int i=0; i < label_num; i++) {\r
final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
final int label_area = label_pt.area;\r
- // 検査対象サイズよりも小さくなったら終了\r
- if (label_pt.area < AR_AREA_MIN) {\r
- break;\r
- }\r
\r
// クリップ領域が画面の枠に接していれば除外\r
if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r