-/* このソースは実験用のソースです。
- * 動いたり動かなかったりします。
- *
- */
-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 jp.nyatla.nyartoolkit.toys.x2.NyARLabeling_ARToolKit_X2;
-import jp.nyatla.nyartoolkit.toys.x2.NyARTransMat_X2;
-
-import java.awt.*;
-
-import jp.nyatla.nyartoolkit.core.INyARSquareDetector;
-import jp.nyatla.nyartoolkit.core.labeling.*;
-import jp.nyatla.nyartoolkit.core.match.*;
-import jp.nyatla.nyartoolkit.core.param.*;
-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.core2.rasteranalyzer.*;
-import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
-import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
-import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.NyARRasterFilter_RgbAve;
-import jp.nyatla.utils.NyObjectStack;
-import jp.nyatla.utils.j2se.LabelingBufferdImage;
-import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
-import jp.nyatla.nyartoolkit.core.transmat.*;
-import jp.nyatla.nyartoolkit.core.types.*;
-
-
-class NyARMkVertexStack extends NyObjectStack
-{
- public NyARMkVertexStack(int i_length)
- {
- super(new NyARIntPoint[i_length][]);
-
- }
-
- protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)
- {
- for (int i = i_start; i < i_end; i++) {
- i_buffer[i] = NyARIntPoint.createArray(4);
- }
- }
-}
-/**
- * QRコードのシンボルを結びつける偉いクラス
- *
- */
-class NyQrCodeSymbolBinder
-{
- LabelingBufferdImage bimg;
-
- NyARIntPoint[][] _sqare;
- /**
- * 最小の三角形を構成する頂点セットを得る
- * @param i_s0
- * @param i_s1
- * @param i_s2
- * @param o_vertex
- */
- public static void getMinimumTriangleVertex(NyARIntPoint[][] i_sqare,int[] o_vertex_id)
- {
- //辺の長さが最小になる頂点の組合せを探す
- int d;
- int x,y;
- int dmax=0x7fffffff;
- for(int i=0;i<4;i++)
- {
- for(int i2=0;i2<4;i2++)
- {
- for(int i3=0;i3<4;i3++){
- x=i_sqare[0][i].x-i_sqare[2][i3].x;
- y=i_sqare[0][i].y-i_sqare[2][i3].y;
- d=x*x+y*y;
- x=i_sqare[1][i2].x-i_sqare[2][i3].x;
- y=i_sqare[1][i2].y-i_sqare[2][i3].y;
- d+=x*x+y*y;
- x=i_sqare[1][i2].x-i_sqare[0][i].x;
- y=i_sqare[1][i2].y-i_sqare[0][i].y;
- d+=x*x+y*y;
- if(d<dmax){
- dmax=d;
- o_vertex_id[0]=i;
- o_vertex_id[1]=i2;
- o_vertex_id[2]=i3;
- }
- }
- }
- }
- return;
- }
- /**
- * 2矩形の頂点距離が最低の組合せを探す
- * @param i_sqare
- * @param o_vertex_id
- */
- public static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
- {
- //辺の長さが最小になる頂点の組合せを探す
- int d;
- int x,y;
- int dmax=0x7fffffff;
- for(int i=0;i<4;i++)
- {
- for(int i2=0;i2<4;i2++)
- {
- x=i_sqare1[i2].x-i_sqare0[i].x;
- y=i_sqare1[i2].y-i_sqare0[i].y;
- d=x*x+y*y;
- if(d<dmax){
- dmax=d;
- o_vertex_id[0]=i;
- o_vertex_id[1]=i2;
- }
- }
- }
- return;
- }
-
- /**
- * キーシンボルのインデックスを得る
- * @param i_sqare
- * @param i_vertex_id
- * 最小三角形の頂点IDセット
- * @return
- */
- public static int getKeySymble(NyARIntPoint[][] i_sqare,int[] i_vertex_id)
- {
- //シンボルグループの重心を計算
- int cx,cy;
- cx=cy=0;
- for(int i=0;i<3;i++)
- {
- final NyARIntPoint[] sq_ptr=i_sqare[i];
- cx+=sq_ptr[0].x;
- cx+=sq_ptr[1].x;
- cx+=sq_ptr[2].x;
- cx+=sq_ptr[3].x;
- cy+=sq_ptr[0].y;
- cy+=sq_ptr[1].y;
- cy+=sq_ptr[2].y;
- cy+=sq_ptr[3].y;
- }
- cx/=12;
- cy/=12;
- //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
- int key_symble_idx=0;
- int x=i_sqare[0][i_vertex_id[0]].x-cx;
- int y=i_sqare[0][i_vertex_id[0]].y-cy;
- int dmax=x*x+y*y;
- for(int i=1;i<3;i++){
- x=i_sqare[i][i_vertex_id[i]].x-cx;
- y=i_sqare[i][i_vertex_id[i]].y-cy;
- final int d=x*x+y*y;
- if(d<dmax){
- dmax=d;
- key_symble_idx=i;
- }
- }
- return key_symble_idx;
- }
- public void getLineFromVertex(NyARIntPoint i_v1,NyARIntPoint i_v2)
- {
- double sx=i_v1.x-i_v2.x;
- double sy=i_v1.y-i_v2.y;
- double k=sy/sx;
- double b=i_v2.y-k*i_v2.x;
- Graphics g=this.bimg.getGraphics();
- g.setColor(Color.red);
- g.drawLine(0,(int)b,320,(int)(k*320+b));
-
- }
- /**
- *
- * @param i_sq
- * @param o_sq
- * @return
- */
- public boolean margeEdge(NyARIntPoint[][] i_sq,NyARSquare o_sq)
- {
- int[] minimum_triangle_vertex=new int[3];
- int[] minimum_line_vertex=new int[2];
-
- //辺の長さが最小になる頂点の組合せを探す
- getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
-
- //キーシンボルのインデクス番号を得る
- int key_simble_idx=getKeySymble(i_sq,minimum_triangle_vertex);
-
- //エッジシンボルのインデックス番号を決める
- int symbol_e1_idx=(key_simble_idx+1)%3;
- int symbol_e2_idx=(key_simble_idx+2)%3;
-
- //エッジシンボル間で最短距離を取る頂点ペアを取る
- //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
- getMinimumLineVertex(i_sq[symbol_e1_idx],i_sq[symbol_e2_idx],minimum_line_vertex);
-
- //内対角を外対角に変換
- int lv1=(minimum_line_vertex[0]+2)%4;
- int lv2=(minimum_line_vertex[1]+2)%4;
- int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
-
- getLineFromVertex(i_sq[symbol_e1_idx][(lv1+1)%4],i_sq[symbol_e1_idx][lv1]);
- getLineFromVertex(i_sq[symbol_e1_idx][(lv1+3)%4],i_sq[symbol_e1_idx][lv1]);
- getLineFromVertex(i_sq[symbol_e2_idx][(lv2+1)%4],i_sq[symbol_e2_idx][lv2]);
- getLineFromVertex(i_sq[symbol_e2_idx][(lv2+3)%4],i_sq[symbol_e2_idx][lv2]);
- getLineFromVertex(i_sq[key_simble_idx][(kv+2)%4],i_sq[key_simble_idx][kv]);
-
-
- Graphics g=this.bimg.getGraphics();
- //内対角に緑の点を打つ
- g.setColor(Color.green);
- g.fillRect(i_sq[key_simble_idx][minimum_triangle_vertex[key_simble_idx]].x-2,i_sq[key_simble_idx][minimum_triangle_vertex[key_simble_idx]].y-2,4,4);
- g.fillRect(i_sq[symbol_e1_idx][minimum_line_vertex[0]].x-2,i_sq[symbol_e1_idx][minimum_line_vertex[0]].y-2,4,4);
- g.fillRect(i_sq[symbol_e2_idx][minimum_line_vertex[1]].x-2,i_sq[symbol_e2_idx][minimum_line_vertex[1]].y-2,4,4);
-
-
- //中央の中心エッジから最も遠い点が
- //両端のエッジも探す
-
-
-
-
-// this.bimg.getGraphics().fillRect(i_sq[edge1_id][vid1_id].x,i_sq[edge1_id][vid1_id].y,5,5);
-
- for (int i = 0; i <3; i++) {
- int[] xp=new int[4];
- int[] yp=new int[4];
- for(int i2=0;i2<4;i2++){
- xp[i2]=i_sq[i][i2].x;
- yp[i2]=i_sq[i][i2].y;
- }
- this.bimg.getGraphics().setColor(Color.RED);
- this.bimg.getGraphics().drawPolygon(xp, yp,4);
- }
-
-
- return false;
-
-
-
-
-
-
- }
-
-
-
-
-}
-
-
-/**
- * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス
- *
- */
-class NyARQRCodeDetector implements INyARSquareDetector
-{
- LabelingBufferdImage bimg;
- private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
-
- 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 NyARLabeling_ARToolKit_X2 _labeling;
-
- private final NyARLabelingImage _limage;
-
- private final NyARCameraDistortionFactor _dist_factor_ref;
-
- /**
- * 最大i_squre_max個のマーカーを検出するクラスを作成する。
- *
- * @param i_param
- */
- public NyARQRCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
- {
- this._width = i_size.w;
- this._height = i_size.h;
- this._dist_factor_ref = i_dist_factor_ref;
- this._labeling = new NyARLabeling_ARToolKit_X2();
- this._limage = new NyARLabelingImage(this._width, this._height);
- this._labeling.attachDestination(this._limage);
-
- // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
- int number_of_coord = (this._width + this._height) * 2;
-
- // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
- this._max_coord = number_of_coord;
- this._xcoord = new int[number_of_coord * 2];
- this._ycoord = new int[number_of_coord * 2];
- }
-
- private final int _max_coord;
-
- private final int[] _xcoord;
-
- private final int[] _ycoord;
-
- private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
- {
- // vertex1を境界にして、後方に配列を連結
- System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
- System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
- }
-
- private final int[] __detectMarker_mkvertex = new int[5];
-
- /**
- * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
- * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
- *
- * @param i_raster
- * 解析する2値ラスタイメージを指定します。
- * @param o_square_stack
- * 抽出した正方形候補を格納するリスト
- * @throws NyARException
- */
- public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
- {
- final INyARLabeling labeling_proc = this._labeling;
- final NyARLabelingImage limage = this._limage;
-
- // 初期化
-
- // マーカーホルダをリセット
- o_square_stack.clear();
-
- // ラベリング
- labeling_proc.labeling(i_raster);
-
- // ラベル数が0ならここまで
- final int label_num = limage.getLabelStack().getLength();
- if (label_num < 1) {
- return;
- }
-
- final NyARLabelingLabelStack stack = limage.getLabelStack();
- final NyARLabelingLabel[] labels = (NyARLabelingLabel[]) stack.getArray();
-
- // ラベルを大きい順に整列
- stack.sortByArea();
-
- // デカいラベルを読み飛ばし
- int i;
- for (i = 0; i < label_num; i++) {
- // 検査対象内のラベルサイズになるまで無視
- if (labels[i].area <= AR_AREA_MAX) {
- break;
- }
- }
-
- final int xsize = this._width;
- final int ysize = this._height;
- final int[] xcoord = this._xcoord;
- final int[] ycoord = this._ycoord;
- final int coord_max = this._max_coord;
- final int[] mkvertex = this.__detectMarker_mkvertex;
- final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
- final int[] indextable = limage.getIndexArray();
- int coord_num;
- int label_area;
- NyARLabelingLabel label_pt;
- NyARMkVertexStack vertex_stack=new NyARMkVertexStack(100);
-
- for (; i < label_num; i++) {
- label_pt = labels[i];
- label_area = label_pt.area;
- // 検査対象サイズよりも小さくなったら終了
- if (label_area < AR_AREA_MIN) {
- break;
- }
- // クリップ領域が画面の枠に接していれば除外
- if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
- continue;
- }
- if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
- continue;
- }
- // 特徴点候補であるかを確認する。
- if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
- continue;
- }
-
- // 輪郭を取得
- coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
- if (coord_num == coord_max) {
- // 輪郭が大きすぎる。
- continue;
- }
- // 頂点候補のインデクスを取得
- final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
-
- // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
- normalizeCoord(xcoord, ycoord, vertex1, coord_num);
-
-
- // 頂点情報を取得
- if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
-// o_square_stack.pop();// 頂点の取得が出来なかったので破棄
- continue;
- }
- // 領域を準備する。
- NyARIntPoint[] vertex_ptr = (NyARIntPoint[]) vertex_stack.prePush();
- vertex_ptr[0].x=xcoord[mkvertex[0]];
- vertex_ptr[0].y=ycoord[mkvertex[0]];
- vertex_ptr[1].x=xcoord[mkvertex[1]];
- vertex_ptr[1].y=ycoord[mkvertex[1]];
- vertex_ptr[2].x=xcoord[mkvertex[2]];
- vertex_ptr[2].y=ycoord[mkvertex[2]];
- vertex_ptr[3].x=xcoord[mkvertex[3]];
- vertex_ptr[3].y=ycoord[mkvertex[3]];
-
-// // 頂点情報からライン情報を作っちゃう
-// getSquare(mkvertex, xcoord, ycoord, vertex_ptr);
- }
- bindQrcodeEdge(vertex_stack);
- //エッジ同士の相関関係をしらべる。
-
- return;
- }
- /**
- *
- * @param i_sq
- * @param o_sq
- * @return
- */
- public boolean margeEdge(NyARIntPoint[][] i_sq,NyARSquare o_sq)
- {
- NyQrCodeSymbolBinder binder=new NyQrCodeSymbolBinder();
- binder.bimg=this.bimg;
- binder.margeEdge(i_sq, o_sq);
-
- return false;
-
-
-
-
- }
- /**
- * QRコードのエッジペアを作る
- * @param i_square_stack
- */
- public void bindQrcodeEdge(NyARMkVertexStack i_square_stack)
- {
-
- NyARIntPoint[] sq_ptr1,sq_ptr2,sq_ptr3;
- int number_of_edge=i_square_stack.getLength();
- if(number_of_edge<3){
- return;
- }
- NyARIntPoint[][] sa=(NyARIntPoint[][])i_square_stack.getArray();
- for(int i=0;i<number_of_edge;i++)
- {
- for(int i2=i+1;i2<number_of_edge;i2++)
- {
- sq_ptr2=sa[i2];
- for(int i3=i2+1;i3<number_of_edge;i3++){
- sq_ptr3=sa[i3];
- //3個のエッジの関連性を確認する。
- margeEdge(sa,null);
- }
- //
- }
- }
- }
- /**
- * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
- *
- * @param i_v1
- * @param i_v2
- * @param o_line
- */
- final private void getLine(NyARDoublePoint2d i_v1, NyARDoublePoint2d i_v2, NyARLinear o_line)
- {
- final double x = i_v1.x - i_v2.x;
- final double y = i_v1.y - i_v2.y;
- final double x2 = x * x;
- final double y2 = y * y;
- final double rise_ = Math.sqrt(x2 / (x2 + y2));
- o_line.rise = rise_;
- o_line.run = Math.sqrt(y2 / (x2 + y2));
- if (x < 0) {
- if (y < 0) {
- o_line.rise = -o_line.rise;
- } else {
- o_line.rise = -o_line.rise;
- o_line.run = -o_line.run;
- }
- } else {
- if (y < 0) {
- o_line.rise = -o_line.rise;
- o_line.run = -o_line.run;
- } else {
- o_line.rise = -o_line.rise;
- }
- }
- o_line.intercept = (i_v1.y + (o_line.run / o_line.rise) * (i_v1.x)) * rise_;
-
- }
-
- private void getSquare(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square)
- {
- final NyARCameraDistortionFactor dist_factor = this._dist_factor_ref;
- final NyARDoublePoint2d[] vertex = o_square.sqvertex;
-
- NyARIntPoint[] imvertex_ptr=o_square.imvertex;
- NyARIntPoint wk_vertex;
- //頂点座標取得
- for (int i = 0; i < 4; i++) {
- final int idx = i_mkvertex[i];
- imvertex_ptr[i].x = i_xcoord[idx];
- imvertex_ptr[i].y = i_ycoord[idx];
- }
- // 歪み補正
- for (int i = 0; i < 4; i++) {
- dist_factor.observ2Ideal(imvertex_ptr[i].x,imvertex_ptr[i].y, vertex[i]);
- }
- // ライン計算
- getLine(vertex[1], vertex[0], o_square.line[0]);
- getLine(vertex[2], vertex[1], o_square.line[1]);
- getLine(vertex[3], vertex[2], o_square.line[2]);
- getLine(vertex[0], vertex[3], o_square.line[3]);
- return;
- }
-
- /**
- * 辺からの対角線が最長になる点を対角線候補として返す。
- *
- * @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;i<marker_info2->coord_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 CopyOfLabelingCamera extends Frame implements JmfCaptureListener
-{
- private final String camera_file = "../Data/camera_para.dat";
-
- private JmfNyARRaster_RGB _raster;
-
- private JmfCameraCapture capture;
- private NyARParam ap;
- public CopyOfLabelingCamera() 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 NyARGlayscaleRaster _gsraster1 = new NyARGlayscaleRaster(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 = (NyARLabelingLabel[]) 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.debugDrawHistgramMap(_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.debugDrawHistgramMap(_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 {
- CopyOfLabelingCamera mainwin = new CopyOfLabelingCamera();
- mainwin.setVisible(true);
- mainwin.startCapture();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
-}