From 01d00f148a47185f95a855a4311753b985255fe9 Mon Sep 17 00:00:00 2001 From: nyatla Date: Tue, 30 Nov 2010 13:46:14 +0000 Subject: [PATCH] git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@693 7cac0a50-4618-4814-88d0-24b83990f816 --- .../jp/nyatla/nyartoolkit/dev/LabelingCamera.java | 951 +++++++++++++++++++++ .../jp/nyatla/nyartoolkit/dev/LabelingTest.java | 103 +++ .../dev/NyARColorPatt_DiagonalRatio.java | 667 +++++++++++++++ .../nyartoolkit/dev/NyARSquareDetector_Vector.java | 358 ++++++++ .../nyartoolkit/dev/OptimizeCompareTest.java | 293 +++++++ .../jp/nyatla/nyartoolkit/dev/PattPickupTest.java | 232 +++++ .../jp/nyatla/nyartoolkit/dev/PattPickupTestS.java | 104 +++ .../src.dev/jp/nyatla/nyartoolkit/dev/Solver.java | 144 ++++ 8 files changed, 2852 insertions(+) create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java create mode 100644 sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/Solver.java diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java new file mode 100644 index 0000000..8e6d72a --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java @@ -0,0 +1,951 @@ +/* このソースは実験用のソースです。 + * 動いたり動かなかったりします。 + * + */ +package jp.nyatla.nyartoolkit.dev; + +import javax.media.*; + +import javax.media.util.BufferToImage; +import javax.media.format.*; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.jmf.utils.*; + +import jp.nyatla.nyartoolkit.core.*; + +import java.awt.*; + +import jp.nyatla.nyartoolkit.core.labeling.*; +import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage; +import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel; +import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack; +import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit; +import jp.nyatla.nyartoolkit.core.match.*; +import jp.nyatla.nyartoolkit.core.param.*; +import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d; +import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2; +import jp.nyatla.nyartoolkit.core.pickup.*; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster; +import jp.nyatla.nyartoolkit.core.rasterfilter.*; +import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack; +import jp.nyatla.nyartoolkit.core.transmat.*; +import jp.nyatla.nyartoolkit.core.types.*; +import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22; +import jp.nyatla.nyartoolkit.core.types.stack.*; + + +///** +// * QRコードのシンボルを結びつける偉いクラス +// * +// */ +//class NyQrCodeSymbolBinder +//{ +// LabelingBufferdImage bimg; +// +// NyARIntPoint[][] _sqare; +// /** +// * 最小の三角形を構成する頂点セットを得る +// * @param i_s0 +// * @param i_s1 +// * @param i_s2 +// * @param o_vertex +// */ +// public static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id) +// { +// //辺の長さが最小になる頂点の組合せを探す +// int d; +// int x,y; +// int dmax=0x7fffffff; +// final NyARIntPoint[] vertex0=i_sqare[0].imvertex; +// final NyARIntPoint[] vertex1=i_sqare[1].imvertex; +// final NyARIntPoint[] vertex2=i_sqare[2].imvertex; +// for(int i=0;i<4;i++) +// { +// for(int i2=0;i2<4;i2++) +// { +// for(int i3=0;i3<4;i3++){ +// x=vertex0[i].x-vertex2[i3].x; +// y=vertex0[i].y-vertex2[i3].y; +// d=x*x+y*y; +// x=vertex1[i2].x-vertex2[i3].x; +// y=vertex1[i2].y-vertex2[i3].y; +// d+=x*x+y*y; +// x=vertex1[i2].x-vertex0[i].x; +// y=vertex1[i2].y-vertex0[i].y; +// d+=x*x+y*y; +// if(d391] + * + * @param i_cparam + * @return + * @throws NyARException + */ + private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException + { + final NyARLinear[] l_line = o_square.line; + final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref; + final NyARDoubleMatrix22 evec=this.__getSquareLine_evec; + final NyARDoublePoint2d mean=this.__getSquareLine_mean; + final NyARDoublePoint2d ev=this.__getSquareLine_ev; + + + for (int i = 0; i < 4; i++) { + final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5; + final int st = (int) (i_mkvertex[i] + w1); + final int ed = (int) (i_mkvertex[i + 1] - w1); + final int n = ed - st + 1; + if (n < 2) { + // nが2以下でmatrix.PCAを計算することはできないので、エラー + return false; + } + //主成分分析する。 + this._pca.pcaWithDistortionFactor(i_xcoord, i_ycoord, st, n,dist_factor, evec, ev,mean); + final NyARLinear l_line_i = l_line[i]; + l_line_i.run = evec.m01;// line[i][0] = evec->m[1]; + l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0]; + l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]); + } + + 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]; + final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise; + if (w1 == 0.0) { + return false; + } + l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1; + l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1; + // 頂点インデクスから頂点座標を得て保存 + l_imvertex[i].x = i_xcoord[i_mkvertex[i]]; + l_imvertex[i].y = i_ycoord[i_mkvertex[i]]; + } + return true; + } + /** + * 辺からの対角線が最長になる点を対角線候補として返す。 + * + * @param i_xcoord + * @param i_ycoord + * @param i_coord_num + * @return + */ + private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num) + { + final int sx = i_xcoord[0]; + final int sy = i_ycoord[0]; + int d = 0; + int w, x, y; + int ret = 0; + for (int i = 1; i < i_coord_num; i++) { + x = i_xcoord[i] - sx; + y = i_ycoord[i] - sy; + w = x * x + y * y; + if (w > d) { + d = w; + ret = i; + } + // ここでうまく終了条件入れられないかな。 + } + return ret; + } + + private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter(); + + private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter(); + + /** + * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。 + * + * @param i_x_coord + * @param i_y_coord + * @param i_vertex1_index + * @param i_coord_num + * @param i_area + * @param o_vertex + * 要素数はint[4]である事 + * @return + */ + 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; + final int end_of_coord = i_vertex1_index + i_coord_num - 1; + final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0]; + final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0]; + int dmax = 0; + int v1 = i_vertex1_index; + for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;icoord_num-1;i++) + // { + final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy); + if (d > dmax) { + dmax = d; + v1 = i; + } + } + 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_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)< + // 0 ) { + return false; + } + if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2) + // < 0) { + 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にあると予想して、検索する。 + v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index; + if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) { + return false; + } + if (!wv2.getVertex(i_x_coord, i_y_coord, 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-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index; + v2 = (v1 + end_of_coord) / 2; + + if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) { + return false; + } + if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, 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] = end_of_coord; + return true; + } + /** + * QRコードのエッジ特徴を持つラベルであるかを調べる + * @param buf + * @param index_table + * @param i_label + * @return + */ + private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label) + { + int tx, bx; + int w; + int i_label_id = i_label.id; + int[] limage_j; + final int clip_l = i_label.clip_l; + final int clip_b = i_label.clip_b; + final int clip_r = i_label.clip_r; + final int clip_t = i_label.clip_t; + + tx = bx = 0; + // 上接点(→) + limage_j = buf[clip_t]; + for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) { + w = limage_j[i]; + if (w > 0 && index_table[w - 1] == i_label_id) { + tx = i; + break; + } + } + // 下接点(←) + limage_j = buf[clip_b]; + for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) { + w = limage_j[i]; + if (w > 0 && index_table[w - 1] == i_label_id) { + bx = i; + break; + } + } + final int cx = (clip_l + clip_r) / 2; + final int cy = (clip_t + clip_b) / 2; + // 横断チェック(中心から線を引いて、101になるかしらべる) + if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) { + return false; + } + if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) { + return false; + } + return true; + } + + /** + * 対角線のパターンを調べる。 + * + * @param buf + * @param i_px1 + * @param i_py1 + * @param i_px2 + * @param i_py2 + * @return + */ + private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2) + { + int sub_y = i_py2 - i_py1; + int sub_x = i_px2 - i_px1; + // 黒 + int i = 0; + for (; i < sub_y; i++) { + int yp = i_py1 + i; + int xp = i_px1 + i * sub_x / sub_y; + if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) { + break; + } + + } + if (i == sub_y) { + return false; + } + // 白 + for (; i < sub_y; i++) { + int yp = i_py1 + i; + int xp = i_px1 + i * sub_x / sub_y; + if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) { + break; + } + + } + if (i == sub_y) { + return false; + } + // 黒 + for (; i < sub_y; i++) { + int yp = i_py1 + i; + int xp = i_px1 + i * sub_x / sub_y; + if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) { + break; + } + + } + if (i != sub_y) { + return false; + } + // 端まで到達したらOK + return true; + } + +} + + +public class LabelingCamera extends Frame implements JmfCaptureListener +{ + private final String camera_file = "../Data/camera_para.dat"; + + private JmfNyARRaster_RGB _raster; + + private JmfCameraCapture capture; + private NyARParam ap; + public LabelingCamera() throws NyARException, NyARException + { + setBounds(0, 0, 640 + 64, 720 + 64); + // キャプチャの準備 + capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB); + capture.setCaptureListener(this); + + // キャプチャイメージ用のラスタを準備 + this._raster = new JmfNyARRaster_RGB(320, 240); + + // AR用カメラパラメタファイルをロード + ap = new NyARParam(); + ap.loadARParamFromFile(camera_file); + ap.changeScreenSize(320, 240); + + + } + + // そのラベルが特徴点候補か返す。 + + private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240); + + private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240); + + private NyARLabelingImage _limage = new NyARLabelingImage(320, 240); + + private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240); + + private NyARRasterFilter_ARToolkitThreshold filter_gs2bin; + + public void onUpdateBuffer(Buffer i_buffer) + { + NyARRasterFilter_AreaAverage gs2bin=new NyARRasterFilter_AreaAverage(); + + try { + // キャプチャしたバッファをラスタにセット + _raster.setBuffer(i_buffer); + + Graphics g = getGraphics(); + // キャプチャ画像 + BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat()); + Image img = b2i.createImage(i_buffer); + this.getGraphics().drawImage(img, 32, 32, this); + + // 画像1 + INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve(); + filter_rgb2gs.doFilter(_raster, _gsraster1); + this._bimg.drawImage(this._gsraster1); + this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this); + + + // 画像2 + gs2bin.doFilter(_gsraster1, _binraster1); + this._bimg.drawImage(_binraster1); + this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this); + + // 画像3 + NyARLabelingImage limage = new NyARLabelingImage(320, 240); + NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit(); + labeling.attachDestination(limage); + labeling.labeling(_binraster1); + this._bimg.drawImage(this._gsraster1); + NyARLabelingLabel[] labels = limage.getLabelStack().getArray(); + + NyARSquareStack stack = new NyARSquareStack(100); + NyARQRCodeDetector detect = new NyARQRCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240)); + detect.bimg=this._bimg; + + detect.detectMarker(_binraster1, stack); + for (int i = 0; i < stack.getLength(); i++) { + NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray(); + int[] xp=new int[4]; + int[] yp=new int[4]; + for(int i2=0;i2<4;i2++){ + xp[i2]=square_ptr[i].imvertex[i2].x; + yp[i2]=square_ptr[i].imvertex[i2].y; + } + this._bimg.getGraphics().setColor(Color.RED); + this._bimg.getGraphics().drawPolygon(xp, yp,2); + } + this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this); + + // 画像3 + // threshold.debugDrawHistogramMap(_workraster, _workraster2); + // this._bimg2.setImage(this._workraster2); + // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this); + + // 画像4 + // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15); + // threshold.analyzeRaster(_gsraster1); + // filter_gs2bin=new NyARRasterFilter_AreaAverage(); + // filter_gs2bin.doFilter(_gsraster1, _binraster1); + // this._bimg.drawImage(_binraster1); + + // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000); + // detector.analyzeRaster(_binraster1); + + // this._bimg.overlayData(detector.geResult()); + + // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this); + // 画像5 + + /* + * threshold2.debugDrawHistogramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2, + * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this); + */ + + // this.getGraphics().drawImage(this._bimg, 32, 32, this); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private INyARLabeling labelingFactory(int i_idx) + { + // switch(i_idx){ + // case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;} + // case 1:{return new NyLineLabeling();} + // } + return null; + + } + + private void startCapture() + { + try { + capture.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) + { + try { + LabelingCamera mainwin = new LabelingCamera(); + mainwin.setVisible(true); + mainwin.startCapture(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java new file mode 100644 index 0000000..1ac6285 --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java @@ -0,0 +1,103 @@ + +package jp.nyatla.nyartoolkit.dev; + +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Date; + +import javax.imageio.ImageIO; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.NyARLabeling_Rle; +import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.NyARRleLabelFragmentInfo; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster; +import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_RGB; +import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.NyARRasterFilter_Rgb2Gs_RgbAve; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARContourPickup; +import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d; +import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d; + +import jp.nyatla.nyartoolkit.utils.j2se.*; + + +class Main_Labeling extends NyARLabeling_Rle +{ + private NyARIntPoint2d[] vx=NyARIntPoint2d.createArray(100); + public NyARGrayscaleRaster current_gs; + public int current_th; + public Main_Labeling(int i_width,int i_height) throws NyARException + { + super(i_width,i_height); + } + /** + * @Override + */ + protected void onLabelFound(NyARRleLabelFragmentInfo iRefLabel)throws NyARException + { + NyARContourPickup ct=new NyARContourPickup(); + Date d2 = new Date(); + + for(int i=0;i<100000;i++){ + int c=ct.getContour(this.current_gs,this.current_th, iRefLabel.entry_x,iRefLabel.clip_t, this.vx); + } + Date d = new Date(); + NyARDoublePoint3d ang=new NyARDoublePoint3d(); + System.out.println(d.getTime() - d2.getTime()); + + return; + } +} + +/** + * ラべリングと、輪郭線抽出のテストコード + * @author nyatla + * + */ +public class LabelingTest extends Frame +{ + private final String source_file = "../Data/ラべリングのエントリポイントエラー.png"; + private BufferedImage _src_image; + public LabelingTest() throws NyARException,Exception + { + this._src_image = ImageIO.read(new File(source_file)); + + INyARRgbRaster ra =new NyARRgbRaster_RGB(this._src_image.getWidth(),this._src_image.getHeight()); + NyARRasterImageIO.copy(this._src_image,ra); + //GS値化 + NyARGrayscaleRaster gs=new NyARGrayscaleRaster(this._src_image.getWidth(),this._src_image.getHeight()); + NyARRasterFilter_Rgb2Gs_RgbAve filter=new NyARRasterFilter_Rgb2Gs_RgbAve(ra.getBufferType()); + filter.doFilter(ra,gs); + //ラべリングの試験 + Main_Labeling lv=new Main_Labeling(ra.getWidth(),ra.getHeight()); + lv.current_gs=gs; + lv.current_th=230; + lv.labeling(gs,lv.current_th); + //画像をストア + + + this.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) + { + System.exit(0); + } + }); + //ペイント + } + + public static void main(String[] args) + { + try { + LabelingTest app = new LabelingTest(); + app.setVisible(true); + app.setBounds(0, 0, 640, 480); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java new file mode 100644 index 0000000..de95d6d --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java @@ -0,0 +1,667 @@ +/* + * PROJECT: NyARToolkit + * -------------------------------------------------------------------------------- + * The NyARToolkit is Java version ARToolkit class library. + * Copyright (C)2008 R.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 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://nyatla.jp/nyatoolkit/ + * + * + */ +package jp.nyatla.nyartoolkit.dev; + + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.raster.rgb.*; +import jp.nyatla.nyartoolkit.core.rasterreader.*; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare; +import jp.nyatla.nyartoolkit.core.types.*; +import jp.nyatla.nyartoolkit.core.types.matrix.*; +import jp.nyatla.nyartoolkit.core.pickup.*; + + +class NyARDoubleLine2d +{ + double x,y; + void set(NyARDoublePoint2d i_point_a,NyARDoublePoint2d i_point_b) + { + this.x=i_point_a.x-i_point_b.x; + this.y=i_point_a.y-i_point_b.y; + return; + } + void add(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result) + { + o_result.x=this.x+i_param.x; + o_result.y=this.y+i_param.y; + return; + } + void sum(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result) + { + o_result.x=this.x-i_param.x; + o_result.y=this.y-i_param.y; + return; + } + /** + * i_paramとの外積を計算する。 + * @param i_param + * @return + */ + double cross(NyARDoubleLine2d i_param) + { + return this.x*i_param.y-this.y*i_param.x; + } + /** + * i_paramとの内積を計算する + * @param i_param + * @return + */ + double dot(NyARDoubleLine2d i_param) + { + return this.x*i_param.x+this.y*i_param.y; + } + /** + * このベクトルの絶対値を計算する + * @param i_param + * @return + */ + double dist() + { + return Math.sqrt(this.x*this.x+this.y*this.y); + } + + +} + + +class LineParam +{ + public double a; + public double b; + public static LineParam[] createArray(int i_length) + { + LineParam[] result=new LineParam[i_length]; + for(int i=result.length-1;i>=0;i--){ + result[i]=new LineParam(); + } + return result; + } +} + +class Complex +{ + public double i; + public double r; + public Complex() + { + } + public Complex(double i_r,double i_i) + { + this.r=i_r; + this.i=i_i; + } + public void add(Complex i_v) + { + this.r+=i_v.r; + this.i+=i_v.i; + } + public void sub(Complex i_v) + { + this.r-=i_v.r; + this.i-=i_v.i; + } + public void sub(Complex i_v1,Complex i_v2) + { + this.r=i_v1.r-i_v2.r; + this.i=i_v1.i-i_v2.i; + } + + public void mul(Complex i_v) + { + double r,i; + r=this.r; + i=this.i; + final double d2=Math.sqrt(r*r+i*i); + final double s2=Math.acos(r/d2); + r=i_v.r; + i=i_v.i; + final double d1=Math.sqrt(r*r+i*i); + final double s1=Math.acos(r/d1); + + this.r=d1*d2*Math.cos(s2+s1); + this.i=d1*d2*Math.sin(s2+s1); + return; + } + public void div(Complex i_v) + { + double r,i; + r=this.r; + i=this.i; + final double d2=Math.sqrt(r*r+i*i); + final double s2=Math.acos(r/d2); + r=i_v.r; + i=i_v.i; + final double d1=Math.sqrt(r*r+i*i); + final double s1=Math.acos(r/d1); + + this.r=d2/d1*Math.cos(s2/s1); + this.i=d2/d1*Math.sin(s2/s1); + return; + } + public void pow(Complex i_v,double i_base) + { + double r,i; + r=i_v.r; + i=i_v.i; + double d=Math.sqrt(r*r+i*i); + final double s=Math.acos(r/d)*i_base; + d=Math.pow(d,i_base); + this.r=d*Math.cos(s); + this.i=d*Math.sin(s); + } + public void sqrt(Complex i_v) + { + double r,i; + r=i_v.r; + i=i_v.i; + double d=Math.sqrt(r*r+i*i); + final double s=Math.acos(r/d)*0.5; + d=Math.sqrt(d); + this.r=d*Math.cos(s); + this.i=d*Math.sin(s); + } + public double dist() + { + return Math.sqrt(this.r*this.r+this.i*this.i); + } + +} + + +/** + * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。 + * 演算順序を含む最適化をしたもの + * + */ +public class NyARColorPatt_DiagonalRatio implements INyARColorPatt +{ + private int[] _patdata; + private NyARBufferReader _buf_reader; + private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader; + private NyARIntSize _size; + + public final int getWidth() + { + return this._size.w; + } + + public final int getHeight() + { + return this._size.h; + } + + public final NyARIntSize getSize() + { + return this._size; + } + + public final INyARBufferReader getBufferReader() + { + return this._buf_reader; + } + + public final INyARRgbPixelReader getRgbPixelReader() + { + return this._pixelreader; + } + NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44(); + /** + * @param i_width + * @param i_height + */ + public NyARColorPatt_DiagonalRatio(int i_model) + { + int resolution=(1<320||vertex_map[i][i2].y>240||vertex_map[i][i2].x<0||vertex_map[i][i2].y<0) + { + //System.out.println(vertex_map[i][i2].x+","+vertex_map[i][i2].y); + this._patdata[i2+i*this._size.w]=0; + continue; + } + reader.getPixel((int)vertex_map[i][i2].x,(int)vertex_map[i][i2].y,rgb_tmp); + this._patdata[i2+i*this._size.w]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2]; + } + } + return true; + } + /** + * 直線をscaleで2^n分割した配列を計算する。 + * @param i_p1 + * @param i_p2 + * @param o_param + * @return + */ + private void solvLinePointArray4(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result) + { + //分割直線の計算(2=2分割,3=4分割,4=8分割) + //中心コピー + o_result[0][0].setValue(i_center); + + + //[0]->[1]のベクトルを計算 + NyARDoublePoint2d vec01=new NyARDoublePoint2d(); + NyARDoublePoint2d vec12=new NyARDoublePoint2d(); + NyARDoublePoint2d vec03=new NyARDoublePoint2d(); + NyARDoublePoint2d vec32=new NyARDoublePoint2d(); + vec01.vecSub(i_vertex[1],i_vertex[0]); + vec12.vecSub(i_vertex[2],i_vertex[1]); + vec03.vecSub(i_vertex[3],i_vertex[0]); + vec32.vecSub(i_vertex[2],i_vertex[3]); + + //中心点から[0]->[1]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d(); + vec01_ep.vecAdd(vec01,i_center); + //中心点から[3]->[2]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d(); + vec32_ep.vecAdd(vec32,i_center); + //平均値 + NyARDoublePoint2d cx_e=new NyARDoublePoint2d(); + cx_e.x=(vec01_ep.x+vec32_ep.x)/2; + cx_e.y=(vec01_ep.y+vec32_ep.y)/2; + + //ベクトル[1]->[2]との交差点を計算 + solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]); + //ベクトル[3]->[0]との交差点を計算 + solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]); + + + + //中心点から[1]->[2]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d(); + vec12_ep.vecAdd(vec12,i_center); + //中心点から[0]->[3]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d(); + vec03_ep.vecAdd(vec03,i_center); + //平均値 + NyARDoublePoint2d cx_e2=new NyARDoublePoint2d(); + cx_e2.x=(vec12_ep.x+vec03_ep.x)/2; + cx_e2.y=(vec12_ep.y+vec03_ep.y)/2; + + //cx_e2とベクトル[0]->[1]との交差点を計算 + solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]); + //ベクトル[3]->[2]との交差点を計算 + solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]); + + + + + return; + } + private void solvLinePointArray(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result) + { + //中心コピー + o_result[0][0].setValue(i_center); + + //[0]+[1]+[c] + NyARDoublePoint2d vt=new NyARDoublePoint2d(); + vt.x=(i_vertex[0].x+i_vertex[1].x)/2; + vt.y=(i_vertex[0].y+i_vertex[1].y)/2; + //[2]+[3]+[c] + NyARDoublePoint2d vb=new NyARDoublePoint2d(); + vb.x=(i_vertex[2].x+i_vertex[3].x)/2; + vb.y=(i_vertex[2].y+i_vertex[3].y)/2; + + vt.vecSub(vb); + vt.vecAdd(i_center); + + //[0][1]->[2][3]ベクトル + solvCrossPoint(vt,i_center,i_vertex[0],i_vertex[1],o_result[1][2]); + //[0][1]->[2][3]ベクトル:v[3][0] + solvCrossPoint(vt,i_center,i_vertex[3],i_vertex[2],o_result[1][0]); + + + +/* + + //[0]->[1]のベクトルを計算 + NyARDoublePoint2d vec01=new NyARDoublePoint2d(); + NyARDoublePoint2d vec12=new NyARDoublePoint2d(); + NyARDoublePoint2d vec03=new NyARDoublePoint2d(); + NyARDoublePoint2d vec32=new NyARDoublePoint2d(); + vec01.vecSub(i_vertex[1],i_vertex[0]); + vec12.vecSub(i_vertex[2],i_vertex[1]); + vec03.vecSub(i_vertex[3],i_vertex[0]); + vec32.vecSub(i_vertex[2],i_vertex[3]); + + //中心点から[0]->[1]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d(); + vec01_ep.vecSum(vec01,i_center); + //中心点から[3]->[2]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d(); + vec32_ep.vecSum(vec32,i_center); + //平均値 + NyARDoublePoint2d cx_e=new NyARDoublePoint2d(); + cx_e.x=(vec01_ep.x+vec32_ep.x)/2; + cx_e.y=(vec01_ep.y+vec32_ep.y)/2; + + //ベクトル[1]->[2]との交差点を計算 + solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]); + //ベクトル[3]->[0]との交差点を計算 + solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]); + + + + //中心点から[1]->[2]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d(); + vec12_ep.vecSum(vec12,i_center); + //中心点から[0]->[3]と平行なベクトルの終点を計算 + NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d(); + vec03_ep.vecSum(vec03,i_center); + //平均値 + NyARDoublePoint2d cx_e2=new NyARDoublePoint2d(); + cx_e2.x=(vec12_ep.x+vec03_ep.x)/2; + cx_e2.y=(vec12_ep.y+vec03_ep.y)/2; + + //cx_e2とベクトル[0]->[1]との交差点を計算 + solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]); + //ベクトル[3]->[2]との交差点を計算 + solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]); + + +*/ + + return; + } + + + + private void solvLinePointArray3(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result) + { + NyARDoublePoint2d scale=new NyARDoublePoint2d(); + //分割直線の計算(2=2分割,3=4分割,4=8分割) + int d=i_div; + NyARDoublePoint2d[] r=o_result[d/2]; + //対角線Aを計算 + r[0].x=i_vertex[0].x; + r[0].y=i_vertex[0].y; + r[d].x=i_vertex[2].x; + r[d].y=i_vertex[2].y; + scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x); + scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y); + + solvLinePointArray_b(scale,0,d,r); + //対角線上にコピー + for(int i=0;i<=d;i++){ + o_result[i][i].x=r[i].x; + o_result[i][i].y=r[i].y; + } + //対角線Bを計算 + r[0].x=i_vertex[3].x; + r[0].y=i_vertex[3].y; + r[d].x=i_vertex[1].x; + r[d].y=i_vertex[1].y; + scale.x=(i_canter.x-i_vertex[3].x)/(i_vertex[1].x-i_vertex[3].x); + scale.y=(i_canter.y-i_vertex[3].y)/(i_vertex[1].y-i_vertex[3].y); + solvLinePointArray_b(scale,0,d,r); + //対角線上にコピー + for(int i=0;i<=d;i++){ + o_result[d-i][i].x=r[i].x; + o_result[d-i][i].y=r[i].y; + } + //マップ作成 + for(int i=0;i<=d;i++){ + final NyARDoublePoint2d y1=o_result[i][i]; + final NyARDoublePoint2d y2=o_result[d-i][i]; + if(i==d/2){ + continue; + } + for(int i2=0;i2<=d;i2++){ + if(i==i2){ + continue; + } + if(i==d-i2){ + continue; + } + if(i2==d/2){ + continue; + } + final NyARDoublePoint2d x1=o_result[i2][i2]; + final NyARDoublePoint2d x2=o_result[i2][d-i2]; + solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]); + } + } + + return; + } + /** + * 直線をscaleで2^n分割した配列を計算する。 + * @param i_p1 + * @param i_p2 + * @param o_param + * @return + */ + private void solvLinePointArray2(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result) + { + NyARDoublePoint2d scale=new NyARDoublePoint2d(); + //分割直線の計算(2=2分割,3=4分割,4=8分割) + int d=i_div; + NyARDoublePoint2d[] r=o_result[d/2]; + //対角線Aを計算 + r[0].x=i_vertex[0].x; + r[0].y=i_vertex[0].y; + r[d].x=i_vertex[2].x; + r[d].y=i_vertex[2].y; +// scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x); +// scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y); + double sx,kx,lx,sy,ky,ly; + + sx=i_vertex[0].x; + kx=solvK(i_canter.x-sx,i_vertex[2].x-sx); + lx=solvL(kx,i_canter.x-sx); + + sy=i_vertex[0].y; + ky=solvK(i_canter.y-sy,i_vertex[2].y-sy); + ly=solvL(kx,i_canter.y-sy); + + solvLinePointArray_b(scale,0,d,r); + //対角線上にコピー + for(int i=0;i<=d;i++){ + o_result[i][i].x=sx+kx*lx; + o_result[i][i].y=sy+ky*ly; + kx*=kx; + ky*=ky; + } + + sx=i_vertex[3].x; + kx=solvK(i_canter.x-sx,i_vertex[1].x-sx); + lx=solvL(kx,i_canter.x-sx); + + sy=i_vertex[3].y; + ky=solvK(i_canter.y-sy,i_vertex[1].y-sy); + ly=solvL(kx,i_canter.y-sy); + + solvLinePointArray_b(scale,0,d,r); + //対角線上にコピー + for(int i=0;i<=d;i++){ + o_result[d-i][i].x=sx+kx*lx; + o_result[d-i][i].y=sy+ky*ly; + kx*=kx; + ky*=ky; + } + //マップ作成 + for(int i=0;i<=d;i++){ + final NyARDoublePoint2d y1=o_result[i][i]; + final NyARDoublePoint2d y2=o_result[d-i][i]; + if(i==d/2){ + continue; + } + for(int i2=0;i2<=d;i2++){ + if(i==i2){ + continue; + } + if(i==d-i2){ + continue; + } + if(i2==d/2){ + continue; + } + final NyARDoublePoint2d x1=o_result[i2][i2]; + final NyARDoublePoint2d x2=o_result[i2][d-i2]; + solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]); + } + } + + return; + } + + private void solvLinePointArray_b(NyARDoublePoint2d i_scale,int i_si,int i_ei,NyARDoublePoint2d[] o_result) + { + int ci=(i_ei-i_si)/2+i_si; + o_result[ci].x=i_scale.x*(o_result[i_ei].x-o_result[i_si].x)+o_result[i_si].x; + o_result[ci].y=i_scale.y*(o_result[i_ei].y-o_result[i_si].y)+o_result[i_si].y; + + if(ci-i_si==1){ + return; + } + solvLinePointArray_b(i_scale,i_si,ci,o_result); + solvLinePointArray_b(i_scale,ci,i_ei,o_result); + return; + } + + private void solvCrossPoint(NyARIntPoint2d i_p1,NyARIntPoint2d i_p2,NyARIntPoint2d i_p3,NyARIntPoint2d i_p4,NyARDoublePoint2d o_result) + { + NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2); + NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4); + va.vecSub(i_p1); + vb.vecSub(i_p3); + o_result.setValue(i_p3); + o_result.vecSub(i_p1); + va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va)); + o_result.setValue(va); + o_result.vecAdd(i_p1); + return; + //V a=p2-p1; + //V b=p4-p3; + //return a1 + a * cross(b, b1-a1) / cross(b, a); + } + private void solvCrossPoint(NyARDoublePoint2d i_p1,NyARDoublePoint2d i_p2,NyARDoublePoint2d i_p3,NyARDoublePoint2d i_p4,NyARDoublePoint2d o_result) + { + NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2); + NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4); + va.vecSub(i_p1); + vb.vecSub(i_p3); + o_result.setValue(i_p3); + o_result.vecSub(i_p1); + va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va)); + o_result.setValue(va); + o_result.vecAdd(i_p1); + return; + //V a=p2-p1; + //V b=p4-p3; + //return a1 + a * cross(b, b1-a1) / cross(b, a); + } + double pow_1_3(double a) + { + double x = Math.pow(a, 1./3); + return (2*x+a/x/x)/3; // modifier + } + /* + * + * + * */ + //(Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))-(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z))^(1/3)+(-((Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z)+Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))))^(1/3)-Z/(3*Z) + private double solvK(double mp,double vp) + { + double Z=mp/vp; + double a=(Z-1); + double b=(3.0*Z); + double c=(a*Z); + double d=(2.0*Z*Z);//(2*Z^2) + double e=(4.0*Z*Z);//(4*Z^2) + double f=((-Z)/b); + double g=(Z*f*f+Z*f*f*f-c/b+Z-1);//(Z*f^2+Z*f^3-c/b+Z-1) + double h=(3.0*Z*f*f-d/b+Z-1.0);//(3*Z*f^2-d/b+Z-1) + double i=(h/Z); + Complex j=new Complex(0,i*i*i/27.0+g*g/e);//(0,i*i*i/27.0+g*g/e); +// j.r=0; +// j.i=Math.sqrt(-i*i*i/27.0+g*g/e); +// j.sqrt(j); + Complex k=new Complex(); + k.r=j.r-g/(2.0*Z); + k.i=j.i; + Complex l=new Complex(); + l.r=-(g/(2.0*Z)+j.r); + l.i=-j.i; + + k.pow(k,1.0/3); + l.pow(l,1.0/3); + double fi=k.dist()+l.dist()-Z/b; + return fi; + } + private double solvL(double k,double mp) + { + return 100/(1+k*k+k*k*k+k); + } + + + public static void main(String[] args) + { + + try { + NyARColorPatt_DiagonalRatio t = new NyARColorPatt_DiagonalRatio(3); + double k=t.solvK(60,100); + double l=t.solvL(k,60); + + // t.Test_arGetVersion(); + NyARSquare s=new NyARSquare(); + s.sqvertex[0].x=10; + s.sqvertex[0].y=10; + s.sqvertex[1].x=90; + s.sqvertex[1].y=0; + s.sqvertex[2].x=100; + s.sqvertex[2].y=100; + s.sqvertex[3].x=0; + s.sqvertex[3].y=100; + //t.getLineCrossPoint(s); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java new file mode 100644 index 0000000..472489c --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java @@ -0,0 +1,358 @@ +/* + * 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.dev; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.labeling.NyARLabelOverlapChecker; +import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*; +import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARCoord2SquareVertexIndexes; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare; +import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d; +import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d; +import jp.nyatla.nyartoolkit.core.types.NyARIntSize; +import jp.nyatla.nyartoolkit.core.types.NyARLinear; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.squaredetect.*; +import jp.nyatla.nyartoolkit.core.param.*; + + + +/** + * + * + */ +public class NyARSquareDetector_Vector +{ + private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000 + private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70 + private final int _width; + private final int _height; + private final int[] _xcoord; + private final int[] _ycoord; + + private final NyARLabeling_Rle _labeling; + + private final NyARLabelOverlapChecker _overlap_checker = new NyARLabelOverlapChecker(32,NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo.class); + private final SquareContourDetector_Vector _sqconvertor; + private final NyARContourPickup _cpickup=new NyARContourPickup(); + private final NyARRleLabelFragmentInfoPtrStack _stack; + + private final int _max_coord; + /** + * 最大i_squre_max個のマーカーを検出するクラスを作成する。 + * + * @param i_param + */ + public NyARSquareDetector_Vector(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException + { + this._width = i_size.w; + this._height = i_size.h; + //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。 + this._labeling = new NyARLabeling_Rle(this._width,this._height); + this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN); + this._sqconvertor=new SquareContourDetector_Vector(i_size,i_dist_factor_ref); + this._stack=new NyARRleLabelFragmentInfoPtrStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数 + + + // 輪郭の最大長は画面に映りうる最大の長方形サイズ。 + int number_of_coord = (this._width + this._height) * 2; + + // 輪郭バッファ + this._max_coord = number_of_coord; + this._xcoord = new int[number_of_coord]; + this._ycoord = new int[number_of_coord]; + return; + } + + /** + * arDetectMarker2を基にした関数 + * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。 + * directionの確定は行いません。 + * @param i_raster + * 解析する2値ラスタイメージを指定します。 + * @param o_square_stack + * 抽出した正方形候補を格納するリスト + * @throws NyARException + */ + public final void detectMarker(NyARGrayscaleRaster i_gs,int i_th,NyARSquareStack o_square_stack) throws NyARException + { + final NyARRleLabelFragmentInfoPtrStack flagment=this._stack; + final NyARLabelOverlapChecker overlap = this._overlap_checker; + + // マーカーホルダをリセット + o_square_stack.clear(); + + // ラベル数が0ならここまで + final int label_num=this._labeling.labeling(i_gs,i_th, 0, i_gs.getHeight(), flagment); + if (label_num < 1) { + return; + } + //ラベルをソートしておく + flagment.sortByArea(); + //ラベルリストを取得 + NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo[] labels=flagment.getArray(); + + final int xsize = this._width; + final int ysize = this._height; + final int coord_max = this._max_coord; + int[] xcoord = this._xcoord; + int[] ycoord = this._ycoord; + + + //重なりチェッカの最大数を設定 + overlap.setMaxLabels(label_num); + + for (int i=0; i < label_num; i++) { + final NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo label_pt=labels[i]; + final int label_area = label_pt.area; + + // クリップ領域が画面の枠に接していれば除外 + if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){ + continue; + } + if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){ + continue; + } + // 既に検出された矩形との重なりを確認 + if (!overlap.check(label_pt)) { + // 重なっているようだ。 + continue; + } + + // 輪郭を取得 + final int coord_num = _cpickup.getContour(i_gs,i_th,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord); + if (coord_num == coord_max) { + // 輪郭が大きすぎる。 + continue; + } + + //ここから先が輪郭分析 + NyARSquare square_ptr = o_square_stack.prePush(); + if(!this._sqconvertor.coordToSquare(i_gs,xcoord,ycoord,coord_num,label_area,square_ptr)){ + o_square_stack.pop();// 頂点の取得が出来なかったので破棄 + continue; + } + // 検出済の矩形の属したラベルを重なりチェックに追加する。 + overlap.push(label_pt); + } + return; + } + /** + * デバック用API + * @return + */ + public NyARRleLabelFragmentInfoPtrStack _getFragmentStack() + { + return this._stack; + } + /******************************************************************************** + * + * 追加クラス + * + ********************************************************************************/ + private class SquareContourDetector_Vector + { + private final NyARObserv2IdealMap2 _distmap; + private final int[] __detectMarker_mkvertex = new int[4]; + private final NyARCoord2SquareVertexIndexes _coord2vertex=new NyARCoord2SquareVertexIndexes(); + public SquareContourDetector_Vector(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref) + { + this._distmap=new NyARObserv2IdealMap2(i_distfactor_ref,i_size); + return; + } + + public boolean coordToSquare(NyARGrayscaleRaster i_raster,int[] i_xcoord,int[] i_ycoord,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException + { + + final int[] mkvertex = this.__detectMarker_mkvertex; + + // 頂点情報を取得 + if (!this._coord2vertex.getVertexIndexes(i_xcoord, i_ycoord,i_coord_num, i_label_area, mkvertex)) { + // 頂点の取得が出来なかったので破棄 + return false; + } + // マーカーを検出 + if (!getSquareLine(i_raster,mkvertex, i_xcoord, i_ycoord,i_coord_num, o_square)){ + // 矩形が成立しなかった。 + return false; + } + return true; + } + /** + * 指定した範囲の輪郭点ベクトル・座標を、加算する。 + * @param i_raster + * @param i_xcoord + * @param i_ycoord + * @param i_st + * @param i_ed + * @param o_vecsum + * @param o_possum + * @return + */ + private boolean addCoordVecPos(NyARGrayscaleRaster i_raster,int[] i_xcoord, int[] i_ycoord,int i_st,int i_ed,NyARIntPoint2d io_vecsum) + { + int dxi,dyi; + //ベクトル分析 + dxi=io_vecsum.x; + dyi=io_vecsum.y; + for(int i=i_st;i=319 || i_ycoord[i]>=239){ + return false; + } + //o_vecsumをワークに流用 + i_raster.getPixelVector8(i_xcoord[i],i_ycoord[i],io_vecsum); + dxi+=io_vecsum.x; + dyi-=io_vecsum.y; + } + io_vecsum.x=dxi; + io_vecsum.y=dyi; + return true; + } + + + private NyARDoublePoint2d __work_pos=new NyARDoublePoint2d(); + + private boolean getSquareLine(NyARGrayscaleRaster i_raster,int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord,int i_cood_num, NyARSquare o_square) throws NyARException + { + final NyARLinear[] l_line = o_square.line; + final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex; + final NyARIntPoint2d[] l_imvertex = o_square.imvertex; + final NyARDoublePoint2d idealcenter=this.__work_pos; + + NyARIntPoint2d vecsum=new NyARIntPoint2d(); + for (int i = 0; i < 4; i++){ + //頂点を取得 + int ver1=i_mkvertex[i]; + int ver2=i_mkvertex[(i+1)%4]; + + int n,st,ed; + double w1; + //探索区間の決定 + if(ver2>=i_mkvertex[i]){ + //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき + w1 = (double) (ver2 - ver1 + 1) * 0.05 + 0.5; + //探索区間の決定 + st = (int) (ver1+w1); + ed = (int) (ver2 - w1); + }else{ + //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき + w1 = (double) (ver2+i_cood_num-ver1+1)%i_cood_num * 0.05 + 0.5; + //探索区間の決定 + st = (int) (ver1+w1)%i_cood_num; + ed = (int) (ver2+i_cood_num-w1)%i_cood_num; + } + vecsum.x=vecsum.y=0; + //ベクトル分析 + if(st<=ed){ + //1区間 + n = ed - st+1; + addCoordVecPos(i_raster,i_xcoord,i_ycoord,st,ed+1,vecsum); + this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,st,n,idealcenter); + }else{ + //探索区間は2区間 + double cx,cy; + n=ed+i_cood_num-st+1; + addCoordVecPos(i_raster,i_xcoord,i_ycoord,st,i_cood_num,vecsum); + addCoordVecPos(i_raster,i_xcoord,i_ycoord,0,ed,vecsum); + //輪郭の中心位置を計算 + this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,st,i_cood_num-st,idealcenter); + cx=idealcenter.x; + cy=idealcenter.y; + this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,0,ed+1,idealcenter); + idealcenter.x=(idealcenter.x+cx)/2; + idealcenter.y=(idealcenter.y+cy)/2; + } + //中央値を歪修正(ほんとはピクセル単位にゆがみ矯正するべきだと思う) + + double l=Math.sqrt((double)(vecsum.x*vecsum.x+vecsum.y*vecsum.y)); + final NyARLinear l_line_i = l_line[i]; + //直交するベクトルを計算 + l_line_i.a = vecsum.x/l; + l_line_i.b = -vecsum.y/l; + //cを計算 + l_line_i.c = -(l_line_i.a * (idealcenter.x) + l_line_i.b * (idealcenter.y)); + + // 頂点インデクスから頂点座標を得て保存 + l_imvertex[i].x = i_xcoord[ver1]; + l_imvertex[i].y = i_ycoord[ver1]; + } + //線分式から頂点を計算 + for(int i=0;i<4;i++) + { + if(!NyARLinear.crossPos(l_line[i],l_line[(i + 3) % 4],l_sqvertex[i])){ + return false; + } + } + return true; + } + } + + /** + * 輪郭線の中心位置を計算する関数を追加したマップクラス + */ + private class NyARObserv2IdealMap2 extends NyARObserv2IdealMap + { + public NyARObserv2IdealMap2(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size) + { + super(i_distfactor,i_screen_size); + } + /** + * 歪み矯正した座標における、各座標の合計値を + * @param i_x_coord + * @param i_y_coord + * @param i_start + * @param i_num + * @param o_center + */ + public void getIdealCoodCenter(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num,NyARDoublePoint2d o_center) + { + int idx; + double x,y; + x=y=0; + 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; + x+=mapx[idx]; + y+=mapy[idx]; + } + o_center.x=x/(double)i_num; + o_center.y=y/(double)i_num; + return; + } + } +} + + + diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java new file mode 100644 index 0000000..beeefc6 --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java @@ -0,0 +1,293 @@ +/* + * PROJECT: NyARToolkit JOGL sample program. + * -------------------------------------------------------------------------------- + * The MIT License + * Copyright (c) 2008 nyatla + * airmail(at)ebony.plala.or.jp + * http://nyatla.jp/nyartoolkit/ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nyartoolkit.dev; + +import java.awt.event.*; +import java.awt.*; +import javax.media.Buffer; +import javax.media.opengl.*; +import com.sun.opengl.util.*; +import jp.nyatla.nyartoolkit.*; +import jp.nyatla.nyartoolkit.core.*; +import jp.nyatla.nyartoolkit.core.param.*; +import jp.nyatla.nyartoolkit.core.transmat.*; +import jp.nyatla.nyartoolkit.detector.*; +import jp.nyatla.nyartoolkit.jmf.utils.*; +import jp.nyatla.nyartoolkit.jogl.utils.*; +/** + * 2種類の最適化アルゴリズムを比較するテストプログラム + * + */ + +class Program implements JmfCaptureListener +{ + private OptimizeCompareTest _view1; + private OptimizeCompareTest _view2; + public Object _sync_object=new Object(); + public NyARParam _ar_param; + public NyARCode _ar_code; + private final static int SCREEN_X = 320; + private final static int SCREEN_Y = 240; + private JmfCaptureDevice _capture; + public GLNyARRaster_RGB _cap_image; + public Program(NyARParam i_param, NyARCode i_ar_code) throws NyARException + { + // キャプチャの準備 + JmfCaptureDeviceList devlist = new JmfCaptureDeviceList(); + this._capture = devlist.getDevice(0); + if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) { + throw new NyARException(); + } + this._ar_param=i_param; + this._ar_code=i_ar_code; + this._capture.setOnCapture(this); + // GL対応のRGBラスタオブジェクト + this._cap_image = new GLNyARRaster_RGB(i_param, this._capture.getCaptureFormat()); + this._view1=new OptimizeCompareTest(this,NyARSingleDetectMarker.PF_NYARTOOLKIT); + this._view2=new OptimizeCompareTest(this,NyARSingleDetectMarker.PF_NYARTOOLKIT_ARTOOLKIT_FITTING); + this._capture.start(); + return; + } + public void onUpdateBuffer(Buffer i_buffer) + { + try { + synchronized (this._sync_object) { + this._cap_image.setBuffer(i_buffer); + this._view1.updateCapture(this._cap_image); + this._view2.updateCapture(this._cap_image); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + //GL API + void glDrawCube(GL i_gl) + { + // Colour cube data. + int polyList = 0; + float fSize = 0.5f;// マーカーサイズに対して0.5倍なので、4cmの立方体 + int f, i; + float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } }; + float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; + int cube_num_faces = 6; + short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } }; + + if (polyList == 0) { + polyList = i_gl.glGenLists(1); + i_gl.glNewList(polyList, GL.GL_COMPILE); + i_gl.glBegin(GL.GL_QUADS); + for (f = 0; f < cube_num_faces; f++) + for (i = 0; i < 4; i++) { + i_gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]); + i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize); + } + i_gl.glEnd(); + i_gl.glColor3f(0.0f, 0.0f, 0.0f); + for (f = 0; f < cube_num_faces; f++) { + i_gl.glBegin(GL.GL_LINE_LOOP); + for (i = 0; i < 4; i++) + i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize); + i_gl.glEnd(); + } + i_gl.glEndList(); + } + + i_gl.glPushMatrix(); // Save world coordinate system. + i_gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface. + i_gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis. + i_gl.glDisable(GL.GL_LIGHTING); // Just use colours. + i_gl.glCallList(polyList); // Draw the cube. + i_gl.glPopMatrix(); // Restore world coordinate system. + return; + } + +} +/** + * simpleLiteと同じようなテストプログラム 出来る限りARToolKitのサンプルと似せて作ってあります。 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。 + * + */ +public class OptimizeCompareTest implements GLEventListener +{ + private final static int SCREEN_X = 320; + + private final static int SCREEN_Y = 240; + + private Animator _animator; + + private Program _parent; + + +// private JmfCaptureDevice _capture; + + private GL _gl; + private NyARGLUtil _glnya; + + // NyARToolkit関係 + private NyARSingleDetectMarker _nya; + private NyARParam _ar_param; + + private double[] _camera_projection = new double[16]; + + + public OptimizeCompareTest(Program i_program,int i_pf) throws NyARException + { + this._parent=i_program; + this._ar_param = i_program._ar_param; + + Frame frame = new Frame("["+i_pf+"]"); + + // NyARToolkitの準備 + this._nya = new NyARSingleDetectMarker(this._ar_param, i_program._ar_code, 80.0,i_program._cap_image.getBufferType(),i_pf); + this._nya.setContinueMode(true);// ここをtrueにすると、transMatContinueモード(History計算)になります。 + + // 3Dを描画するコンポーネント + GLCanvas canvas = new GLCanvas(); + frame.add(canvas); + canvas.addGLEventListener(this); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) + { + System.exit(0); + } + }); + + frame.setVisible(true); + Insets ins = frame.getInsets(); + frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom); + canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y); + } + + public void init(GLAutoDrawable drawable) + { + this._gl = drawable.getGL(); + this._gl.glEnable(GL.GL_DEPTH_TEST); + this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + // NyARToolkitの準備 + try { + // NyARToolkit用の支援クラス + _glnya = new NyARGLUtil(_gl); + } catch (Exception e) { + e.printStackTrace(); + } + // カメラパラメータの計算 + this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection); + this._animator = new Animator(drawable); + this._animator.start(); + return; + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) + { + _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + _gl.glViewport(0, 0, width, height); + + // 視体積の設定 + _gl.glMatrixMode(GL.GL_PROJECTION); + _gl.glLoadIdentity(); + // 見る位置 + _gl.glMatrixMode(GL.GL_MODELVIEW); + _gl.glLoadIdentity(); + } + + private boolean _is_marker_exist=false; + private NyARTransMatResult __display_transmat_result = new NyARTransMatResult(); + + private double[] __display_wk = new double[16]; + + public void display(GLAutoDrawable drawable) + { + NyARTransMatResult transmat_result = __display_transmat_result; + if (!this._parent._cap_image.hasData()) { + return; + } + // 背景を書く + this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. + this._glnya.drawBackGround(this._parent._cap_image, 1.0); + try{ + synchronized(this._parent._sync_object){ + // マーカーがあれば、立方体を描画 + if (this._is_marker_exist){ + // マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。 + // Projection transformation. + _gl.glMatrixMode(GL.GL_PROJECTION); + _gl.glLoadMatrixd(_camera_projection, 0); + _gl.glMatrixMode(GL.GL_MODELVIEW); + // Viewing transformation. + _gl.glLoadIdentity(); + // 変換行列を取得 + _nya.getTransmationMatrix(transmat_result); + // 変換行列をOpenGL形式に変換 + _glnya.toCameraViewRH(transmat_result, __display_wk); + _gl.glLoadMatrixd(__display_wk, 0); + + // All other lighting and geometry goes here. + this._parent.glDrawCube(_gl); + } + } + Thread.sleep(1);// タスク実行権限を一旦渡す + }catch(Exception e){ + e.printStackTrace(); + } + + } + + public void updateCapture(GLNyARRaster_RGB i_img) + { + try { + synchronized (this._parent._sync_object) { + this._is_marker_exist =this._nya.detectMarkerLite(i_img, 110); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) + { + } + + private final static String CARCODE_FILE = "../Data/patt.hiro"; + + private final static String PARAM_FILE = "../Data/camera_para.dat"; + + public static void main(String[] args) + { + try { + NyARParam param = new NyARParam(); + param.loadARParamFromFile(PARAM_FILE); + param.changeScreenSize(SCREEN_X, SCREEN_Y); + + NyARCode code = new NyARCode(16, 16); + code.loadARPattFromFile(CARCODE_FILE); + + new Program(param, code); + } catch (Exception e) { + e.printStackTrace(); + } + return; + } +} diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java new file mode 100644 index 0000000..d109faa --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java @@ -0,0 +1,232 @@ +package jp.nyatla.nyartoolkit.dev; + +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; + +import javax.media.Buffer; +import javax.media.format.VideoFormat; +import javax.media.util.BufferToImage; + +import java.awt.color.ColorSpace; +import java.awt.image.*; +import java.io.File; +import java.io.FileInputStream; +import java.util.Date; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.jmf.utils.*; +import jp.nyatla.nyartoolkit.detector.*; +import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPickup; +import jp.nyatla.nyartoolkit.core.transmat.*; +import jp.nyatla.nyartoolkit.core.*; +import jp.nyatla.nyartoolkit.core.param.*; +import jp.nyatla.nyartoolkit.core.pickup.*; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.types.*; +import jp.nyatla.nyartoolkit.core.raster.rgb.*; +import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*; +import jp.nyatla.nyartoolkit.nyidmarker.*; +import jp.nyatla.nyartoolkit.utils.j2se.*; +import jp.nyatla.nyartoolkit.core.squaredetect.*; + + + +public class PattPickupTest extends Frame implements JmfCaptureListener +{ + private final String PARAM_FILE = "../Data/camera_para.dat"; + + private final static String CARCODE_FILE = "../Data/patt.hiro"; + + private static final long serialVersionUID = -2110888320986446576L; + + private JmfCaptureDevice _capture; + + private JmfNyARRaster_RGB _capraster; + + private int W = 320; + + private int H = 240; + + private NyARParam _param; + + private NyARBinRaster _bin_raster; + + private NyARSquareStack _stack = new NyARSquareStack(100); + + private NyARSingleDetectMarker detect; + + public PattPickupTest() throws NyARException + { + setTitle("JmfCaptureTest"); + Insets ins = this.getInsets(); + this.setSize(640 + ins.left + ins.right, 480 + ins.top + ins.bottom); + JmfCaptureDeviceList dl = new JmfCaptureDeviceList(); + this._capture = dl.getDevice(0); + if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB, W, H, 30.0f)) { + if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV, W, H, 30.0f)) { + throw new NyARException("キャプチャフォーマットが見つかりません。"); + } + } + NyARParam ar_param = new NyARParam(); + ar_param.loadARParamFromFile(PARAM_FILE); + ar_param.changeScreenSize(W, H); + + NyARCode code = new NyARCode(16, 16); + code.loadARPattFromFile(CARCODE_FILE); + this._capraster = new JmfNyARRaster_RGB(W, H, this._capture.getCaptureFormat()); + this.detect = new NyARSingleDetectMarker(ar_param, code, 80, this._capraster.getBufferType()); + this._capture.setOnCapture(this); + this._bin_raster = new NyARBinRaster(W, H); + this._param = ar_param; + return; + } + + /** + * 矩形の矩形っぽい点数を返す。 + * + * @param i_sq + * @return + */ + private int getSQPoint(NyARSquare i_sq) + { + int lx1 = i_sq.imvertex[0].x - i_sq.imvertex[2].x; + int ly1 = i_sq.imvertex[0].y - i_sq.imvertex[2].y; + int lx2 = i_sq.imvertex[1].x - i_sq.imvertex[3].x; + int ly2 = i_sq.imvertex[1].y - i_sq.imvertex[3].y; + return (int) Math.sqrt((lx1 * lx1) + (ly1 * ly1)) * (int) Math.sqrt(((lx2 * lx2) + (ly2 * ly2))); + } + + private final String data_file = "../Data/320x240ABGR.raw"; + + private INyARColorPatt _patt1 = new NyARColorPatt_O3(16, 16); + + public void draw(INyARRgbRaster i_raster) + { + try { + Insets ins = this.getInsets(); + Graphics g = getGraphics(); + + {// ピックアップ画像の表示 + // 矩形抽出 + INyARRasterFilter_Bin to_binfilter = new NyARRasterFilterBuilder_RgbToBin(110, i_raster.getBufferType()); + to_binfilter.doFilter(i_raster, this._bin_raster); + if (this.detect.detectMarkerLite(i_raster, 100)) { + + NyARTransMatResult res = new NyARTransMatResult(); + this.detect.getTransmationMatrix(res); + int max_point = 0; + + // NyARSquare t=new NyARSquare(); + + TransformedBitmapPickup patt2 = new TransformedBitmapPickup(this._param.getPerspectiveProjectionMatrix(), 100, 100, 1); + + BufferedImage sink = new BufferedImage(this._patt1.getWidth(), this._patt1.getHeight(), ColorSpace.TYPE_RGB); + BufferedImage sink2 = new BufferedImage(patt2.getWidth(), patt2.getHeight(), ColorSpace.TYPE_RGB); + patt2.pickupImage2d(i_raster,-20,-40,20,-80,res); + /* + * t.imvertex[0].x=(int)483.0639377595418; t.imvertex[0].y=(int)303.17616747966747; + * + * t.imvertex[1].x=(int)506.1019505415998; t.imvertex[1].y=(int)310.5313224526344; + * + * t.imvertex[2].x=(int)589.3605435960492; t.imvertex[2].y=(int)258.46261716798523; + * + * t.imvertex[3].x=(int)518.1385869954609; t.imvertex[3].y=(int)325.1434618295405; + */ + Graphics g1, g2, g3; + /* {// ARToolkit + // 一番それっぽいパターンを取得 + this._patt1.pickFromRaster(i_raster, t.imvertex); + Date d2 = new Date(); + for (int i = 0; i < 10000; i++) { + this._patt1.pickFromRaster(i_raster, t.imvertex); + } + Date d = new Date(); + System.out.println(d.getTime() - d2.getTime()); + + // パターンを書く + NyARRasterImageIO.copy(this._patt1, sink); + g1 = sink.getGraphics(); + g1.setColor(Color.red); + }*/ + {// 疑似アフィン変換 + NyARRasterImageIO.copy(patt2, sink2); + g2 = sink2.getGraphics(); + g2.setColor(Color.red); + + } + g.drawImage(sink, ins.left + 320, ins.top, 128, 128, null); + g.drawImage(sink2, ins.left + 320, ins.top + 128, 128, 128, null); + // g.drawImage(sink3, ins.left + 100, ins.top + 240, this._patt3.getWidth() * 10, this._patt3.getHeight() * 10, null); + + } + {// 撮影画像 + BufferedImage sink = new BufferedImage(i_raster.getWidth(), i_raster.getHeight(), ColorSpace.TYPE_RGB); + NyARRasterImageIO.copy(i_raster, sink); + g.drawImage(sink, ins.left, ins.top, this); + } + + {// 信号取得テスト + + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void onUpdateBuffer(Buffer i_buffer) + { + try { + + {// ピックアップ画像の表示 + // 矩形抽出 + this._capraster.setBuffer(i_buffer); + draw(this._capraster); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void startCapture() + { + try { + this._capture.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void startImage() + { + try { + // 試験イメージの読み出し(320x240 BGRAのRAWデータ) + File f = new File(data_file); + FileInputStream fs = new FileInputStream(data_file); + byte[] buf = new byte[(int) f.length() * 4]; + fs.read(buf); + INyARRgbRaster ra = NyARRgbRaster_BGRA.wrap(buf, W, H); + draw(ra); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public static void main(String[] args) + { + try { + PattPickupTest mainwin = new PattPickupTest(); + mainwin.setVisible(true); + mainwin.startCapture(); + // mainwin.startImage(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java new file mode 100644 index 0000000..53b56a9 --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java @@ -0,0 +1,104 @@ +package jp.nyatla.nyartoolkit.dev; + +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; + +import javax.imageio.ImageIO; +import javax.media.Buffer; +import javax.media.format.VideoFormat; +import javax.media.util.BufferToImage; + +import java.awt.color.ColorSpace; +import java.awt.image.*; +import java.io.File; +import java.io.FileInputStream; +import java.util.Date; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.jmf.utils.*; +import jp.nyatla.nyartoolkit.detector.*; +import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPickup; +import jp.nyatla.nyartoolkit.core.transmat.*; +import jp.nyatla.nyartoolkit.core.*; +import jp.nyatla.nyartoolkit.core.param.*; +import jp.nyatla.nyartoolkit.core.pickup.*; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.types.*; +import jp.nyatla.nyartoolkit.core.raster.rgb.*; +import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*; +import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*; +import jp.nyatla.nyartoolkit.nyidmarker.*; +import jp.nyatla.nyartoolkit.sample.RawFileTest; +import jp.nyatla.nyartoolkit.utils.j2se.*; +import jp.nyatla.nyartoolkit.core.squaredetect.*; +import jp.nyatla.nyartoolkit.core.pickup.*; + + +public class PattPickupTestS extends Frame +{ + private final String code_file = "../Data/flarlogo.pat"; + + private final static String SAMPLE_FILES = "../Data/flarlogo_45.png"; + + private final String camera_file = "../Data/camera_para.dat"; + + + + public void Test_arDetectMarkerLite() throws Exception + { + // AR用カメラパラメタファイルをロード + NyARParam ap = new NyARParam(); + ap.loadARParamFromFile(camera_file); + + + // AR用のパターンコードを読み出し + NyARCode code = new NyARCode(16, 16); + code.loadARPattFromFile(code_file); + + // 試験イメージの読み出し(320x240 BGRAのRAWデータ) + BufferedImage src_image = ImageIO.read(new File(SAMPLE_FILES)); + INyARRgbRaster ra = new NyARRgbRaster_RGB(src_image.getWidth(),src_image.getHeight(),true); + NyARRasterImageIO.copy(src_image, ra); + + + // NyARToolkitの準備 + ap.changeScreenSize(src_image.getWidth(),src_image.getHeight()); + + + // Blank_Raster ra=new Blank_Raster(320, 240); + + // 1パターンのみを追跡するクラスを作成 + NyARSingleDetectMarker ar = new NyARSingleDetectMarker( + ap, code, 80.0,ra.getBufferType(),NyARSingleDetectMarker.PF_NYARTOOLKIT); + NyARTransMatResult result_mat = new NyARTransMatResult(); + ar.setContinueMode(false); + ar.detectMarkerLite(ra, 100); + ar.getTransmationMatrix(result_mat); + + NyARDoublePoint3d ang=new NyARDoublePoint3d(); + result_mat.getZXYAngle(ang); + NyARRasterImageIO.copy(((INyARColorPatt)(ar._getProbe()[0])),b); + + } + BufferedImage b=new BufferedImage(16,16,ColorSpace.TYPE_RGB); + + public void drawImage(){ + Graphics g=this.getGraphics(); + g.drawImage(b,50,50,100,100,null); + }; + public static void main(String[] args) + { + try { + PattPickupTestS app = new PattPickupTestS(); + app.setVisible(true); + app.setBounds(0, 0, 640, 480); + app.Test_arDetectMarkerLite(); + app.drawImage(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/Solver.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/Solver.java new file mode 100644 index 0000000..a063c6a --- /dev/null +++ b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/Solver.java @@ -0,0 +1,144 @@ +package jp.nyatla.nyartoolkit.dev; + + + +public class Solver +{ + public String[][] _data=new String[4][6]; + public String[] _temp=new String[6]; + public Solver() + { + this._data[0][0]="a"; + this._data[0][1]="b"; + this._data[0][2]="c"; + this._data[0][3]="d"; + this._data[0][4]="e"; + this._data[0][5]="1"; + + this._data[1][0]="f"; + this._data[1][1]="g"; + this._data[1][2]="h"; + this._data[1][3]="i"; + this._data[1][4]="j"; + this._data[1][5]="1"; + + this._data[2][0]="k"; + this._data[2][1]="l"; + this._data[2][2]="m"; + this._data[2][3]="n"; + this._data[2][4]="o"; + this._data[2][5]="1"; + + this._data[3][0]="p"; + this._data[3][1]="q"; + this._data[3][2]="r"; + this._data[3][3]="s"; + this._data[3][4]="t"; + this._data[3][5]="1"; + } + public void dump() + { + for(int i=0;i