Пример #1
0
        public int getContour(NyARLabelingImage i_raster, int i_entry_x, int i_entry_y, int i_array_size, int[] o_coord_x, int[] o_coord_y)
        {
            int[] xdir = _getContour_xdir; // static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
            int[] ydir = _getContour_ydir; // static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};

            int[] i_buf  = (int[])i_raster.getBuffer();
            int   width  = i_raster.getWidth();
            int   height = i_raster.getHeight();
            //クリップ領域の上端に接しているポイントを得る。
            int sx = i_entry_x;
            int sy = i_entry_y;

            int coord_num = 1;

            o_coord_x[0] = sx;
            o_coord_y[0] = sy;
            int dir = 5;

            int c = o_coord_x[0];
            int r = o_coord_y[0];

            for (; ;)
            {
                dir = (dir + 5) % 8;//dirの正規化
                //ここは頑張ればもっと最適化できると思うよ。
                //4隅以外の境界接地の場合に、境界チェックを省略するとかね。
                if (c >= 1 && c < width - 1 && r >= 1 && r < height - 1)
                {
                    for (; ;)
                    {//gotoのエミュレート用のfor文
                        //境界に接していないとき
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        //8方向全て調べたけどラベルが無いよ?
                        throw new NyARException();
                    }
                }
                else
                {
                    //境界に接しているとき
                    int i;
                    for (i = 0; i < 8; i++)
                    {
                        int x = c + xdir[dir];
                        int y = r + ydir[dir];
                        //境界チェック
                        if (x >= 0 && x < width && y >= 0 && y < height)
                        {
                            if (i_buf[(y) * width + (x)] > 0)
                            {
                                break;
                            }
                        }
                        dir++;//倍長テーブルを参照するので問題なし
                    }
                    if (i == 8)
                    {
                        //8方向全て調べたけどラベルが無いよ?
                        throw new NyARException();// return(-1);
                    }
                }

                dir = dir % 8;//dirの正規化

                // xcoordとycoordをc,rにも保存
                c = c + xdir[dir];
                r = r + ydir[dir];
                o_coord_x[coord_num] = c;
                o_coord_y[coord_num] = r;
                // 終了条件判定
                if (c == sx && r == sy)
                {
                    coord_num++;
                    break;
                }
                coord_num++;
                if (coord_num == i_array_size)
                {
                    //輪郭が末端に達した
                    return(coord_num);
                }
            }
            return(coord_num);
        }
        /**
         * この関数は、ラスタをラべリングします。
         * 結果は、o_destinationに出力します。
         * <p>メモ -
         * この関数の元になるARToolKitの関数は、static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )です。
         * </p>
         * @param i_raster
         * 入力元の二値ラスタオブジェクトです。画素形式は、{@link NyARBufferType#INT1D_BIN_8}である必要があります。
         * @param o_destination
         * ラべリング画像の出力先オブジェクトです。i_rasterと同じサイズである必要があります。
         * @
         */
        public int labeling(INyARBinRaster i_raster, NyARLabelingImage o_destination)
        {
            Debug.Assert(i_raster.getBufferType() == NyARBufferType.INT1D_BIN_8);
            int label_img_ptr1, label_pixel;
            int i, j;
            int n, k; /* work */

            // サイズチェック
            NyARIntSize in_size = i_raster.getSize();

            Debug.Assert(o_destination.getSize().isEqualSize(in_size));

            int lxsize = in_size.w; // lxsize = arUtil_c.arImXsize;
            int lysize = in_size.h; // lysize = arUtil_c.arImYsize;

            int[] label_img = (int[])o_destination.getBuffer();

            // 枠作成はインスタンスを作った直後にやってしまう。

            // ラベリング情報のリセット(ラベリングインデックスを使用)
            o_destination.reset(true);

            int[] label_idxtbl = o_destination.getIndexArray();
            int[] raster_buf   = (int[])i_raster.getBuffer();

            int[] work2_pt;
            int   wk_max = 0;

            int pixel_index;

            int[][] work2 = this._work_holder.work2;

            // [1,1](ptr0)と、[0,1](ptr1)のインデクス値を計算する。
            for (j = 1; j < lysize - 1; j++)
            {                                          // for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) {
                pixel_index    = j * lxsize + 1;
                label_img_ptr1 = pixel_index - lxsize; // label_img_pt1 = label_img[j - 1];
                for (i = 1; i < lxsize - 1; i++, pixel_index++, label_img_ptr1++)
                {                                      // for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) {
                    // RGBの合計値が閾値より小さいかな?
                    if (raster_buf[pixel_index] != 0)
                    {
                        label_img[pixel_index] = 0;// label_img_pt0[i] = 0;// *pnt2 = 0;
                    }
                    else
                    {
                        // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]);
                        if (label_img[label_img_ptr1] > 0)
                        {                                            // if (label_img_pt1[i] > 0) {// if( *pnt1 > 0 ) {
                            label_pixel = label_img[label_img_ptr1]; // 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[label_img_ptr1 + 1] > 0)
                        {                                                                      // } else if (label_img_pt1[i + 1] > 0) {// }else if(*(pnt1+1) > 0 ) {
                            if (label_img[label_img_ptr1 - 1] > 0)
                            {                                                                  // if (label_img_pt1[i - 1] > 0) {// if( *(pnt1-1) > 0 ) {
                                label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1]; // m = label_idxtbl[label_img_pt1[i + 1] - 1];// m
                                // =work[*(pnt1+1)-1];
                                n = label_idxtbl[label_img[label_img_ptr1 - 1] - 1];           // n = label_idxtbl[label_img_pt1[i - 1] - 1];// n =work[*(pnt1-1)-1];
                                if (label_pixel > n)
                                {
                                    // wk=IntPointer.wrap(work, 0);//wk = &(work[0]);
                                    for (k = 0; k < wk_max; k++)
                                    {
                                        if (label_idxtbl[k] == label_pixel)
                                        {                        // if( *wk == m )
                                            label_idxtbl[k] = n; // *wk = n;
                                        }
                                    }
                                    label_pixel = n;// *pnt2 = n;
                                }
                                else if (label_pixel < n)
                                {
                                    // 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] = label_pixel; // *wk = 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[pixel_index - 1]) > 0)
                            {                                                                  // } else if ((label_img_pt0[i - 1]) > 0) {// }else if(*(pnt2-1) > 0) {
                                label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1]; // m = label_idxtbl[label_img_pt1[i + 1] - 1];// m =work[*(pnt1+1)-1];
                                n           = label_idxtbl[label_img[pixel_index - 1] - 1];    // n = label_idxtbl[label_img_pt0[i - 1] - 1];// n =work[*(pnt2-1)-1];
                                if (label_pixel > n)
                                {
                                    for (k = 0; k < wk_max; k++)
                                    {
                                        if (label_idxtbl[k] == label_pixel)
                                        {                        // if( *wk == m ){
                                            label_idxtbl[k] = n; // *wk = n;
                                        }
                                    }
                                    label_pixel = n;// *pnt2 = n;
                                }
                                else if (label_pixel < n)
                                {
                                    for (k = 0; k < wk_max; k++)
                                    {
                                        if (label_idxtbl[k] == n)
                                        {                                  // if( *wk == n ){
                                            label_idxtbl[k] = label_pixel; // *wk = 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[label_img_ptr1 + 1];// 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[label_img_ptr1 - 1]) > 0)
                        {                                                // } else if ((label_img_pt1[i - 1]) > 0) {// }else if(
                            // *(pnt1-1) > 0 ) {
                            label_pixel = label_img[label_img_ptr1 - 1]; // 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] <i ){
                                work2_pt[4] = i; // work2[((*pnt2)-1)*7+4] = i;
                            }
                            work2_pt[6] = j;     // work2[((*pnt2)-1)*7+6] = j;
                        }
                        else if (label_img[pixel_index - 1] > 0)
                        {                                             // } else if (label_img_pt0[i - 1] > 0) {// }else if(*(pnt2-1) > 0) {
                            label_pixel = label_img[pixel_index - 1]; // 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] <i ){
                                work2_pt[4] = i; // work2[((*pnt2)-1)*7+4] = i;
                            }
                        }
                        else
                        {
                            // 現在地までの領域を予約
                            this._work_holder.reserv(wk_max);
                            wk_max++;
                            label_idxtbl[wk_max - 1] = wk_max;
                            label_pixel = wk_max;// work[wk_max-1] = *pnt2 = wk_max;
                            work2_pt    = work2[wk_max - 1];
                            work2_pt[0] = 1;
                            work2_pt[1] = i;
                            work2_pt[2] = j;
                            work2_pt[3] = i;
                            work2_pt[4] = i;
                            work2_pt[5] = j;
                            work2_pt[6] = j;
                        }
                        label_img[pixel_index] = label_pixel;// label_img_pt0[i] = label_pixel;
                    }
                }
            }
            // インデックステーブルとラベル数の計算
            int wlabel_num = 1;// *label_num = *wlabel_num = j - 1;

            for (i = 0; i < wk_max; i++)
            {                                                                                                    // for(int i = 1; i <= wk_max; i++,wk++) {
                label_idxtbl[i] = (label_idxtbl[i] == i + 1) ? wlabel_num++ : label_idxtbl[label_idxtbl[i] - 1]; // *wk=(*wk==i)?j++:work[(*wk)-1];
            }
            wlabel_num -= 1;                                                                                     // *label_num = *wlabel_num = j - 1;
            if (wlabel_num == 0)
            {                                                                                                    // if( *label_num == 0 ) {
                // 発見数0
                o_destination.getLabelStack().clear();
                return(0);
            }
            // ラベル情報の保存等
            NyARLabelingLabelStack label_list = o_destination.getLabelStack();

            // ラベルバッファを予約
            label_list.init(wlabel_num);

            // エリアと重心、クリップ領域を計算
            NyARLabelingLabel label_pt;

            NyARLabelingLabel[] labels = label_list.getArray();
            for (i = 0; i < wlabel_num; i++)
            {
                label_pt        = labels[i];
                label_pt.id     = (short)(i + 1);
                label_pt.area   = 0;
                label_pt.pos_x  = label_pt.pos_y = 0;
                label_pt.clip_l = lxsize;              // wclip[i*4+0] = lxsize;
                label_pt.clip_t = lysize;              // wclip[i*4+2] = lysize;
                label_pt.clip_r = label_pt.clip_b = 0; // wclip[i*4+3] = 0;
            }

            for (i = 0; i < wk_max; i++)
            {
                label_pt        = labels[label_idxtbl[i] - 1];
                work2_pt        = work2[i];
                label_pt.area  += work2_pt[0];
                label_pt.pos_x += work2_pt[1];
                label_pt.pos_y += work2_pt[2];
                if (label_pt.clip_l > 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(wlabel_num);
        }
Пример #3
0
        public int getContour(NyARLabelingImage i_raster, int i_entry_x, int i_entry_y, int i_array_size, int[] o_coord_x, int[] o_coord_y)
        {
            int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
            int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};

            int[] i_buf = (int[])i_raster.getBuffer();
            int width = i_raster.getWidth();
            int height = i_raster.getHeight();
            //クリップ領域の上端に接しているポイントを得る。
            int sx = i_entry_x;
            int sy = i_entry_y;

            int coord_num = 1;
            o_coord_x[0] = sx;
            o_coord_y[0] = sy;
            int dir = 5;

            int c = o_coord_x[0];
            int r = o_coord_y[0];
            for (; ; )
            {
                dir = (dir + 5) % 8;//dirの正規化
                //ここは頑張ればもっと最適化できると思うよ。
                //4隅以外の境界接地の場合に、境界チェックを省略するとかね。
                if (c >= 1 && c < width - 1 && r >= 1 && r < height - 1)
                {
                    for (; ; )
                    {//gotoのエミュレート用のfor文
                        //境界に接していないとき
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        dir++;
                        if (i_buf[(r + ydir[dir]) * width + (c + xdir[dir])] > 0)
                        {
                            break;
                        }
                        //8方向全て調べたけどラベルが無いよ?
                        throw new NyARException();
                    }
                }
                else
                {
                    //境界に接しているとき
                    int i;
                    for (i = 0; i < 8; i++)
                    {
                        int x = c + xdir[dir];
                        int y = r + ydir[dir];
                        //境界チェック
                        if (x >= 0 && x < width && y >= 0 && y < height)
                        {
                            if (i_buf[(y) * width + (x)] > 0)
                            {
                                break;
                            }
                        }
                        dir++;//倍長テーブルを参照するので問題なし
                    }
                    if (i == 8)
                    {
                        //8方向全て調べたけどラベルが無いよ?
                        throw new NyARException();// return(-1);
                    }
                }

                dir = dir % 8;//dirの正規化

                // xcoordとycoordをc,rにも保存
                c = c + xdir[dir];
                r = r + ydir[dir];
                o_coord_x[coord_num] = c;
                o_coord_y[coord_num] = r;
                // 終了条件判定
                if (c == sx && r == sy)
                {
                    coord_num++;
                    break;
                }
                coord_num++;
                if (coord_num == i_array_size)
                {
                    //輪郭が末端に達した
                    return coord_num;
                }
            }
            return coord_num;
        }
        /**
         * この関数は、ラスタをラべリングします。
         * 結果は、o_destinationに出力します。
         * <p>メモ -
         * この関数の元になるARToolKitの関数は、static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )です。
         * </p>
         * @param i_raster
         * 入力元の二値ラスタオブジェクトです。画素形式は、{@link NyARBufferType#INT1D_BIN_8}である必要があります。
         * @param o_destination
         * ラべリング画像の出力先オブジェクトです。i_rasterと同じサイズである必要があります。
         * @
         */
        public int labeling(NyARBinRaster i_raster, NyARLabelingImage o_destination)
        {
            Debug.Assert(i_raster.getBufferType() == NyARBufferType.INT1D_BIN_8);
            int label_img_ptr1, label_pixel;
            int i, j;
            int n, k; /* work */

            // サイズチェック
            NyARIntSize in_size = i_raster.getSize();
            Debug.Assert(o_destination.getSize().isEqualSize(in_size));

            int lxsize = in_size.w;// lxsize = arUtil_c.arImXsize;
            int lysize = in_size.h;// lysize = arUtil_c.arImYsize;
            int[] label_img = (int[])o_destination.getBuffer();

            // 枠作成はインスタンスを作った直後にやってしまう。

            // ラベリング情報のリセット(ラベリングインデックスを使用)
            o_destination.reset(true);

            int[] label_idxtbl = o_destination.getIndexArray();
            int[] raster_buf = (int[])i_raster.getBuffer();

            int[] work2_pt;
            int wk_max = 0;

            int pixel_index;
            int[][] work2 = this._work_holder.work2;

            // [1,1](ptr0)と、[0,1](ptr1)のインデクス値を計算する。
            for (j = 1; j < lysize - 1; j++)
            {// for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) {
                pixel_index = j * lxsize + 1;
                label_img_ptr1 = pixel_index - lxsize;// label_img_pt1 = label_img[j - 1];
                for (i = 1; i < lxsize - 1; i++, pixel_index++, label_img_ptr1++)
                {// for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) {
                    // RGBの合計値が閾値より小さいかな?
                    if (raster_buf[pixel_index] != 0)
                    {
                        label_img[pixel_index] = 0;// label_img_pt0[i] = 0;// *pnt2 = 0;
                    }
                    else
                    {
                        // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]);
                        if (label_img[label_img_ptr1] > 0)
                        {// if (label_img_pt1[i] > 0) {// if( *pnt1 > 0 ) {
                            label_pixel = label_img[label_img_ptr1];// 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[label_img_ptr1 + 1] > 0)
                        {// } else if (label_img_pt1[i + 1] > 0) {// }else if(*(pnt1+1) > 0 ) {
                            if (label_img[label_img_ptr1 - 1] > 0)
                            {// if (label_img_pt1[i - 1] > 0) {// if( *(pnt1-1) > 0 ) {
                                label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1];// m = label_idxtbl[label_img_pt1[i + 1] - 1];// m
                                // =work[*(pnt1+1)-1];
                                n = label_idxtbl[label_img[label_img_ptr1 - 1] - 1];// n = label_idxtbl[label_img_pt1[i - 1] - 1];// n =work[*(pnt1-1)-1];
                                if (label_pixel > n)
                                {
                                    // wk=IntPointer.wrap(work, 0);//wk = &(work[0]);
                                    for (k = 0; k < wk_max; k++)
                                    {
                                        if (label_idxtbl[k] == label_pixel)
                                        {// if( *wk == m )
                                            label_idxtbl[k] = n;// *wk = n;
                                        }
                                    }
                                    label_pixel = n;// *pnt2 = n;
                                }
                                else if (label_pixel < n)
                                {
                                    // 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] = label_pixel;// *wk = 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[pixel_index - 1]) > 0)
                            {// } else if ((label_img_pt0[i - 1]) > 0) {// }else if(*(pnt2-1) > 0) {
                                label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1];// m = label_idxtbl[label_img_pt1[i + 1] - 1];// m =work[*(pnt1+1)-1];
                                n = label_idxtbl[label_img[pixel_index - 1] - 1];// n = label_idxtbl[label_img_pt0[i - 1] - 1];// n =work[*(pnt2-1)-1];
                                if (label_pixel > n)
                                {
                                    for (k = 0; k < wk_max; k++)
                                    {
                                        if (label_idxtbl[k] == label_pixel)
                                        {// if( *wk == m ){
                                            label_idxtbl[k] = n;// *wk = n;
                                        }
                                    }
                                    label_pixel = n;// *pnt2 = n;
                                }
                                else if (label_pixel < n)
                                {
                                    for (k = 0; k < wk_max; k++)
                                    {
                                        if (label_idxtbl[k] == n)
                                        {// if( *wk == n ){
                                            label_idxtbl[k] = label_pixel;// *wk = 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[label_img_ptr1 + 1];// 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[label_img_ptr1 - 1]) > 0)
                        {// } else if ((label_img_pt1[i - 1]) > 0) {// }else if(
                            // *(pnt1-1) > 0 ) {
                            label_pixel = label_img[label_img_ptr1 - 1];// 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] <i ){
                                work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;
                            }
                            work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;
                        }
                        else if (label_img[pixel_index - 1] > 0)
                        {// } else if (label_img_pt0[i - 1] > 0) {// }else if(*(pnt2-1) > 0) {
                            label_pixel = label_img[pixel_index - 1];// 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] <i ){
                                work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;
                            }
                        }
                        else
                        {
                            // 現在地までの領域を予約
                            this._work_holder.reserv(wk_max);
                            wk_max++;
                            label_idxtbl[wk_max - 1] = wk_max;
                            label_pixel = wk_max;// work[wk_max-1] = *pnt2 = wk_max;
                            work2_pt = work2[wk_max - 1];
                            work2_pt[0] = 1;
                            work2_pt[1] = i;
                            work2_pt[2] = j;
                            work2_pt[3] = i;
                            work2_pt[4] = i;
                            work2_pt[5] = j;
                            work2_pt[6] = j;
                        }
                        label_img[pixel_index] = label_pixel;// label_img_pt0[i] = label_pixel;
                    }
                }

            }
            // インデックステーブルとラベル数の計算
            int wlabel_num = 1;// *label_num = *wlabel_num = j - 1;

            for (i = 0; i < wk_max; i++)
            {// for(int i = 1; i <= wk_max; i++,wk++) {
                label_idxtbl[i] = (label_idxtbl[i] == i + 1) ? wlabel_num++ : label_idxtbl[label_idxtbl[i] - 1];// *wk=(*wk==i)?j++:work[(*wk)-1];
            }
            wlabel_num -= 1;// *label_num = *wlabel_num = j - 1;
            if (wlabel_num == 0)
            {// if( *label_num == 0 ) {
                // 発見数0
                o_destination.getLabelStack().clear();
                return 0;
            }
            // ラベル情報の保存等
            NyARLabelingLabelStack label_list = o_destination.getLabelStack();

            // ラベルバッファを予約
            label_list.init(wlabel_num);

            // エリアと重心、クリップ領域を計算
            NyARLabelingLabel label_pt;
            NyARLabelingLabel[] labels = label_list.getArray();
            for (i = 0; i < wlabel_num; i++)
            {
                label_pt = labels[i];
                label_pt.id = (short)(i + 1);
                label_pt.area = 0;
                label_pt.pos_x = label_pt.pos_y = 0;
                label_pt.clip_l = lxsize;// wclip[i*4+0] = lxsize;
                label_pt.clip_t = lysize;// wclip[i*4+2] = lysize;
                label_pt.clip_r = label_pt.clip_b = 0;// wclip[i*4+3] = 0;
            }

            for (i = 0; i < wk_max; i++)
            {
                label_pt = labels[label_idxtbl[i] - 1];
                work2_pt = work2[i];
                label_pt.area += work2_pt[0];
                label_pt.pos_x += work2_pt[1];
                label_pt.pos_y += work2_pt[2];
                if (label_pt.clip_l > 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 wlabel_num;
        }