5 package jp.nyatla.nyartoolkit.dev;
\r
8 import java.awt.event.WindowAdapter;
\r
9 import java.awt.event.WindowEvent;
\r
10 import java.io.File;
\r
11 import java.io.FileInputStream;
\r
13 import jp.nyatla.nyartoolkit.NyARException;
\r
14 import jp.nyatla.nyartoolkit.core.raster.*;
\r
15 import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_BGRA;
\r
16 import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;
\r
17 import jp.nyatla.nyartoolkit.utils.j2se.*;
\r
21 public class LabelingTest extends Frame
\r
23 private final String data_file = "../Data/320x240ABGR.raw";
\r
27 public void drawImage() throws Exception
\r
29 File f = new File(data_file);
\r
30 FileInputStream fs = new FileInputStream(data_file);
\r
31 byte[] buf = new byte[(int) f.length()];
\r
33 NyARRgbRaster_BGRA ra = NyARRgbRaster_BGRA.wrap(buf, W, H);
\r
35 NyARRasterFilterBuilder_RgbToBin filter = new NyARRasterFilterBuilder_RgbToBin(110, ra.getBufferReader().getBufferType());
\r
36 NyARBinRaster bin = new NyARBinRaster(W,240);
\r
37 filter.doFilter(ra, bin);
\r
38 int[] t = (int[]) bin.getBuffer();
\r
40 1,1,1,1,1,1,1,1,1,1,
\r
42 1,0,0,0,0,1,0,1,1,1,
\r
43 1,0,1,1,0,1,0,1,1,1,
\r
44 1,1,1,1,1,0,1,1,1,1,
\r
45 1,1,1,1,1,1,1,1,1,1,
\r
46 1,1,1,1,1,1,1,1,1,1,
\r
47 1,1,1,1,1,1,1,1,1,1,
\r
48 1,1,1,1,1,1,1,1,1,1,
\r
49 1,1,1,1,1,1,1,1,1,1,
\r
50 1,1,1,1,1,1,1,1,1,1, 0};
\r
51 System.arraycopy(s, 0, t, 0, 10*10);
\r
52 NyARRasterImageIO sink = new NyARRasterImageIO(W, H);
\r
53 RleImage rle = new RleImage(bin.getWidth(),bin.getHeight());
\r
54 RleLabelingTable table=createRelTable(rle,bin,sink);
\r
56 int nof=i%table.number_of_fragment;
\r
57 if(table._fragment_area[nof]==0){
\r
60 drawLabelingImage(nof,rle,table,bin,sink);
\r
62 g=this.getGraphics();
\r
63 g.drawImage(sink, 100, 100,100,100, this);
\r
67 public void drawLabelingImage(int id,RleImage rle, RleLabelingTable i_table,NyARBinRaster i_source,NyARRasterImageIO i_img)
\r
69 // RleImage rle = new RleImage(i_source.getWidth(),i_source.getHeight());
\r
70 // i_table.labeling(rle,0,10);
\r
72 for(int i=0;i<H;i++){
\r
73 for(int i2=0;i2<W;i2++){
\r
74 i_img.setRGB(i2,i,0xffffff);
\r
76 for(int i2=0;i2<rle.row_length[i];i2++){
\r
77 for(int i3=rle.rle_img_l[rle.row_index[i]+i2];i3<rle.rle_img_r[rle.row_index[i]+i2];i3++)
\r
80 int tid=i_table._fragment_id[i_table.rle_img_id[p]];
\r
84 i_img.setRGB(i3,i,c);
\r
90 i_img.setRGB(i_table._flagment_entry_x[id],i_table._flagment_entry_y[id],0xff0000);
\r
91 // i_img.setRGB(i_table._flagment_entry_x[id]+1,i_table._flagment_entry_y[id],0xff0000);
\r
92 // i_img.setRGB(i_table._flagment_entry_x[id],i_table._flagment_entry_y[id]+1,0xff0000);
\r
93 // i_img.setRGB(i_table._flagment_entry_x[id]+1,i_table._flagment_entry_y[id]+1,0xff0000);
\r
96 public RleLabelingTable createRelTable(RleImage rle,NyARBinRaster i_source,NyARRasterImageIO i_img)
\r
99 rle.toRel(i_source);
\r
101 RleLabelingTable table = new RleLabelingTable(10000);
\r
102 table.labeling(rle,0,H);
\r
106 public LabelingTest() throws NyARException
\r
108 this.addWindowListener(new WindowAdapter() {
\r
109 public void windowClosing(WindowEvent e)
\r
116 public static void main(String[] args)
\r
119 LabelingTest app = new LabelingTest();
\r
120 app.setVisible(true);
\r
121 app.setBounds(0, 0, 640, 480);
\r
123 } catch (Exception e) {
\r
124 e.printStackTrace();
\r
135 short[] rle_img_l;// RELのフラグメント左
\r
137 short[] rle_img_r;// RELのフラグメント右
\r
142 short[] row_length;
\r
146 public RleImage(int i_width, int i_height)
\r
148 final int size = i_width * i_height / 2;
\r
150 this.rle_img_l = new short[size]; // RELのフラグメント長
\r
151 this.rle_img_r = new short[size]; // RELの開始位置
\r
152 this.rle_buf_size = size;
\r
154 this.row_index = new int[i_height];
\r
155 this.row_length = new short[i_height];
\r
156 this._width = i_width;
\r
157 this._height = i_height;
\r
164 * @param i_bin_raster
\r
166 public void toRel(NyARBinRaster i_bin_raster)
\r
168 final int width = this._width;
\r
169 final int height = this._height;
\r
170 int[] in_buf = (int[]) i_bin_raster.getBuffer();
\r
174 for (int y = 0; y < height; y++) {
\r
175 this.row_index[y] = current;
\r
177 int row_index = y * width;
\r
179 final int right_edge = (y + 1) * width - 1;
\r
180 while (x < right_edge) {
\r
182 if (in_buf[x] != 0) {
\r
187 r = (short) (x - row_index);
\r
188 this.rle_img_l[current] = r;
\r
191 while (x < right_edge) {
\r
192 if (in_buf[x] != 0) {
\r
193 // 明点(1)→暗点(0)配列終了>登録
\r
194 this.rle_img_r[current] = r;
\r
197 r = -1;// 右端の位置を0に。
\r
206 // 最後の1点だけ判定方法が少し違うの。
\r
207 if (in_buf[x] != 0) {
\r
208 // 明点→rカウント中なら暗点配列終了>登録
\r
210 this.rle_img_r[current] = r;
\r
214 // 暗点→カウント中でなければl1で追加
\r
216 this.rle_img_r[current] = (short) (x + 1);
\r
219 this.rle_img_l[current] = (short) (width - 1);
\r
220 this.rle_img_r[current] = (short) (width);
\r
225 this.row_length[y] = (short) (current - this.row_index[y]);
\r
229 public void fromRel(NyARBinRaster i_bin_raster)
\r
235 // RleImageをラベリングする。
\r
236 class RleLabelingTable
\r
238 short[] rle_img_id;
\r
240 short[] _fragment_id; // フラグメントラベルのインデクス
\r
242 int[] _fragment_area; // フラグメントラベルの領域数
\r
244 int[] _fragment_pos_x; // フラグメントラベルの位置
\r
246 int[] _fragment_pos_y; // フラグメントラベルの位置
\r
248 short[] _flagment_entry_x; // フラグメントラベルの位置
\r
250 short[] _flagment_entry_y; // フラグメントラベルの位置
\r
252 short number_of_fragment; // 現在のフラグメントの数
\r
254 public RleLabelingTable(int i_max_fragment)
\r
256 this.rle_img_id = new short[i_max_fragment];
\r
257 this._fragment_id = new short[i_max_fragment];
\r
258 this._fragment_area = new int[i_max_fragment];
\r
259 this._fragment_pos_x = new int[i_max_fragment];
\r
260 this._fragment_pos_y = new int[i_max_fragment];
\r
261 this._flagment_entry_x = new short[i_max_fragment];
\r
262 this._flagment_entry_y = new short[i_max_fragment];
\r
265 private void addFragment(RleImage i_rel_img, short i_nof, int i_row_index, int i_rel_index)
\r
267 this.rle_img_id[i_rel_index] = i_nof;// REL毎の固有ID
\r
268 this._fragment_id[i_nof] = i_nof;
\r
269 this._flagment_entry_x[i_nof] = i_rel_img.rle_img_l[i_rel_index];
\r
270 this._flagment_entry_y[i_nof] = (short) i_row_index;
\r
271 this._fragment_area[i_nof] = i_rel_img.rle_img_r[i_rel_index] - i_rel_img.rle_img_l[i_rel_index];
\r
277 // 指定した行のフラグメントをマージします。
\r
278 public void labeling(RleImage i_rel_img, int i_top, int i_bottom)
\r
280 short[] rle_l = i_rel_img.rle_img_l;
\r
281 short[] rle_r = i_rel_img.rle_img_r;
\r
282 short nof = this.number_of_fragment;
\r
284 int index = i_rel_img.row_index[i_top];
\r
285 int eol = i_rel_img.row_length[i_top];
\r
286 for (int i = index; i < index + eol; i++) {
\r
287 // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行
\r
288 addFragment(i_rel_img, nof, i_top, i);
\r
293 for (int y = i_top+1; y < i_bottom; y++) {
\r
294 int index_prev = i_rel_img.row_index[y - 1];
\r
295 int eol_prev = index_prev + i_rel_img.row_length[y - 1];
\r
296 index = i_rel_img.row_index[y];
\r
297 eol = index + i_rel_img.row_length[y];
\r
299 SCAN_CUR:for (int i = index; i < eol; i++) {
\r
300 // index_prev,len_prevの位置を調整する
\r
302 //チェックすべきprevがあれば確認
\r
303 SCAN_PREV: while (index_prev < eol_prev) {
\r
304 if (rle_l[i] - rle_r[index_prev] > 0) {// 0なら8方位ラベリング
\r
305 // prevがcurの左方にある→次のフラグメントを探索
\r
308 } else if (rle_l[index_prev] - rle_r[i] > 0) {// 0なら8方位ラベリングになる
\r
309 // prevがcur右方にある→独立フラグメント
\r
310 addFragment(i_rel_img, nof, y, i);
\r
315 // 結合対象->prevのIDをコピーして、対象フラグメントの情報を更新
\r
316 id = this._fragment_id[this.rle_img_id[index_prev]];
\r
317 this.rle_img_id[i] = id;
\r
318 this._fragment_area[id] += (rle_r[i] - rle_l[i]);
\r
320 this._flagment_entry_x[id] = this._flagment_entry_x[this.rle_img_id[index_prev]];
\r
321 this._flagment_entry_y[id] = this._flagment_entry_y[this.rle_img_id[index_prev]];
\r
325 while (index_prev < eol_prev) {
\r
326 if (rle_l[i] - rle_r[index_prev] > 0) {// 0なら8方位ラベリング
\r
327 // prevがcurの左方にある→prevはcurに連結していない。
\r
329 } else if (rle_l[index_prev] - rle_r[i] > 0) {// 0なら8方位ラベリングになる
\r
330 // prevがcurの右方にある→prevはcurに連結していない。
\r
334 // prevとcurは連結している。
\r
335 final short prev_id = this.rle_img_id[index_prev];
\r
336 if (id != prev_id) {
\r
337 this._fragment_area[id] += this._fragment_area[prev_id];
\r
338 this._fragment_area[prev_id] = 0;
\r
339 // 結合対象->現在のidをインデクスにセット
\r
340 this._fragment_id[prev_id]=id;
\r
342 if (this._flagment_entry_y[id] > this._flagment_entry_y[prev_id]) {
\r
343 // 現在のエントリポイントの方が下にある。(何もしない)
\r
345 if (this._flagment_entry_y[id] < this._flagment_entry_y[prev_id]) {
\r
346 // 現在のエントリポイントの方が上にある。(エントリポイントの交換)
\r
347 this._flagment_entry_y[id] = this._flagment_entry_y[prev_id];
\r
348 this._flagment_entry_x[id] = this._flagment_entry_x[prev_id];
\r
350 // 水平方向で小さい方がエントリポイント。
\r
351 if (this._flagment_entry_x[id] > this._flagment_entry_x[prev_id]) {
\r
352 this._flagment_entry_y[id] = this._flagment_entry_y[prev_id];
\r
353 this._flagment_entry_x[id] = this._flagment_entry_x[prev_id];
\r
362 // curにidが割り当てられたかを確認
\r
365 addFragment(i_rel_img, nof, y, i);
\r
372 this.number_of_fragment = nof;
\r