* <airmail(at)ebony.plala.or.jp>\r
* \r
*/\r
-package jp.nyatla.nyartoolkit.core.squaredetect;\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
\r
-import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
+import java.lang.reflect.Array;\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
\r
/**\r
* ラベル同士の重なり(内包関係)を調べるクラスです。 \r
* ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。\r
*/\r
-public class LabelOverlapChecker\r
+public class LabelOverlapChecker<T extends NyARLabelInfo>\r
{\r
- private NyARLabelingLabel[] _labels = new NyARLabelingLabel[32];\r
+ private T[] _labels;\r
private int _length;\r
- public LabelOverlapChecker(int i_max_label)\r
+ private Class<T> _element_type;\r
+ /*\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public LabelOverlapChecker(int i_max_label,Class<T> i_element_type)\r
{\r
- this._labels = new NyARLabelingLabel[i_max_label];\r
+ this._element_type=i_element_type;\r
+ this._labels = (T[])Array.newInstance(i_element_type, 32);\r
}\r
\r
/**\r
* \r
* @param i_label_ref\r
*/\r
- public void push(NyARLabelingLabel i_label_ref)\r
+ public void push(T i_label_ref)\r
{\r
this._labels[this._length] = i_label_ref;\r
this._length++;\r
* @param i_label\r
* @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.\r
*/\r
- public boolean check(NyARLabelingLabel i_label)\r
+ public boolean check(T i_label)\r
{\r
// 重なり処理かな?\r
- final NyARLabelingLabel[] label_pt = this._labels;\r
+ final T[] label_pt = this._labels;\r
final int px1 = (int) i_label.pos_x;\r
final int py1 = (int) i_label.pos_y;\r
for (int i = this._length - 1; i >= 0; i--) {\r
* \r
* @param i_max_label\r
*/\r
- public void setMaxlabel(int i_max_label)\r
+ @SuppressWarnings("unchecked")\r
+ public void setMaxLabels(int i_max_label)\r
{\r
if (i_max_label > this._labels.length) {\r
- this._labels = new NyARLabelingLabel[i_max_label];\r
+ this._labels = (T[])Array.newInstance(this._element_type, i_max_label);\r
}\r
this._length = 0;\r
} \r
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
package jp.nyatla.nyartoolkit.core.labeling;\r
\r
/**\r
public class NyARLabelInfo\r
{\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 double pos_x;\r
+ public double pos_y;\r
}\r
final public void sortByArea()\r
{\r
int len=this._length;\r
+ if(len<1){\r
+ return;\r
+ }\r
int h = len *13/10;\r
T[] item=this._items;\r
for(;;){\r
h=h*10/13;\r
}\r
} \r
- } \r
+ }\r
}\r
\r
*/\r
public class NyARLabelingLabel extends NyARLabelInfo\r
{\r
- public int id;\r
- public int clip_r;// 0\r
- public int clip_l;// 1\r
- public int clip_b;// 2\r
- public int clip_t;// 3\r
- public double pos_x;\r
- public double pos_y;\r
+ public int id; // フラグメントラベルのインデクス\r
+\r
}\r
* @param i_raster\r
* @throws NyARException\r
*/\r
- public void labeling(NyARBinRaster i_raster,NyARLabelingImage o_destination) throws NyARException\r
+ public int labeling(NyARBinRaster i_raster,NyARLabelingImage o_destination) throws NyARException\r
{\r
int label_img_ptr1, label_pixel;\r
int i, j;\r
if (wlabel_num == 0) {// if( *label_num == 0 ) {\r
// 発見数0\r
o_destination.getLabelStack().clear();\r
- return;\r
+ return 0;\r
}\r
// ラベル情報の保存等\r
NyARLabelingLabelStack label_list = o_destination.getLabelStack();\r
NyARLabelingLabel[] labels =label_list.getArray();\r
for (i = 0; i < wlabel_num; i++) {\r
label_pt = labels[i];\r
- label_pt.id = i + 1;\r
+ label_pt.id = (short)(i + 1);\r
label_pt.area = 0;\r
label_pt.pos_x = label_pt.pos_y = 0;\r
label_pt.clip_l = lxsize;// wclip[i*4+0] = lxsize;\r
label_pt.pos_x /= label_pt.area;\r
label_pt.pos_y /= label_pt.area;\r
}\r
- return;\r
+ // ラベルを大きい順に整列\r
+ label_list.sortByArea(); \r
+ return wlabel_num;\r
}\r
\r
}\r
{\r
int l;\r
int r;\r
- short id;\r
+ int fid;\r
public static RleElement[] createArray(int i_length)\r
{\r
RleElement[] ret = new RleElement[i_length];\r
\r
private RleElement[] _rle2;\r
\r
- private short number_of_fragment; // 現在のフラグメントの数\r
-\r
public NyARLabeling_Rle(int i_width)\r
{\r
this._rle1 = RleElement.createArray(i_width/2+1);\r
i_out[current].r = (r + 1);\r
} else {\r
// 最後の1点の場合\r
- i_out[current].l = (i_st + i_len - 1);\r
- i_out[current].r = (i_st + i_len);\r
+ i_out[current].l = (i_len - 1);\r
+ i_out[current].r = (i_len);\r
}\r
current++;\r
}\r
return current;\r
}\r
\r
- private void addFragment(RleElement i_rel_img, short 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,RleLabelFragmentInfoStack 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.id = i_nof;// REL毎の固有ID\r
+ i_rel_img.fid = i_nof;// REL毎の固有ID\r
RleLabelFragmentInfoStack.RleLabelFragmentInfo v = o_stack.prePush();\r
- v.id = i_nof;\r
v.entry_x = l;\r
v.area =len;\r
v.clip_l=l;\r
- v.clip_r=i_rel_img.r;\r
+ v.clip_r=i_rel_img.r-1;\r
v.clip_t=i_row_index;\r
v.clip_b=i_row_index;\r
- v.pos_x+=len*(2*l+(len-1)*1);\r
+ v.pos_x+=(len*(2*l+(len-1)))/2;\r
v.pos_y+=i_row_index*len;\r
\r
- \r
return;\r
}\r
\r
//\r
- public void labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+ public int labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
{\r
// リセット処理\r
- this.number_of_fragment = 0;\r
o_stack.clear();\r
//\r
RleElement[] rle_prev = this._rle1;\r
final int width = i_bin_raster.getWidth();\r
int[] in_buf = (int[]) i_bin_raster.getBufferReader().getBuffer();\r
\r
- short nof = this.number_of_fragment;\r
+ int id_max = 0;\r
+ int label_count=0;\r
// 初段登録\r
\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], nof, i_top, i,o_stack);\r
- nof++;\r
+ addFragment(rle_prev[i], id_max, i_top, i,o_stack);\r
+ id_max++;\r
// nofの最大値チェック\r
+ label_count++;\r
}\r
RleLabelFragmentInfoStack.RleLabelFragmentInfo[] f_array = o_stack.getArray();\r
// 次段結合\r
\r
SCAN_CUR: for (int i = 0; i < len_current; i++) {\r
// index_prev,len_prevの位置を調整する\r
- short id = -1;\r
+ int id = -1;\r
// チェックすべきprevがあれば確認\r
SCAN_PREV: while (index_prev < len_prev) {\r
if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\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], nof, y, i,o_stack);\r
- nof++;\r
+ addFragment(rle_current[i], id_max, y, i,o_stack);\r
+ id_max++;\r
+ label_count++;\r
// 次のindexをしらべる\r
continue SCAN_CUR;\r
}\r
- // 結合対象->prevのIDをコピーして、対象フラグメントの情報を更新\r
- id = f_array[rle_prev[index_prev].id].id;\r
- RleLabelFragmentInfoStack.RleLabelFragmentInfo prev_ptr;\r
- final RleLabelFragmentInfoStack.RleLabelFragmentInfo id_ptr = f_array[id];\r
- prev_ptr = f_array[rle_prev[index_prev].id];\r
- rle_current[i].id = id;\r
+ id=rle_prev[index_prev].fid;//ルートフラグメントid\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo id_ptr = f_array[id];\r
+ //結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新\r
+ rle_current[i].fid = id;//フラグメントIDを保存\r
//\r
final int l= rle_current[i].l;\r
final int r= rle_current[i].r;\r
- final int len=rle_current[i].r - rle_current[i].l;\r
+ final int len=r-l;\r
+ //結合先フラグメントの情報を更新する。\r
id_ptr.area += len;\r
- id_ptr.entry_x = prev_ptr.entry_x;\r
- id_ptr.clip_l=l<prev_ptr.clip_l?l:prev_ptr.clip_l;\r
- id_ptr.clip_r=r>prev_ptr.clip_r?r:prev_ptr.clip_r;\r
- //id_ptr.clip_tは変更無し。\r
+ //tとentry_xは、結合先のを使うので更新しない。\r
+ id_ptr.clip_l=l<id_ptr.clip_l?l:id_ptr.clip_l;\r
+ id_ptr.clip_r=r>id_ptr.clip_r?r-1:id_ptr.clip_r;\r
id_ptr.clip_b=y;\r
- id_ptr.pos_x+=len*(2*l+(len-1)*1);\r
+ id_ptr.pos_x+=(len*(2*l+(len-1)))/2;\r
id_ptr.pos_y+=y*len;\r
- // 多重リンクの確認\r
-\r
+ //多重結合の確認(2個目以降)\r
index_prev++;\r
while (index_prev < len_prev) {\r
if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
index_prev--;\r
continue SCAN_CUR;\r
}\r
- // prevとcurは連結している。\r
- final short prev_id = rle_prev[index_prev].id;\r
- prev_ptr = f_array[prev_id];\r
- if (id != prev_id) {\r
- id_ptr.area += prev_ptr.area;\r
- prev_ptr.area = 0;\r
- // 結合対象->現在のidをインデクスにセット\r
- prev_ptr.id = id;\r
+ // prevとcurは連結している→ルートフラグメントの統合\r
+ \r
+ //結合するルートフラグメントを取得\r
+ final int prev_id =rle_prev[index_prev].fid;\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo prev_ptr = f_array[prev_id];\r
+ if (id != prev_id){\r
+ if(prev_ptr.area==0){\r
+ System.out.println("ERRRR");\r
+ }\r
+ label_count--;\r
+ //prevとcurrentのフラグメントidを書き換える。\r
+ for(int i2=index_prev;i2<len_prev;i2++){\r
+ //prevは現在のidから最後まで\r
+ if(rle_prev[i2].fid==prev_id){\r
+ rle_prev[i2].fid=id;\r
+ }\r
+ }\r
+ for(int i2=0;i2<i;i2++){\r
+ //currentは0から現在-1まで\r
+ if(rle_current[i2].fid==prev_id){\r
+ rle_current[i2].fid=id;\r
+ }\r
+ }\r
+ \r
+ //現在のルートフラグメントに情報を集約\r
+ id_ptr.area +=prev_ptr.area;\r
+ id_ptr.pos_x+=prev_ptr.pos_x;\r
+ id_ptr.pos_y+=prev_ptr.pos_y;\r
//tとentry_xの決定\r
if (id_ptr.clip_t > prev_ptr.clip_t) {\r
// 現在の方が下にある。\r
id_ptr.clip_t = prev_ptr.clip_t;\r
id_ptr.entry_x = prev_ptr.entry_x;\r
}else if (id_ptr.clip_t < prev_ptr.clip_t) {\r
- // 現在の方が上にある。なにもしない。\r
+ // 現在の方が上にある。prevにフィードバック\r
} else {\r
// 水平方向で小さい方がエントリポイント。\r
if (id_ptr.entry_x > prev_ptr.entry_x) {\r
id_ptr.entry_x = prev_ptr.entry_x;\r
+ }else{\r
}\r
- } \r
- //bの決定(現状のまま)\r
+ }\r
//lの決定\r
if (id_ptr.clip_l > prev_ptr.clip_l) {\r
id_ptr.clip_l=prev_ptr.clip_l;\r
+ }else{\r
}\r
//rの決定\r
if (id_ptr.clip_r < prev_ptr.clip_r) {\r
id_ptr.clip_r=prev_ptr.clip_r;\r
+ }else{\r
}\r
- id_ptr.pos_x+=prev_ptr.pos_x;\r
- id_ptr.pos_y+=prev_ptr.pos_y; \r
- \r
+ //bの決定\r
\r
+ //結合済のルートフラグメントを無効化する。\r
+ prev_ptr.area=0;\r
}\r
+\r
+\r
index_prev++;\r
}\r
index_prev--;\r
}\r
// curにidが割り当てられたかを確認\r
// 右端独立フラグメントを追加\r
- if (id < 0) {\r
- addFragment(rle_current[i], nof, y, i,o_stack);\r
- nof++;\r
+ if (id < 0){\r
+ addFragment(rle_current[i], id_max, y, i,o_stack);\r
+ id_max++;\r
+ label_count++;\r
}\r
}\r
// prevとrelの交換\r
len_prev = len_current;\r
rle_current = tmp;\r
}\r
- // フラグメントの数を更新\r
- this.number_of_fragment = nof;\r
+ //ソートする。\r
+ o_stack.sortByArea();\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
+ }\r
+ //ラベル数を返却\r
+ return label_count;\r
} \r
}\r
\r
{\r
//継承メンバ\r
//int area; // フラグメントラベルの領域数\r
- public short id; // フラグメントラベルのインデクス\r
public int entry_x; // フラグメントラベルの位置\r
- public int clip_t;\r
- public int clip_l;\r
- public int clip_r;\r
- public int clip_b;\r
- public double pos_x;\r
- public double pos_y;\r
} \r
public RleLabelFragmentInfoStack(int i_length)\r
{\r
}\r
public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
{\r
- NyARException.notImplement(); \r
+ final byte[] ref_buf = this._parent._ref_buf;\r
+ final int bp = (i_x + i_y * this._parent._size.w) * 4;\r
+ ref_buf[bp+0] = (byte)i_rgb[0];// R\r
+ ref_buf[bp+1] = (byte)i_rgb[1];// G\r
+ ref_buf[bp+2] = (byte)i_rgb[2];// B \r
}\r
public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
{\r
package jp.nyatla.nyartoolkit.core.squaredetect;\r
-\r
+/*\r
+import java.awt.color.ColorSpace;\r
+import java.awt.image.BufferedImage;\r
+import java.io.*;\r
+import javax.imageio.*;\r
+import jp.nyatla.utils.j2se.*;*/\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
final int width=i_raster.getWidth();\r
final int height=i_raster.getHeight();\r
//クリップ領域の上端に接しているポイントを得る。\r
- int sx=i_entry_x;\r
- int sy=i_entry_y;\r
+\r
\r
int coord_num = 1;\r
- o_coord_x[0] = sx;\r
- o_coord_y[0] = sy;\r
+ o_coord_x[0] = i_entry_x;\r
+ o_coord_y[0] = i_entry_y;\r
int dir = 5;\r
\r
- int c = o_coord_x[0];\r
- int r = o_coord_y[0];\r
+ int c = i_entry_x;\r
+ int r = i_entry_y;\r
for (;;) {\r
dir = (dir + 5) % 8;//dirの正規化\r
//ここは頑張ればもっと最適化できると思うよ。\r
if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
break;\r
}\r
+/*\r
+ try{\r
+ BufferedImage b=new BufferedImage(width,height,ColorSpace.TYPE_RGB);\r
+ NyARRasterImageIO.copy(i_raster, b);\r
+ ImageIO.write(b,"png",new File("bug.png"));\r
+ }catch(Exception e){\r
+ \r
+ }*/\r
//8方向全て調べたけどラベルが無いよ?\r
throw new NyARException(); \r
}\r
}else{\r
- //境界に接しているとき\r
+ //境界に接しているとき \r
int i;\r
for (i = 0; i < 8; i++){ \r
final int x=c + xdir[dir];\r
o_coord_x[coord_num] = c;\r
o_coord_y[coord_num] = r;\r
// 終了条件判定\r
- if (c == sx && r == sy){\r
+ if (c == i_entry_x && r == i_entry_y){\r
coord_num++;\r
break;\r
}\r
}\r
}\r
return coord_num;\r
- } \r
+ }\r
\r
}\r
import jp.nyatla.nyartoolkit.core.INyARSquareDetector;\r
import jp.nyatla.nyartoolkit.core.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
\r
private final NyARLabelingImage _limage;\r
\r
- private final LabelOverlapChecker _overlap_checker = new LabelOverlapChecker(32);\r
+ private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
private final SquareContourDetector _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
\r
// マーカーホルダをリセット\r
o_square_stack.clear();\r
\r
- // ラベリング\r
- this._labeling.labeling(i_raster,this._limage);\r
-\r
- // ラベル数が0ならここまで\r
- final int label_num = limage.getLabelStack().getLength();\r
+ // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
+ final int label_num = this._labeling.labeling(i_raster,this._limage);\r
if (label_num < 1) {\r
return;\r
}\r
\r
final NyARLabelingLabelStack stack = limage.getLabelStack();\r
final NyARLabelingLabel[] labels = stack.getArray();\r
- \r
- \r
- // ラベルを大きい順に整列\r
- stack.sortByArea();\r
\r
// デカいラベルを読み飛ばし\r
int i;\r
final int[] xcoord = this._xcoord;\r
final int[] ycoord = this._ycoord;\r
final int coord_max = this._max_coord;\r
- final LabelOverlapChecker overlap = this._overlap_checker;\r
- int coord_num;\r
- int label_area;\r
- NyARLabelingLabel label_pt;\r
+ final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
\r
//重なりチェッカの最大数を設定\r
- overlap.setMaxlabel(label_num);\r
+ overlap.setMaxLabels(label_num);\r
\r
for (; i < label_num; i++) {\r
- label_pt = labels[i];\r
- label_area = label_pt.area;\r
+ final NyARLabelingLabel label_pt = labels[i];\r
+ final int label_area = label_pt.area;\r
// 検査対象サイズよりも小さくなったら終了\r
if (label_area < AR_AREA_MIN) {\r
break;\r
continue;\r
}\r
// 輪郭を取得\r
- coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
if (coord_num == coord_max) {\r
// 輪郭が大きすぎる。\r
continue;\r
}\r
// 検出済の矩形の属したラベルを重なりチェックに追加する。\r
overlap.push(label_pt);\r
- } \r
+ }\r
return;\r
}\r
\r
package jp.nyatla.nyartoolkit.core.squaredetect;\r
\r
\r
+import java.util.Date;\r
+\r
import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.INyARSquareDetector;\r
import jp.nyatla.nyartoolkit.core.NyARSquare;\r
import jp.nyatla.nyartoolkit.core.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
\r
private final NyARLabeling_Rle _labeling;\r
\r
- private final LabelOverlapChecker _overlap_checker = new LabelOverlapChecker(32);\r
+ private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
private final SquareContourDetector _sqconvertor;\r
private final ContourPickup _cpickup=new ContourPickup();\r
private final RleLabelFragmentInfoStack _stack;\r
\r
private final int _max_coord;\r
private final int[] _xcoord;\r
- private final int[] _ycoord; \r
+ private final int[] _ycoord;\r
/**\r
* 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
* \r
//領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
this._labeling = new NyARLabeling_Rle(this._width);\r
this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
- this._stack=new RleLabelFragmentInfoStack(1024);//検出可能な最大ラベル数\r
+ this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
\r
\r
// 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
{\r
final RleLabelFragmentInfoStack flagment=this._stack;\r
+ final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
\r
// マーカーホルダをリセット\r
o_square_stack.clear();\r
\r
- // ラベリング\r
- this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
-\r
- // ラベル数が0ならここまで\r
- final int label_num = flagment.getLength();\r
+ // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\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
// ラベルを大きい順に整列\r
- flagment.sortByArea();\r
RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
\r
// デカいラベルを読み飛ばし\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
- int coord_num;\r
- int label_area;\r
\r
//重なりチェッカの最大数を設定\r
-// overlap.setMaxlabel(label_num);\r
+ overlap.setMaxLabels(label_num);\r
\r
for (; i < label_num; i++) {\r
final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
- label_area = label_pt.area;\r
+ final int label_area = label_pt.area;\r
// 検査対象サイズよりも小さくなったら終了\r
- if (label_area < AR_AREA_MIN) {\r
+ if (label_pt.area < AR_AREA_MIN) {\r
break;\r
}\r
-// // クリップ領域が画面の枠に接していれば除外\r
-// if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
-// continue;\r
-// }\r
-// if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
-// continue;\r
-// }\r
-// // 既に検出された矩形との重なりを確認\r
-// if (!overlap.check(label_pt)) {\r
-// // 重なっているようだ。\r
-// continue;\r
-// }\r
+ \r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ \r
// 輪郭を取得\r
- coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ final int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
if (coord_num == coord_max) {\r
// 輪郭が大きすぎる。\r
continue;\r
continue; \r
}\r
// 検出済の矩形の属したラベルを重なりチェックに追加する。\r
-// overlap.push(label_pt);\r
- } \r
+ overlap.push(label_pt);\r
+ }\r
return;\r
}\r
+ /**\r
+ * デバック用API\r
+ * @return\r
+ */\r
+ public RleLabelFragmentInfoStack _getFragmentStack()\r
+ {\r
+ return this._stack;\r
+ }\r
\r
}\r
\r
+++ /dev/null
-package jp.nyatla.utils.j2se;\r
-\r
-import java.awt.Color;\r
-import java.awt.image.*;\r
-import jp.nyatla.nyartoolkit.*;\r
-import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
-import jp.nyatla.nyartoolkit.core.raster.*;\r
-import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
-\r
-public class BufferedImageSink extends BufferedImage\r
-{\r
- public BufferedImageSink(int i_width,int i_height)\r
- {\r
- super(i_width,i_height,TYPE_INT_RGB);\r
- }\r
- /**\r
- * i_inの内容を、このイメージにコピーします。\r
- * @param i_in\r
- * @throws NyARException\r
- */\r
- public void copyFromRaster(INyARRgbRaster i_in) throws NyARException\r
- {\r
- assert i_in.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
- \r
- //thisへ転写\r
- INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
- int[] rgb=new int[3];\r
-\r
- for(int y=this.getHeight()-1;y>=0;y--){\r
- for(int x=this.getWidth()-1;x>=0;x--){\r
- reader.getPixel(x,y,rgb);\r
- this.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
- }\r
- }\r
- return;\r
- }\r
- /**\r
- * BIN_8用\r
- * @param i_in\r
- * @throws NyARException\r
- */\r
- public void copyFromRaster(INyARRaster i_in) throws NyARException\r
- {\r
- assert i_in.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
- if(i_in.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
- {\r
- final int[] buf=(int[])i_in.getBufferReader().getBuffer();\r
- final int w=this.getWidth();\r
- final int h=this.getHeight();\r
- for(int y=h-1;y>=0;y--){\r
- for(int x=w-1;x>=0;x--){\r
- this.setRGB(x, y,buf[x+y*w]==0?0:0xffffff);\r
- }\r
- }\r
- }\r
- return;\r
- } \r
- /**\r
- * i_outへこのイメージを出力します。\r
- * \r
- * @param i_out\r
- * @throws NyARException\r
- */\r
- public void copyToRaster(INyARRgbRaster i_out) throws NyARException\r
- {\r
- assert i_out.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
- \r
- //thisへ転写\r
- INyARRgbPixelReader reader=i_out.getRgbPixelReader();\r
- int[] rgb=new int[3];\r
- for(int y=this.getHeight()-1;y>=0;y--){\r
- for(int x=this.getWidth()-1;x>=0;x--){\r
- int pix=this.getRGB(x, y);\r
- rgb[0]=(pix>>16)&0xff;\r
- rgb[1]=(pix>>8)&0xff;\r
- rgb[2]=(pix)&0xff;\r
- reader.setPixel(x,y,rgb);\r
- }\r
- }\r
- return;\r
- }\r
-}\r
--- /dev/null
+package jp.nyatla.utils.j2se;\r
+\r
+import java.awt.image.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+public class NyARRasterImageIO\r
+{\r
+ /**\r
+ * i_inの内容を、このイメージにコピーします。\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(INyARRgbRaster i_in,BufferedImage o_out) throws NyARException\r
+ {\r
+ assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+ \r
+ //thisへ転写\r
+ INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
+ int[] rgb=new int[3];\r
+\r
+ for(int y=o_out.getHeight()-1;y>=0;y--){\r
+ for(int x=o_out.getWidth()-1;x>=0;x--){\r
+ reader.getPixel(x,y,rgb);\r
+ o_out.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * BIN_8用\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(INyARRaster i_in,BufferedImage o_out) throws NyARException\r
+ {\r
+ assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+ if(i_in.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
+ {\r
+ final int[] buf=(int[])i_in.getBufferReader().getBuffer();\r
+ final int w=o_out.getWidth();\r
+ final int h=o_out.getHeight();\r
+ for(int y=h-1;y>=0;y--){\r
+ for(int x=w-1;x>=0;x--){\r
+ o_out.setRGB(x, y,buf[x+y*w]==0?0:0xffffff);\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ /**\r
+ * i_outへこのイメージを出力します。\r
+ * \r
+ * @param i_out\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(BufferedImage i_in,INyARRgbRaster o_out) throws NyARException\r
+ {\r
+ assert o_out.getSize().isEqualSize(i_in.getWidth(), i_in.getHeight());\r
+ \r
+ //thisへ転写\r
+ INyARRgbPixelReader reader=o_out.getRgbPixelReader();\r
+ int[] rgb=new int[3];\r
+ for(int y=i_in.getHeight()-1;y>=0;y--){\r
+ for(int x=i_in.getWidth()-1;x>=0;x--){\r
+ int pix=i_in.getRGB(x, y);\r
+ rgb[0]=(pix>>16)&0xff;\r
+ rgb[1]=(pix>>8)&0xff;\r
+ rgb[2]=(pix)&0xff;\r
+ reader.setPixel(x,y,rgb);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * BIN_8用\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(BufferedImage i_in,INyARRaster o_out) throws NyARException\r
+ {\r
+ assert o_out.getSize().isEqualSize(i_in.getWidth(), i_in.getHeight());\r
+ if(o_out.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
+ {\r
+ final int[] buf=(int[])o_out.getBufferReader().getBuffer();\r
+ final int w=i_in.getWidth();\r
+ final int h=i_in.getHeight();\r
+ for(int y=h-1;y>=0;y--){\r
+ for(int x=w-1;x>=0;x--){\r
+ buf[x+y*w]=(i_in.getRGB(x, y)&0xffffff)>0?1:0;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ } \r
+}\r