2 * PROJECT: NyARToolkit
\r
3 * --------------------------------------------------------------------------------
\r
4 * This work is based on the original ARToolKit developed by
\r
7 * HITLab, University of Washington, Seattle
\r
8 * http://www.hitl.washington.edu/artoolkit/
\r
10 * The NyARToolkit is Java edition ARToolKit class library.
\r
11 * Copyright (C)2008-2009 Ryo Iizuka
\r
13 * This program is free software: you can redistribute it and/or modify
\r
14 * it under the terms of the GNU General Public License as published by
\r
15 * the Free Software Foundation, either version 3 of the License, or
\r
16 * (at your option) any later version.
\r
18 * This program is distributed in the hope that it will be useful,
\r
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
21 * GNU General Public License for more details.
\r
23 * You should have received a copy of the GNU General Public License
\r
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
26 * For further information please contact.
\r
27 * http://nyatla.jp/nyatoolkit/
\r
28 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
31 package jp.nyatla.nyartoolkit.core.squaredetect;
\r
33 import jp.nyatla.nyartoolkit.NyARException;
\r
34 import jp.nyatla.nyartoolkit.core.raster.*;
\r
35 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;
\r
41 public class ContourPickup
\r
43 //巡回参照できるように、テーブルを二重化
\r
44 // 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6
\r
45 protected final static int[] _getContour_xdir = { 0, 1, 1, 1, 0,-1,-1,-1 , 0, 1, 1, 1, 0,-1,-1};
\r
46 protected final static int[] _getContour_ydir = {-1,-1, 0, 1, 1, 1, 0,-1 ,-1,-1, 0, 1, 1, 1, 0};
\r
47 public int getContour(NyARBinRaster i_raster,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException
\r
49 assert(i_raster.isEqualBufferType(INyARRaster.BUFFERFORMAT_INT1D_BIN_8));
\r
50 return impl_getContour(i_raster,0,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y);
\r
56 * 画像を2値化するための閾値。暗点<=i_th<明点となります。
\r
60 * @param i_array_size
\r
64 * @throws NyARException
\r
66 public int getContour(NyARGrayscaleRaster i_raster,int i_th,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException
\r
68 assert(i_raster.isEqualBufferType(INyARRaster.BUFFERFORMAT_INT1D_GRAY_8));
\r
69 return impl_getContour(i_raster,i_th,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y);
\r
73 * ラスタのエントリポイントから辿れる輪郭線を配列に返します。
\r
79 * @param i_array_size
\r
84 * @throws NyARException
\r
86 private int impl_getContour(INyARRaster i_raster,int i_th,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException
\r
88 final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
\r
89 final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
\r
91 final int[] i_buf=(int[])i_raster.getBuffer();
\r
92 final int width=i_raster.getWidth();
\r
93 final int height=i_raster.getHeight();
\r
94 //クリップ領域の上端に接しているポイントを得る。
\r
98 o_coord_x[0] = i_entry_x;
\r
99 o_coord_y[0] = i_entry_y;
\r
105 dir = (dir + 5) % 8;//dirの正規化
\r
106 //ここは頑張ればもっと最適化できると思うよ。
\r
107 //4隅以外の境界接地の場合に、境界チェックを省略するとかね。
\r
108 if(c>=1 && c<width-1 && r>=1 && r<height-1){
\r
109 for(;;){//gotoのエミュレート用のfor文
\r
110 //境界に接していないとき(暗点判定)
\r
111 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
115 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
119 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
123 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
127 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
131 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
135 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
139 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
\r
144 BufferedImage b=new BufferedImage(width,height,ColorSpace.TYPE_RGB);
\r
145 NyARRasterImageIO.copy(i_raster, b);
\r
146 ImageIO.write(b,"png",new File("bug.png"));
\r
147 }catch(Exception e){
\r
150 //8方向全て調べたけどラベルが無いよ?
\r
151 throw new NyARException();
\r
156 for (i = 0; i < 8; i++){
\r
157 final int x=c + xdir[dir];
\r
158 final int y=r + ydir[dir];
\r
160 if(x>=0 && x<width && y>=0 && y<height){
\r
161 if (i_buf[(y)*width+(x)] <= i_th) {
\r
165 dir++;//倍長テーブルを参照するので問題なし
\r
168 //8方向全て調べたけどラベルが無いよ?
\r
169 throw new NyARException();// return(-1);
\r
173 dir=dir% 8;//dirの正規化
\r
175 // xcoordとycoordをc,rにも保存
\r
178 o_coord_x[coord_num] = c;
\r
179 o_coord_y[coord_num] = r;
\r
181 if (c == i_entry_x && r == i_entry_y){
\r
186 if (coord_num == i_array_size) {
\r
193 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) throws NyARException
\r
195 final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
\r
196 final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
\r
198 final int[] i_buf=(int[])i_raster.getBuffer();
\r
199 final int width=i_raster.getWidth();
\r
200 final int height=i_raster.getHeight();
\r
201 //クリップ領域の上端に接しているポイントを得る。
\r
210 int c = o_coord_x[0];
\r
211 int r = o_coord_y[0];
\r
213 dir = (dir + 5) % 8;//dirの正規化
\r
214 //ここは頑張ればもっと最適化できると思うよ。
\r
215 //4隅以外の境界接地の場合に、境界チェックを省略するとかね。
\r
216 if(c>=1 && c<width-1 && r>=1 && r<height-1){
\r
217 for(;;){//gotoのエミュレート用のfor文
\r
219 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
223 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
227 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
231 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
235 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
239 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
243 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
247 if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {
\r
250 //8方向全て調べたけどラベルが無いよ?
\r
251 throw new NyARException();
\r
256 for (i = 0; i < 8; i++){
\r
257 final int x=c + xdir[dir];
\r
258 final int y=r + ydir[dir];
\r
260 if(x>=0 && x<width && y>=0 && y<height){
\r
261 if (i_buf[(y)*width+(x)] > 0) {
\r
265 dir++;//倍長テーブルを参照するので問題なし
\r
268 //8方向全て調べたけどラベルが無いよ?
\r
269 throw new NyARException();// return(-1);
\r
273 dir=dir% 8;//dirの正規化
\r
275 // xcoordとycoordをc,rにも保存
\r
278 o_coord_x[coord_num] = c;
\r
279 o_coord_y[coord_num] = r;
\r
281 if (c == sx && r == sy){
\r
286 if (coord_num == i_array_size) {
\r