/* * PROJECT: FLARToolKit * -------------------------------------------------------------------------------- * This work is based on the NyARToolKit developed by * R.Iizuka (nyatla) * http://nyatla.jp/nyatoolkit/ * * The FLARToolKit is ActionScript 3.0 version ARToolkit class library. * Copyright (C)2008 Saqoosha * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this framework; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For further information please contact. * http://www.libspark.org/wiki/saqoosha/FLARToolKit * * */ package org.libspark.flartoolkit.core.labeling { import org.libspark.flartoolkit.core.raster.IFLARRaster; import org.libspark.flartoolkit.core.types.FLARIntSize; /** * ARToolKit互換のラベリングクラスです。 ARToolKitと同一な評価結果を返します。 * */ public class student_ar_org_libspark_flartoolkit_core_labeling_FLARLabeling_ARToolKit implements IFLARLabeling { private static const WORK_SIZE:int = 1024 * 32; // #define WORK_SIZE 1024*32 private const work_holder:FLARWorkHolder = new FLARWorkHolder(WORK_SIZE); private var _dest_size:FLARIntSize; private var _out_image:IFLARLabelingImage; public function attachDestination(i_destination_image:IFLARLabelingImage):void { // サイズチェック var size:FLARIntSize = i_destination_image.getSize(); this._out_image = i_destination_image; // NyLabelingImageのイメージ初期化(枠書き) var img:Array = i_destination_image.getBufferReader().getBuffer() as Array; // int[][] var i:int; for (i = 0; i < size.w; i++) { img[0][i] = 0; img[size.h - 1][i] = 0; } for (i = 0;i < size.h; i++) { img[i][0] = 0; img[i][size.w - 1] = 0; } // サイズ(参照値)を保存 this._dest_size = size; } public function getAttachedDestination():IFLARLabelingImage { return this._out_image; } /** * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR ) 関数の代替品 * ラスタimageをラベリングして、結果を保存します。 Optimize:STEP[1514->1493] * * @param i_raster * @throws FLARException */ public function labeling(i_raster:IFLARRaster):void { var m:int; /* work */ var n:int; var i:int; var j:int; var k:int; var out_image:IFLARLabelingImage = this._out_image; // サイズチェック var in_size:FLARIntSize = i_raster.getSize(); this._dest_size.isEqualSizeO(in_size); const lxsize:int = in_size.w;// lxsize = arUtil_c.arImXsize; const lysize:int = in_size.h;// lysize = arUtil_c.arImYsize; var label_img:Array = out_image.getBufferReader().getBuffer() as Array; // int[][] // 枠作成はインスタンスを作った直後にやってしまう。 //ラベリング情報のリセット(ラベリングインデックスを使用) out_image.reset(true); var label_idxtbl:Array = out_image.getIndexArray(); // int[] var work2_pt:Array; // int[] var wk_max:int = 0; var label_pixel:int; var raster_buf:Array = i_raster.getBufferReader().getBuffer() as Array; // int[][] var line_ptr:Array; // int[] var work2:Array = this.work_holder.work2; // int[][] var label_img_pt0:Array; // int[] var label_img_pt1:Array; // int[] for (j = 1; j < lysize - 1; j++) { // for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) { line_ptr = raster_buf[j]; label_img_pt0 = label_img[j]; label_img_pt1 = label_img[j - 1]; for (i = 1; i < lxsize - 1; i++) { // for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) { // RGBの合計値が閾値より小さいかな? if (line_ptr[i] == 0) { // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]); if (label_img_pt1[i] > 0) { // if( *pnt1 > 0 ) { label_pixel = label_img_pt1[i]; // *pnt2 = *pnt1; work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j; } else if (label_img_pt1[i + 1] > 0) { // }else if(*(pnt1+1) > 0 ) { if (label_img_pt1[i - 1] > 0) { // if( *(pnt1-1) > 0 ) { m = label_idxtbl[label_img_pt1[i + 1] - 1]; // m =work[*(pnt1+1)-1]; n = label_idxtbl[label_img_pt1[i - 1] - 1]; // n =work[*(pnt1-1)-1]; if (m > n) { label_pixel = n; // *pnt2 = n; // wk=IntPointer.wrap(work, 0);//wk = // &(work[0]); for (k = 0;k < wk_max; k++) { if (label_idxtbl[k] == m) { // if( *wk == m ) label_idxtbl[k] = n;// *wk = n; } } } else if (m < n) { label_pixel = m; // *pnt2 = m; // wk=IntPointer.wrap(work,0);//wk = &(work[0]); for (k = 0;k < wk_max; k++) { if (label_idxtbl[k] == n) { // if( *wk == n ){ label_idxtbl[k] = m;// *wk = m; } } } else { label_pixel = m;// *pnt2 = m; } work2_pt = work2[label_pixel - 1]; work2_pt[0]++; work2_pt[1] += i; work2_pt[2] += j; work2_pt[6] = j; } else if ((label_img_pt0[i - 1]) > 0) { // }else if(*(pnt2-1) > 0) { m = label_idxtbl[(label_img_pt1[i + 1]) - 1]; // m =work[*(pnt1+1)-1]; n = label_idxtbl[label_img_pt0[i - 1] - 1]; // n =work[*(pnt2-1)-1]; if (m > n) { label_pixel = n; // *pnt2 = n; for (k = 0; k < wk_max; k++) { if (label_idxtbl[k] == m) { // if( *wk == m ){ label_idxtbl[k] = n;// *wk = n; } } } else if (m < n) { label_pixel = m; // *pnt2 = m; for (k = 0; k < wk_max; k++) { if (label_idxtbl[k] == n) { // if( *wk == n ){ label_idxtbl[k] = m;// *wk = m; } } } else { label_pixel = m;// *pnt2 = m; } work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j; } else { label_pixel = label_img_pt1[i + 1]; // *pnt2 = // *(pnt1+1); work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; if (work2_pt[3] > i) { // if( // work2[((*pnt2)-1)*7+3] > // i ){ work2_pt[3] = i;// work2[((*pnt2)-1)*7+3] = i; } work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j; } } else if ((label_img_pt1[i - 1]) > 0) { // }else if( // *(pnt1-1) > 0 ) { label_pixel = label_img_pt1[i - 1]; // *pnt2 = // *(pnt1-1); work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; if (work2_pt[4] < i) { // if( work2[((*pnt2)-1)*7+4] 0) { // }else if(*(pnt2-1) > 0) { label_pixel = label_img_pt0[i - 1]; // *pnt2 =*(pnt2-1); work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; if (work2_pt[4] < i) { // if( work2[((*pnt2)-1)*7+4] work2_pt[3]) { label_pt.clip_l = work2_pt[3]; } if (label_pt.clip_r < work2_pt[4]) { label_pt.clip_r = work2_pt[4]; } if (label_pt.clip_t > work2_pt[5]) { label_pt.clip_t = work2_pt[5]; } if (label_pt.clip_b < work2_pt[6]) { label_pt.clip_b = work2_pt[6]; } } for (i = 0; i < wlabel_num; i++) { // for(int i = 0; i < *label_num; i++ ) { label_pt = labels[i]; label_pt.pos_x /= label_pt.area; label_pt.pos_y /= label_pt.area; } return; } } } import org.libspark.flartoolkit.FLARException; import org.libspark.flartoolkit.utils.ArrayUtil; /** * FLARLabeling_O2のworkとwork2を可変長にするためのクラス * * */ class FLARWorkHolder { private static const ARRAY_APPEND_STEP:int = 256; public var work2:Array; // int[][] private var allocate_size:int; /** * 最大i_holder_size個の動的割り当てバッファを準備する。 * * @param i_holder_size */ public function FLARWorkHolder(i_holder_size:int) { // ポインタだけははじめに確保しておく // this.work2 = new int[i_holder_size][]; this.work2 = ArrayUtil.createJaggedArray(i_holder_size, 0); this.allocate_size = 0; } /** * i_indexで指定した番号までのバッファを準備する。 * * @param i_index */ public function reserv(i_index:int):void { // アロケート済みなら即リターン if (this.allocate_size > i_index) { return; } // 要求されたインデクスは範囲外 if (i_index >= this.work2.length) { throw new FLARException(); } // 追加アロケート範囲を計算 var range:int = i_index + ARRAY_APPEND_STEP; if (range >= this.work2.length) { range = this.work2.length; } // アロケート for (var i:int = this.allocate_size;i < range; i++) { this.work2[i] = new Array(7);//new int[7]; } this.allocate_size = range; } }