From e93544a801900e5ccdeb712e68c85cd7080d65d0 Mon Sep 17 00:00:00 2001 From: nyatla Date: Thu, 19 Nov 2009 11:31:13 +0000 Subject: [PATCH] =?utf8?q?[backup]NyARToolkit=20for=20Java=20=E7=94=BB?= =?utf8?q?=E5=83=8F=E5=87=A6=E7=90=86=E3=83=95=E3=82=A3=E3=83=AB=E3=82=BF?= =?utf8?q?=E3=82=92=E3=81=84=E3=81=8F=E3=81=A4=E3=81=8B=E8=BF=BD=E5=8A=A0?= =?utf8?q?=20NyARLinear=E3=81=AB=E4=BA=A4=E7=82=B9=E8=A8=88=E7=AE=97?= =?utf8?q?=E9=96=A2=E6=95=B0=E3=82=92=E8=BF=BD=E5=8A=A0=20=E3=82=86?= =?utf8?q?=E3=81=8C=E3=81=BF=E8=A8=88=E7=AE=97=E3=83=9E=E3=83=83=E3=83=97?= =?utf8?q?=E3=82=92=E8=8B=A5=E5=B9=B2=E4=BF=AE=E6=AD=A3=20=E7=9F=A9?= =?utf8?q?=E5=BD=A2=E5=88=A4=E5=AE=9A=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE?= =?utf8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3?= =?utf8?q?=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../core/param/NyARObserv2IdealMap.java | 28 ++-- .../rasterfilter/NyARRasterFilter_Reverse.java | 77 ++++++++++ .../rasterfilter/NyARRasterFilter_Roberts.java | 67 +++++++++ .../NyARRasterFilter_SimpleSmooth.java | 125 ++++++++++++++++ ...dd.java => NyARRasterFilter_Rgb2Gs_AveAdd.java} | 4 +- .../rgb2gs/NyARRasterFilter_Rgb2Gs_RgbCube.java | 97 +++++++++++++ .../rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java | 84 +++++++++++ .../squaredetect/Coord2SquareVertexIndexes.java | 160 +++++++++++++++++++++ .../core/squaredetect/SquareContourDetector.java | 149 +++---------------- .../nyartoolkit/core/types/NyARHistgram.java | 2 +- .../nyatla/nyartoolkit/core/types/NyARLinear.java | 17 +++ 11 files changed, 667 insertions(+), 143 deletions(-) create mode 100644 src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java create mode 100644 src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Roberts.java create mode 100644 src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java rename src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/{NyARRasterFilter_RgbAveAdd.java => NyARRasterFilter_Rgb2Gs_AveAdd.java} (93%) create mode 100644 src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbCube.java create mode 100644 src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java create mode 100644 src/jp/nyatla/nyartoolkit/core/squaredetect/Coord2SquareVertexIndexes.java diff --git a/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java b/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java index 63f6cc0..1b6e6de 100644 --- a/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java +++ b/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java @@ -32,14 +32,17 @@ package jp.nyatla.nyartoolkit.core.param; import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d; import jp.nyatla.nyartoolkit.core.types.*; + /** - * 歪み成分マップを使用するINyARCameraDistortionFactor + * 歪み矯正した座標系を格納したクラスです。 + * 2次元ラスタを1次元配列で表現します。 + * */ -final public class NyARObserv2IdealMap +public class NyARObserv2IdealMap { - private int _stride; - private double[] _mapx; - private double[] _mapy; + protected int _stride; + protected double[] _mapx; + protected double[] _mapy; public NyARObserv2IdealMap(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size) { NyARDoublePoint2d opoint=new NyARDoublePoint2d(); @@ -60,9 +63,9 @@ final public class NyARObserv2IdealMap } return; } - public void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point) + public void observ2Ideal(int ix, int iy, NyARDoublePoint2d o_point) { - int idx=(int)ix+(int)iy*this._stride; + int idx=ix+iy*this._stride; o_point.x=this._mapx[idx]; o_point.y=this._mapy[idx]; return; @@ -71,10 +74,13 @@ final public class NyARObserv2IdealMap { int idx; int ptr=i_out_start_index; - for (int j = 0; j < i_num; j++) { - idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*this._stride; - o_x_coord[ptr]=this._mapx[idx]; - o_y_coord[ptr]=this._mapy[idx]; + final double[] mapx=this._mapx; + final double[] mapy=this._mapy; + final int stride=this._stride; + for (int j = 0; j < i_num; j++){ + idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*stride; + o_x_coord[ptr]=mapx[idx]; + o_y_coord[ptr]=mapy[idx]; ptr++; } return; diff --git a/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java b/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java new file mode 100644 index 0000000..b792a42 --- /dev/null +++ b/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java @@ -0,0 +1,77 @@ +/* + * PROJECT: NyARToolkit(Extension) + * -------------------------------------------------------------------------------- + * The NyARToolkit is Java edition ARToolKit class library. + * Copyright (C)2008-2009 Ryo Iizuka + * + * 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 3 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 program. If not, see . + * + * For further information please contact. + * http://nyatla.jp/nyatoolkit/ + * or + * + */ +package jp.nyatla.nyartoolkit.core.rasterfilter; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.types.*; +import jp.nyatla.nyartoolkit.core.rasterreader.*; + + +/** + * ネガポジ反転フィルタ。 + * 画像の明暗を反転します。 + * + */ +public class NyARRasterFilter_Reverse implements INyARRasterFilter +{ + private IdoFilterImpl _do_filter_impl; + public NyARRasterFilter_Reverse(int i_raster_type) throws NyARException + { + switch (i_raster_type) { + case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8: + this._do_filter_impl=new IdoFilterImpl_GRAY_8(); + break; + default: + throw new NyARException(); + } + } + public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException + { + this._do_filter_impl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize()); + } + + interface IdoFilterImpl + { + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException; + } + class IdoFilterImpl_GRAY_8 implements IdoFilterImpl + { + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException + { + assert (i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8)); + assert (i_output.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8)); + int[] in_ptr =(int[])i_input.getBuffer(); + int[] out_ptr=(int[])i_output.getBuffer(); + + + int number_of_pixel=i_size.h*i_size.w; + for(int i=0;i>1; + p00=p01; + p10=p11; + idx++; + } + } + return; + } + } +} + diff --git a/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java b/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java new file mode 100644 index 0000000..39be984 --- /dev/null +++ b/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java @@ -0,0 +1,125 @@ +/* + * PROJECT: NyARToolkit(Extension) + * -------------------------------------------------------------------------------- + * The NyARToolkit is Java edition ARToolKit class library. + * Copyright (C)2008-2009 Ryo Iizuka + * + * 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 3 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 program. If not, see . + * + * For further information please contact. + * http://nyatla.jp/nyatoolkit/ + * or + * + */ +package jp.nyatla.nyartoolkit.core.rasterfilter; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.raster.INyARRaster; +import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader; +import jp.nyatla.nyartoolkit.core.types.NyARIntSize; + + +/** + * 平滑化フィルタ + * 画像を平滑化します。 + * カーネルサイズは3x3です。 + */ +public class NyARRasterFilter_SimpleSmooth implements INyARRasterFilter +{ + private IdoFilterImpl _do_filter_impl; + public NyARRasterFilter_SimpleSmooth(int i_raster_type) throws NyARException + { + switch (i_raster_type) { + case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8: + this._do_filter_impl=new IdoFilterImpl_GRAY_8(); + break; + default: + throw new NyARException(); + } + } + public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException + { + assert (i_input!=i_output); + this._do_filter_impl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize()); + } + + interface IdoFilterImpl + { + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException; + } + class IdoFilterImpl_GRAY_8 implements IdoFilterImpl + { + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException + { + assert (i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8)); + assert (i_output.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8)); + int[] in_ptr =(int[])i_input.getBuffer(); + int[] out_ptr=(int[])i_output.getBuffer(); + /* 画像端は捨てる。 + */ + int width=i_size.w; + int height=i_size.h; + int col0,col1,col2; + int bptr=0; + //1行目 + col1=in_ptr[bptr ]+in_ptr[bptr+width ]; + col2=in_ptr[bptr+1]+in_ptr[bptr+width+1]; + out_ptr[bptr]=(col1+col2)/4; + bptr++; + for(int x=0;x. + * + * For further information please contact. + * http://nyatla.jp/nyatoolkit/ + * or + * + */ +package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster; +import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs; +import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader; +import jp.nyatla.nyartoolkit.core.types.NyARIntSize; + + +/** + * RGBラスタをGrayScaleに変換するフィルタを作成します。 + * このフィルタは、RGB値の平均値を、(R*G*B)/(255*255)で算出します。 + * + * この値は、RGB成分の作る立方体の体積を0-255スケールにした値です。 + * + */ +public class NyARRasterFilter_Rgb2Gs_RgbCube implements INyARRasterFilter_RgbToGs +{ + private IdoFilterImpl _dofilterimpl; + public NyARRasterFilter_Rgb2Gs_RgbCube(int i_raster_type) throws NyARException + { + switch (i_raster_type) { + case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24: + case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24: + this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24(); + break; + default: + throw new NyARException(); + } + } + public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException + { + assert (i_input.getSize().isEqualSize(i_output.getSize()) == true); + this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize()); + } + + interface IdoFilterImpl + { + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException; + } + class IdoFilterImpl_BYTE1D_B8G8R8_24 implements IdoFilterImpl + { + /** + * This function is not optimized. + */ + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException + { + assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24) + || i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24)); + + int[] out_buf = (int[]) i_output.getBuffer(); + byte[] in_buf = (byte[]) i_input.getBuffer(); + + int bp = 0; + for (int y = 0; y < i_size.h; y++) { + for (int x = 0; x < i_size.w; x++) { + out_buf[y*i_size.w+x] = ((in_buf[bp] & 0xff) * (in_buf[bp + 1] & 0xff) * (in_buf[bp + 2] & 0xff)) >> 16; + bp += 3; + } + } + return; + } + } + +} + diff --git a/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java b/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java new file mode 100644 index 0000000..cd56979 --- /dev/null +++ b/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java @@ -0,0 +1,84 @@ +/* + * PROJECT: NyARToolkit(Extension) + * -------------------------------------------------------------------------------- + * The NyARToolkit is Java edition ARToolKit class library. + * Copyright (C)2008-2009 Ryo Iizuka + * + * 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 3 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 program. If not, see . + * + * For further information please contact. + * http://nyatla.jp/nyatoolkit/ + * or + * + */ +package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster; +import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster; +import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs; +import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader; +import jp.nyatla.nyartoolkit.core.types.NyARIntSize; + +/** + * YCbCr変換して、Y成分のグレースケールの値を計算します。 + * 変換式は、http://www.tyre.gotdns.org/を参考にしました。 + */ +public class NyARRasterFilter_Rgb2Gs_YCbCr implements INyARRasterFilter_RgbToGs +{ + private IdoFilterImpl _dofilterimpl; + public NyARRasterFilter_Rgb2Gs_YCbCr(int i_raster_type) throws NyARException + { + switch (i_raster_type) { + case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24: + this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24(); + break; + case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24: + default: + throw new NyARException(); + } + } + public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException + { + assert (i_input.getSize().isEqualSize(i_output.getSize()) == true); + this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize()); + } + + interface IdoFilterImpl + { + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException; + } + class IdoFilterImpl_BYTE1D_B8G8R8_24 implements IdoFilterImpl + { + /** + * This function is not optimized. + */ + public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException + { + assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24)); + + int[] out_buf = (int[]) i_output.getBuffer(); + byte[] in_buf = (byte[]) i_input.getBuffer(); + + int bp = 0; + for (int y = 0; y < i_size.h; y++){ + for (int x = 0; x < i_size.w; x++){ + out_buf[y*i_size.w+x]=(306*(in_buf[bp+2] & 0xff)+601*(in_buf[bp + 1] & 0xff)+117 * (in_buf[bp + 0] & 0xff))>>10; + bp += 3; + } + } + return; + } + } +} \ No newline at end of file diff --git a/src/jp/nyatla/nyartoolkit/core/squaredetect/Coord2SquareVertexIndexes.java b/src/jp/nyatla/nyartoolkit/core/squaredetect/Coord2SquareVertexIndexes.java new file mode 100644 index 0000000..47e8806 --- /dev/null +++ b/src/jp/nyatla/nyartoolkit/core/squaredetect/Coord2SquareVertexIndexes.java @@ -0,0 +1,160 @@ +/* + * PROJECT: NyARToolkit + * -------------------------------------------------------------------------------- + * This work is based on the original ARToolKit developed by + * Hirokazu Kato + * Mark Billinghurst + * HITLab, University of Washington, Seattle + * http://www.hitl.washington.edu/artoolkit/ + * + * The NyARToolkit is Java edition ARToolKit class library. + * Copyright (C)2008-2009 Ryo Iizuka + * + * 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 3 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 program. If not, see . + * + * For further information please contact. + * http://nyatla.jp/nyatoolkit/ + * or + * + */ +package jp.nyatla.nyartoolkit.core.squaredetect; + +/** + * 座標店集合(輪郭線)から、頂点リストを計算します。 + * + */ +public class Coord2SquareVertexIndexes +{ + private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ + private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter(); + private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter(); + public Coord2SquareVertexIndexes() + { + return; + } + /** + * 座標集合から、頂点候補になりそうな場所を4箇所探して、そのインデクス番号を返します。 + * @param i_x_coord + * @param i_y_coord + * @param i_coord_num + * @param i_area + * @param o_vertex + * @return + */ + public boolean getVertexIndexes(int[] i_x_coord, int[] i_y_coord, int i_coord_num, int i_area, int[] o_vertex) + { + final NyARVertexCounter wv1 = this.__getSquareVertex_wv1; + final NyARVertexCounter wv2 = this.__getSquareVertex_wv2; + int vertex1_index=getFarPoint(i_x_coord,i_y_coord,i_coord_num,0); + int prev_vertex_index=(vertex1_index+i_coord_num)%i_coord_num; + int v1=getFarPoint(i_x_coord,i_y_coord,i_coord_num,vertex1_index); + final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR; + + o_vertex[0] = vertex1_index; + + if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, vertex1_index, v1, thresh)) { + return false; + } + if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) { + return false; + } + + int v2; + if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) { + o_vertex[1] = wv1.vertex[0]; + o_vertex[2] = v1; + o_vertex[3] = wv2.vertex[0]; + } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) { + //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。 + if(v1>=vertex1_index){ + v2 = (v1-vertex1_index)/2+vertex1_index; + }else{ + v2 = ((v1+i_coord_num-vertex1_index)/2+vertex1_index)%i_coord_num; + } + if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, vertex1_index, v2, thresh)) { + return false; + } + if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, v1, thresh)) { + return false; + } + if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) { + o_vertex[1] = wv1.vertex[0]; + o_vertex[2] = wv2.vertex[0]; + o_vertex[3] = v1; + } else { + return false; + } + } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) { + //v2 = (v1+ end_of_coord)/2; + if(v1<=prev_vertex_index){ + v2 = (v1+prev_vertex_index)/2; + }else{ + v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num; + + } + if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, v1, v2, thresh)) { + return false; + } + if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, prev_vertex_index, thresh)) { + return false; + } + if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) { + o_vertex[1] = v1; + o_vertex[2] = wv1.vertex[0]; + o_vertex[3] = wv2.vertex[0]; + } else { + + return false; + } + } else { + return false; + } + return true; + } + /** + * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。 + * @param i_xcoord + * @param i_ycoord + * @param i_coord_num + * @return + */ + private static int getFarPoint(int[] i_coord_x, int[] i_coord_y,int i_coord_num,int i_point) + { + // + final int sx = i_coord_x[i_point]; + final int sy = i_coord_y[i_point]; + int d = 0; + int w, x, y; + int ret = 0; + for (int i = i_point+1; i < i_coord_num; i++) { + x = i_coord_x[i] - sx; + y = i_coord_y[i] - sy; + w = x * x + y * y; + if (w > d) { + d = w; + ret = i; + } + } + for (int i = 0; i < i_point; i++) { + x = i_coord_x[i] - sx; + y = i_coord_y[i] - sy; + w = x * x + y * y; + if (w > d) { + d = w; + ret = i; + } + } + return ret; + } +} \ No newline at end of file diff --git a/src/jp/nyatla/nyartoolkit/core/squaredetect/SquareContourDetector.java b/src/jp/nyatla/nyartoolkit/core/squaredetect/SquareContourDetector.java index b45c814..61a2f2a 100644 --- a/src/jp/nyatla/nyartoolkit/core/squaredetect/SquareContourDetector.java +++ b/src/jp/nyatla/nyartoolkit/core/squaredetect/SquareContourDetector.java @@ -41,18 +41,19 @@ import jp.nyatla.nyartoolkit.core.types.NyARIntSize; import jp.nyatla.nyartoolkit.core.types.NyARLinear; import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22; + + + public class SquareContourDetector { - private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ private final double[] _xpos; private final double[] _ypos; - private final int[] __detectMarker_mkvertex = new int[5]; - private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter(); - private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter(); + private final int[] __detectMarker_mkvertex = new int[4]; private final INyARPca2d _pca; private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22(); private final double[] __getSquareLine_mean=new double[2]; private final double[] __getSquareLine_ev=new double[2]; + private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes(); private final NyARObserv2IdealMap _dist_factor; public SquareContourDetector(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref) { @@ -61,7 +62,7 @@ public class SquareContourDetector this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size); - // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。 + // 輪郭バッファ this._pca=new NyARPca2d_MatrixPCA_O2(); this._xpos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height this._ypos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height @@ -72,9 +73,8 @@ public class SquareContourDetector { final int[] mkvertex = this.__detectMarker_mkvertex; - int vertex_1=getFarPoint(i_xcoord,i_ycoord,i_coord_num,0); // 頂点情報を取得 - if (!getSquareVertex(i_xcoord, i_ycoord, vertex_1, i_coord_num-1, i_label_area, mkvertex)) { + if (!this._coord2vertex.getVertexIndexes(i_xcoord, i_ycoord, i_coord_num, i_label_area, mkvertex)) { // 頂点の取得が出来なかったので破棄 return false; } @@ -93,22 +93,25 @@ public class SquareContourDetector final double[] mean=this.__getSquareLine_mean; final double[] ev=this.__getSquareLine_ev; - double w1; + double w1; for (int i = 0; i < 4; i++){ + //頂点を取得 + int ver1=i_mkvertex[i]; + int ver2=i_mkvertex[(i+1)%4]; int n,st,ed; //探索区間の決定 - if(i_mkvertex[i + 1]>=i_mkvertex[i]){ + if(ver2>=i_mkvertex[i]){ //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき - w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5; + w1 = (double) (ver2 - ver1 + 1) * 0.05 + 0.5; //探索区間の決定 - st = (int) (i_mkvertex[i]+w1); - ed = (int) (i_mkvertex[i+1] - w1); + st = (int) (ver1+w1); + ed = (int) (ver2 - w1); }else{ //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき - w1 = (double) (i_mkvertex[i + 1]+i_cood_num-i_mkvertex[i]+1)%i_cood_num * 0.05 + 0.5; + w1 = (double) (ver2+i_cood_num-ver1+1)%i_cood_num * 0.05 + 0.5; //探索区間の決定 - st = (int) (i_mkvertex[i]+w1)%i_cood_num; - ed = (int) (i_mkvertex[i+1]+i_cood_num-w1)%i_cood_num; + st = (int) (ver1+w1)%i_cood_num; + ed = (int) (ver2+i_cood_num-w1)%i_cood_num; } //探索区間数を確認 if(st<=ed){ @@ -137,126 +140,14 @@ public class SquareContourDetector final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex; final NyARIntPoint2d[] l_imvertex = o_square.imvertex; for (int i = 0; i < 4; i++) { - final NyARLinear l_line_i = l_line[i]; - final NyARLinear l_line_2 = l_line[(i + 3) % 4]; - w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx; - if (w1 == 0.0) { + //直線同士の交点計算 + if(!NyARLinear.crossPos(l_line[i],l_line[(i + 3) % 4],l_sqvertex[i])){ return false; } - l_sqvertex[i].x = (l_line_2.dx * l_line_i.c - l_line_i.dx * l_line_2.c) / w1; - l_sqvertex[i].y = (l_line_i.dy * l_line_2.c - l_line_2.dy * l_line_i.c) / w1; // 頂点インデクスから頂点座標を得て保存 l_imvertex[i].x = i_xcoord[i_mkvertex[i]]; l_imvertex[i].y = i_ycoord[i_mkvertex[i]]; } return true; } - - - private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex) - { - final NyARVertexCounter wv1 = this.__getSquareVertex_wv1; - final NyARVertexCounter wv2 = this.__getSquareVertex_wv2; - int prev_vertex_index=(i_vertex1_index+i_coord_num)%i_coord_num; - int v1=getFarPoint(i_x_coord,i_y_coord,i_coord_num,i_vertex1_index); - final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR; - - o_vertex[0] = i_vertex1_index; - - if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, i_vertex1_index, v1, thresh)) { - return false; - } - if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) { - return false; - } - - int v2; - if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) { - o_vertex[1] = wv1.vertex[0]; - o_vertex[2] = v1; - o_vertex[3] = wv2.vertex[0]; - } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) { - //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。 - if(v1>=i_vertex1_index){ - v2 = (v1-i_vertex1_index)/2+i_vertex1_index; - }else{ - v2 = ((v1+i_coord_num-i_vertex1_index)/2+i_vertex1_index)%i_coord_num; - } - if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, i_vertex1_index, v2, thresh)) { - return false; - } - if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, v1, thresh)) { - return false; - } - if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) { - o_vertex[1] = wv1.vertex[0]; - o_vertex[2] = wv2.vertex[0]; - o_vertex[3] = v1; - } else { - return false; - } - } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) { - //v2 = (v1+ end_of_coord)/2; - if(v1<=prev_vertex_index){ - v2 = (v1+prev_vertex_index)/2; - }else{ - v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num; - - } - if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, v1, v2, thresh)) { - return false; - } - if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, prev_vertex_index, thresh)) { - return false; - } - if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) { - o_vertex[1] = v1; - o_vertex[2] = wv1.vertex[0]; - o_vertex[3] = wv2.vertex[0]; - } else { - - return false; - } - } else { - return false; - } - o_vertex[4] = prev_vertex_index; - return true; - } - - /** - * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。 - * @param i_xcoord - * @param i_ycoord - * @param i_coord_num - * @return - */ - private static int getFarPoint(int[] i_coord_x, int[] i_coord_y,int i_coord_num,int i_point) - { - // - final int sx = i_coord_x[i_point]; - final int sy = i_coord_y[i_point]; - int d = 0; - int w, x, y; - int ret = 0; - for (int i = i_point+1; i < i_coord_num; i++) { - x = i_coord_x[i] - sx; - y = i_coord_y[i] - sy; - w = x * x + y * y; - if (w > d) { - d = w; - ret = i; - } - } - for (int i = 0; i < i_point; i++) { - x = i_coord_x[i] - sx; - y = i_coord_y[i] - sy; - w = x * x + y * y; - if (w > d) { - d = w; - ret = i; - } - } - return ret; - } } \ No newline at end of file diff --git a/src/jp/nyatla/nyartoolkit/core/types/NyARHistgram.java b/src/jp/nyatla/nyartoolkit/core/types/NyARHistgram.java index 1188630..78f16e4 100644 --- a/src/jp/nyatla/nyartoolkit/core/types/NyARHistgram.java +++ b/src/jp/nyatla/nyartoolkit/core/types/NyARHistgram.java @@ -53,7 +53,7 @@ public class NyARHistgram this.total_of_data-=s; } /** - * 指定したi_pos未満サンプルを0にします。 + * 指定したi_pos以上のサンプルを0にします。 * @param i_pos */ public void highCut(int i_pos) diff --git a/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java b/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java index 54c52e9..1297e03 100644 --- a/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java +++ b/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java @@ -56,4 +56,21 @@ public class NyARLinear this.c=i_source.c; return; } + /** + * 2直線の交点を計算します。 + * @param l_line_i + * @param l_line_2 + * @param o_point + * @return + */ + public final static boolean crossPos(NyARLinear l_line_i,NyARLinear l_line_2,NyARDoublePoint2d o_point) + { + final double w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx; + if (w1 == 0.0) { + return false; + } + o_point.x = (l_line_2.dx * l_line_i.c - l_line_i.dx * l_line_2.c) / w1; + o_point.y = (l_line_i.dy * l_line_2.c - l_line_2.dy * l_line_i.c) / w1; + return true; + } } -- 2.11.0