package jp.nyatla.nyartoolkit.dev;\r
\r
import java.awt.Frame;\r
+import java.awt.*;\r
+import java.awt.event.WindowAdapter;\r
+import java.awt.event.WindowEvent;\r
import java.io.File;\r
import java.io.FileInputStream;\r
\r
+import jp.nyatla.nyartoolkit.NyARException;\r
import jp.nyatla.nyartoolkit.core.raster.*;\r
import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_BGRA;\r
-import jp.nyatla.nyartoolkit.core.labeling.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+\r
\r
-import jp.nyatla.nyartoolkit.core2.rasteranalyzer.*;\r
import jp.nyatla.utils.j2se.*;\r
\r
public class LabelingTest extends Frame\r
{\r
- private final String data_file ="../Data/320x240ABGR.raw";\r
- public void drawImage() throws Exception\r
- {\r
- File f=new File(data_file);\r
- FileInputStream fs=new FileInputStream(data_file);\r
- byte[] buf=new byte[(int)f.length()];\r
- fs.read(buf);\r
- NyARRgbRaster_BGRA ra=NyARRgbRaster_BGRA.wrap(buf, 320, 240);\r
- NyARLabelingImage limage=new NyARLabelingImage(320,240);\r
- INyARLabeling labeling=new NyARLabeling_ARToolKit();\r
-// INyARLabeling labeling=new NyLineLabeling();\r
- INyARRasterReaderFactory rf=new NyARRasterReaderFactory_RgbTotal();\r
- labeling.attachDestination(limage);\r
- labeling.labeling(rf.createReader(ra));\r
- LabelingBufferdImage img=new LabelingBufferdImage(320,240,LabelingBufferdImage.COLOR_125_COLOR);\r
- img.setLabelingImage(limage);\r
- this.getGraphics().drawImage(img, 32,32,this);\r
- }\r
- public static void main(String[] args)\r
- {\r
- try{\r
- LabelingTest app=new LabelingTest();\r
- app.setVisible(true);\r
- app.setBounds(0,0,640,480);\r
- app.drawImage();\r
- }catch(Exception e){\r
- e.printStackTrace();\r
+ private final String data_file = "../Data/320x240ABGR.raw";\r
+\r
+ final int W=10;\r
+ final int H=10;\r
+ public void drawImage() throws Exception\r
+ {\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length()];\r
+ fs.read(buf);\r
+ NyARRgbRaster_BGRA ra = NyARRgbRaster_BGRA.wrap(buf, W, H);\r
+ // 二値化\r
+ NyARRasterFilter_ARToolkitThreshold filter = new NyARRasterFilter_ARToolkitThreshold(110, ra.getBufferReader().getBufferType());\r
+ NyARBinRaster bin = new NyARBinRaster(W,240);\r
+ filter.doFilter(ra, bin);\r
+ int[] t = (int[]) bin.getBufferReader().getBuffer();\r
+ int[] s = {\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+\r
+ 1,0,0,0,0,1,0,1,1,1,\r
+ 1,0,1,1,0,1,0,1,1,1,\r
+ 1,1,1,1,1,0,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1, 0};\r
+ System.arraycopy(s, 0, t, 0, 10*10);\r
+ NyARRasterImageIO sink = new NyARRasterImageIO(W, H);\r
+ RleImage rle = new RleImage(bin.getWidth(),bin.getHeight());\r
+ RleLabelingTable table=createRelTable(rle,bin,sink);\r
+ for(int i=0;;i++){\r
+ int nof=i%table.number_of_fragment;\r
+ if(table._fragment_area[nof]==0){\r
+ continue;\r
+ }\r
+ drawLabelingImage(nof,rle,table,bin,sink);\r
+ Graphics g;\r
+ g=this.getGraphics();\r
+ g.drawImage(sink, 100, 100,100,100, this);\r
+ Thread.sleep(500);\r
+ }\r
+ }\r
+ public void drawLabelingImage(int id,RleImage rle, RleLabelingTable i_table,NyARBinRaster i_source,NyARRasterImageIO i_img)\r
+ {\r
+// RleImage rle = new RleImage(i_source.getWidth(),i_source.getHeight());\r
+// i_table.labeling(rle,0,10);\r
+ int p=0;\r
+ for(int i=0;i<H;i++){\r
+ for(int i2=0;i2<W;i2++){\r
+ i_img.setRGB(i2,i,0xffffff);\r
+ }\r
+ for(int i2=0;i2<rle.row_length[i];i2++){\r
+ for(int i3=rle.rle_img_l[rle.row_index[i]+i2];i3<rle.rle_img_r[rle.row_index[i]+i2];i3++)\r
+ {\r
+ int c=0x0000ff;\r
+ int tid=i_table._fragment_id[i_table.rle_img_id[p]];\r
+ if(tid==id){\r
+ c=0x00ff00;\r
+ }\r
+ i_img.setRGB(i3,i,c);\r
+ }\r
+ p++;\r
+ }\r
+ }\r
+\r
+ i_img.setRGB(i_table._flagment_entry_x[id],i_table._flagment_entry_y[id],0xff0000);\r
+// i_img.setRGB(i_table._flagment_entry_x[id]+1,i_table._flagment_entry_y[id],0xff0000);\r
+// i_img.setRGB(i_table._flagment_entry_x[id],i_table._flagment_entry_y[id]+1,0xff0000);\r
+// i_img.setRGB(i_table._flagment_entry_x[id]+1,i_table._flagment_entry_y[id]+1,0xff0000);\r
+ }\r
+ \r
+ public RleLabelingTable createRelTable(RleImage rle,NyARBinRaster i_source,NyARRasterImageIO i_img)\r
+ {\r
+ // RELイメージの作成\r
+ rle.toRel(i_source);\r
+ // 1行目のテーブル登録\r
+ RleLabelingTable table = new RleLabelingTable(10000);\r
+ table.labeling(rle,0,H);\r
+ return table;\r
+ }\r
+\r
+ public LabelingTest() throws NyARException\r
+ {\r
+ this.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ LabelingTest app = new LabelingTest();\r
+ app.setVisible(true);\r
+ app.setBounds(0, 0, 640, 480);\r
+ app.drawImage();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ class RleImage\r
+ {\r
+ int _width;\r
+\r
+ int _height;\r
+\r
+ // RELデータ\r
+ short[] rle_img_l;// RELのフラグメント左\r
+\r
+ short[] rle_img_r;// RELのフラグメント右\r
+\r
+ // Rowデータ\r
+ int[] row_index;\r
+\r
+ short[] row_length;\r
+\r
+ int rle_buf_size;\r
+\r
+ public RleImage(int i_width, int i_height)\r
+ {\r
+ final int size = i_width * i_height / 2;\r
+ // 1/2に圧縮できることを想定。\r
+ this.rle_img_l = new short[size]; // RELのフラグメント長\r
+ this.rle_img_r = new short[size]; // RELの開始位置\r
+ this.rle_buf_size = size;\r
+\r
+ this.row_index = new int[i_height];\r
+ this.row_length = new short[i_height];\r
+ this._width = i_width;\r
+ this._height = i_height;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * binラスタからRELに変換する\r
+ * \r
+ * @param i_bin_raster\r
+ */\r
+ public void toRel(NyARBinRaster i_bin_raster)\r
+ {\r
+ final int width = this._width;\r
+ final int height = this._height;\r
+ int[] in_buf = (int[]) i_bin_raster.getBufferReader().getBuffer();\r
+\r
+ short current = 0;\r
+ short r = -1;\r
+ for (int y = 0; y < height; y++) {\r
+ this.row_index[y] = current;\r
+ // 行確定開始\r
+ int row_index = y * width;\r
+ int x = row_index;\r
+ final int right_edge = (y + 1) * width - 1;\r
+ while (x < right_edge) {\r
+ // 暗点(0)スキャン\r
+ if (in_buf[x] != 0) {\r
+ x++;\r
+ continue;\r
+ }\r
+ // 暗点発見→暗点長を調べる\r
+ r = (short) (x - row_index);\r
+ this.rle_img_l[current] = r;\r
+ r++;// 暗点+1\r
+ x++;\r
+ while (x < right_edge) {\r
+ if (in_buf[x] != 0) {\r
+ // 明点(1)→暗点(0)配列終了>登録\r
+ this.rle_img_r[current] = r;\r
+ current++;\r
+ x++;// 次点の確認。\r
+ r = -1;// 右端の位置を0に。\r
+ break;\r
+ } else {\r
+ // 暗点(0)長追加\r
+ r++;\r
+ x++;\r
+ }\r
+ }\r
+ }\r
+ // 最後の1点だけ判定方法が少し違うの。\r
+ if (in_buf[x] != 0) {\r
+ // 明点→rカウント中なら暗点配列終了>登録\r
+ if (r >= 0) {\r
+ this.rle_img_r[current] = r;\r
+ current++;\r
+ }\r
+ } else {\r
+ // 暗点→カウント中でなければl1で追加\r
+ if (r >= 0) {\r
+ this.rle_img_r[current] = (short) (x + 1);\r
+ } else {\r
+ // 最後の1点の場合\r
+ this.rle_img_l[current] = (short) (width - 1);\r
+ this.rle_img_r[current] = (short) (width);\r
+ }\r
+ current++;\r
+ }\r
+ // 行確定\r
+ this.row_length[y] = (short) (current - this.row_index[y]);\r
+ }\r
+ }\r
+\r
+ public void fromRel(NyARBinRaster i_bin_raster)\r
+ {\r
+\r
+ }\r
+ }\r
+\r
+ // RleImageをラベリングする。\r
+ class RleLabelingTable\r
+ {\r
+ short[] rle_img_id;\r
+\r
+ short[] _fragment_id; // フラグメントラベルのインデクス\r
+\r
+ int[] _fragment_area; // フラグメントラベルの領域数\r
+\r
+ int[] _fragment_pos_x; // フラグメントラベルの位置\r
+\r
+ int[] _fragment_pos_y; // フラグメントラベルの位置\r
+\r
+ short[] _flagment_entry_x; // フラグメントラベルの位置\r
+\r
+ short[] _flagment_entry_y; // フラグメントラベルの位置\r
+\r
+ short number_of_fragment; // 現在のフラグメントの数\r
+\r
+ public RleLabelingTable(int i_max_fragment)\r
+ {\r
+ this.rle_img_id = new short[i_max_fragment];\r
+ this._fragment_id = new short[i_max_fragment];\r
+ this._fragment_area = new int[i_max_fragment];\r
+ this._fragment_pos_x = new int[i_max_fragment];\r
+ this._fragment_pos_y = new int[i_max_fragment];\r
+ this._flagment_entry_x = new short[i_max_fragment];\r
+ this._flagment_entry_y = new short[i_max_fragment];\r
+ }\r
+\r
+ private void addFragment(RleImage i_rel_img, short i_nof, int i_row_index, int i_rel_index)\r
+ {\r
+ this.rle_img_id[i_rel_index] = i_nof;// REL毎の固有ID\r
+ this._fragment_id[i_nof] = i_nof;\r
+ this._flagment_entry_x[i_nof] = i_rel_img.rle_img_l[i_rel_index];\r
+ this._flagment_entry_y[i_nof] = (short) i_row_index;\r
+ this._fragment_area[i_nof] = i_rel_img.rle_img_r[i_rel_index] - i_rel_img.rle_img_l[i_rel_index];\r
+ return;\r
+ }\r
+\r
+\r
+\r
+ // 指定した行のフラグメントをマージします。\r
+ public void labeling(RleImage i_rel_img, int i_top, int i_bottom)\r
+ {\r
+ short[] rle_l = i_rel_img.rle_img_l;\r
+ short[] rle_r = i_rel_img.rle_img_r;\r
+ short nof = this.number_of_fragment;\r
+ // 初段登録\r
+ int index = i_rel_img.row_index[i_top];\r
+ int eol = i_rel_img.row_length[i_top];\r
+ for (int i = index; i < index + eol; i++) {\r
+ // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行\r
+ addFragment(i_rel_img, nof, i_top, i);\r
+ nof++;\r
+ // nofの最大値チェック\r
+ }\r
+ // 次段結合\r
+ for (int y = i_top+1; y < i_bottom; y++) {\r
+ int index_prev = i_rel_img.row_index[y - 1];\r
+ int eol_prev = index_prev + i_rel_img.row_length[y - 1];\r
+ index = i_rel_img.row_index[y];\r
+ eol = index + i_rel_img.row_length[y];\r
+\r
+ SCAN_CUR:for (int i = index; i < eol; i++) {\r
+ // index_prev,len_prevの位置を調整する\r
+ short id = -1;\r
+ //チェックすべきprevがあれば確認\r
+ SCAN_PREV: while (index_prev < eol_prev) {\r
+ if (rle_l[i] - rle_r[index_prev] > 0) {// 0なら8方位ラベリング\r
+ // prevがcurの左方にある→次のフラグメントを探索\r
+ index_prev++;\r
+ continue;\r
+ } else if (rle_l[index_prev] - rle_r[i] > 0) {// 0なら8方位ラベリングになる\r
+ // prevがcur右方にある→独立フラグメント\r
+ addFragment(i_rel_img, nof, y, i);\r
+ nof++;\r
+ // 次のindexをしらべる\r
+ continue SCAN_CUR;\r
+ }\r
+ // 結合対象->prevのIDをコピーして、対象フラグメントの情報を更新\r
+ id = this._fragment_id[this.rle_img_id[index_prev]];\r
+ this.rle_img_id[i] = id;\r
+ this._fragment_area[id] += (rle_r[i] - rle_l[i]);\r
+ // エントリポイントの情報をコピー\r
+ this._flagment_entry_x[id] = this._flagment_entry_x[this.rle_img_id[index_prev]];\r
+ this._flagment_entry_y[id] = this._flagment_entry_y[this.rle_img_id[index_prev]];\r
+ //多重リンクの確認\r
+\r
+ index_prev++;\r
+ while (index_prev < eol_prev) {\r
+ if (rle_l[i] - rle_r[index_prev] > 0) {// 0なら8方位ラベリング\r
+ // prevがcurの左方にある→prevはcurに連結していない。\r
+ break SCAN_PREV;\r
+ } else if (rle_l[index_prev] - rle_r[i] > 0) {// 0なら8方位ラベリングになる\r
+ // prevがcurの右方にある→prevはcurに連結していない。\r
+ index_prev--;\r
+ continue SCAN_CUR;\r
+ }\r
+ // prevとcurは連結している。\r
+ final short prev_id = this.rle_img_id[index_prev];\r
+ if (id != prev_id) {\r
+ this._fragment_area[id] += this._fragment_area[prev_id];\r
+ this._fragment_area[prev_id] = 0;\r
+ // 結合対象->現在のidをインデクスにセット\r
+ this._fragment_id[prev_id]=id;\r
+ // エントリポイントを訂正\r
+ if (this._flagment_entry_y[id] > this._flagment_entry_y[prev_id]) {\r
+ // 現在のエントリポイントの方が下にある。(何もしない)\r
+ }\r
+ if (this._flagment_entry_y[id] < this._flagment_entry_y[prev_id]) {\r
+ // 現在のエントリポイントの方が上にある。(エントリポイントの交換)\r
+ this._flagment_entry_y[id] = this._flagment_entry_y[prev_id];\r
+ this._flagment_entry_x[id] = this._flagment_entry_x[prev_id];\r
+ } else {\r
+ // 水平方向で小さい方がエントリポイント。\r
+ if (this._flagment_entry_x[id] > this._flagment_entry_x[prev_id]) {\r
+ this._flagment_entry_y[id] = this._flagment_entry_y[prev_id];\r
+ this._flagment_entry_x[id] = this._flagment_entry_x[prev_id];\r
+ }\r
+ }\r
+ }\r
+ index_prev++;\r
+ }\r
+ index_prev--;\r
+ break;\r
+ }\r
+ // curにidが割り当てられたかを確認\r
+ // 右端独立フラグメントを追加\r
+ if (id < 0) {\r
+ addFragment(i_rel_img, nof, y, i);\r
+ nof++;\r
+ }\r
+\r
+ }\r
+ }\r
+ // フラグメントの数を更新\r
+ this.number_of_fragment = nof;\r
+ }\r
}\r
- }\r
}\r
+\r
+// REL圧縮配列を作成\r
+// REL結合\r
+// 面積計算\r
+// 参照インデクス化\r
+// ラベルイメージ化\r