/** * サイズが同一であるかを確認する。 * * @param i_width * @param i_height * @return * @throws NyARException */ public bool isEqualSize(NyARIntSize i_size) { if (i_size.w == this.w && i_size.h == this.h) { return true; } return false; }
/** * コンストラクタです。 * 入力画像のサイズを指定して、インスタンスを生成します。 * @param i_size * 入力画像のサイズ */ public NyARSquareContourDetector_ARToolKit(NyARIntSize i_size) { this._width = i_size.w; this._height = i_size.h; this._labeling = new NyARLabeling_ARToolKit(); this._limage = new NyARLabelingImage(this._width, this._height); // 輪郭の最大長は画面に映りうる最大の長方形サイズ。 int number_of_coord = (this._width + this._height) * 2; // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。 this._coord = new NyARIntCoordinates(number_of_coord); return; }
/** * コンストラクタです。 * 輪郭取得元画像の歪み矯正オブジェクトとサイズを指定して、インスタンスを生成します。 * @param i_size * 入力画像のサイズ * @param i_distfactor * 樽型歪みを補正する場合に、オブジェクトを指定します。 * nullの場合、補正を行いません。 */ public NyARCoord2Linear(NyARIntSize i_size, INyARCameraDistortionFactor i_distfactor) { if (i_distfactor != null) { this._dist_factor = new NyARObserv2IdealMap(i_distfactor, i_size); } else { this._dist_factor = null; } // 輪郭バッファ this._pca = new NyARPca2d_MatrixPCA_O2(); this._xpos = new double[i_size.w + i_size.h];//最大辺長はthis._width+this._height this._ypos = new double[i_size.w + i_size.h];//最大辺長はthis._width+this._height return; }
/** * コンストラクタです。 * 入力した{@link NyARCameraDistortionFactor}とそのサイズから、テーブルを作成します。 * 2つのパラメータは整合性が取れていなければなりません。 * (通常は、{@link NyARParam}の{@link NyARParam#getDistortionFactor()},{@link NyARParam#getScreenSize()}から得られた * パラメータを入力します。) * @param i_distfactor * 樽型歪みパラメータのオブジェクト。 * @param i_screen_size * スクリーンサイズ */ public NyARObserv2IdealMap(INyARCameraDistortionFactor i_distfactor, NyARIntSize i_screen_size) { NyARDoublePoint2d opoint = new NyARDoublePoint2d(); this._mapx = new double[i_screen_size.w * i_screen_size.h]; this._mapy = new double[i_screen_size.w * i_screen_size.h]; this._stride = i_screen_size.w; int ptr = i_screen_size.h * i_screen_size.w - 1; //歪みマップを構築 for (int i = i_screen_size.h - 1; i >= 0; i--) { for (int i2 = i_screen_size.w - 1; i2 >= 0; i2--) { i_distfactor.observ2Ideal(i2, i, opoint); this._mapx[ptr] = opoint.x; this._mapy[ptr] = opoint.y; ptr--; } } return; }
public void switchRaster(INyARRgbRaster i_raster) { this._ref_buf = (Color32[])(((NyARUnityRaster)i_raster).getBuffer()); this._ref_size = i_raster.getSize(); }
/** * 画像ドライバに依存するインスタンスの生成。 * 継承クラスで上書きする。 * @param s * @ */ protected void InitResource(NyARIntSize s) { this._gs_raster = new NyARGrayscaleRaster(s.w, s.h, NyARBufferType.INT1D_GRAY_8, true); }
/** * 透視投影行列と視錐体パラメータを元に、インスタンスを作成します。 * この関数は、樽型歪み矯正を外部で行うときに使います。 * @param i_prjmat * ARToolKitスタイルのカメラパラメータです。通常は{@link NyARParam#getPerspectiveProjectionMatrix()}から得られた値を使います。 * @param i_screen_size * スクリーン(入力画像)のサイズです。通常は{@link NyARParam#getScreenSize()}から得られた値を使います。 * @param i_near * 視錐体のnear-pointをmm単位で指定します。 * default値は{@link #FRASTRAM_ARTK_NEAR}です。 * @param i_far * 視錐体のfar-pointをmm単位で指定します。 * default値は{@link #FRASTRAM_ARTK_FAR}です。 * @param i_max_known_target * @param i_max_unknown_target * @throws NyARException */ public NyARRealityD3d(NyARPerspectiveProjectionMatrix i_prjmat, NyARIntSize i_screen_size, double i_near, double i_far, int i_max_known_target, int i_max_unknown_target) : base(i_screen_size, i_near, i_far, i_prjmat, null, i_max_known_target, i_max_unknown_target) { }
private int detectDataBitsIndex(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, double[] o_index_row, double[] o_index_col) { //周波数を測定 int[] freq_index1 = this.__detectDataBitsIndex_freq_index1; int[] freq_index2 = this.__detectDataBitsIndex_freq_index2; int frq_t = getRowFrequency(i_reader, i_raster_size, i_th.lt_y, i_th.th_h, i_th.th_l, freq_index1); int frq_b = getRowFrequency(i_reader, i_raster_size, i_th.rb_y, i_th.th_h, i_th.th_l, freq_index2); //周波数はまとも? if ((frq_t < 0 && frq_b < 0) || frq_t == frq_b) { return(-1); } //タイミングパターンからインデクスを作成 int freq_h, freq_v; int[] index; if (frq_t > frq_b) { freq_h = frq_t; index = freq_index1; } else { freq_h = frq_b; index = freq_index2; } for (int i = 0; i < freq_h + freq_h - 1; i++) { o_index_row[i * 2] = ((index[i + 1] - index[i]) * 2 / 5 + index[i]) + FRQ_EDGE; o_index_row[i * 2 + 1] = ((index[i + 1] - index[i]) * 3 / 5 + index[i]) + FRQ_EDGE; } int frq_l = getColFrequency(i_reader, i_raster_size, i_th.lt_x, i_th.th_h, i_th.th_l, freq_index1); int frq_r = getColFrequency(i_reader, i_raster_size, i_th.rb_x, i_th.th_h, i_th.th_l, freq_index2); //周波数はまとも? if ((frq_l < 0 && frq_r < 0) || frq_l == frq_r) { return(-1); } //タイミングパターンからインデクスを作成 if (frq_l > frq_r) { freq_v = frq_l; index = freq_index1; } else { freq_v = frq_r; index = freq_index2; } //同じ周期? if (freq_v != freq_h) { return(-1); } for (int i = 0; i < freq_v + freq_v - 1; i++) { int w = index[i]; int w2 = index[i + 1] - w; o_index_col[i * 2] = ((w2) * 2 / 5 + w) + FRQ_EDGE; o_index_col[i * 2 + 1] = ((w2) * 3 / 5 + w) + FRQ_EDGE; } //Lv4以上は無理 if (freq_v > MAX_FREQ) { return(-1); } return(freq_v); }
/** * この関数は、マーカ画像のi_x1列目とi_x2列目を平均して、タイミングパターンの周波数を得ます。 * L=暗点、H=明点、LHL=1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを * 検出した場合、関数は失敗します。 * @param i_x1 * ライン1のインデクス * @param i_th_h * 明点の敷居値 * @param i_th_l * 暗点の敷居値 * @param o_edge_index * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列。 * [FRQ_POINTS]以上の配列を指定すること。 * @return * 周波数の値。失敗すると-1 * @ */ public int getColFrequency(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, int i_x1, int i_th_h, int i_th_l, int[] o_edge_index) { double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int[] pixcel_temp = this._pixcel_temp; //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110 //初期化 int[] freq_count_table = this._freq_count_table; for (int i = 0; i < 10; i++) { freq_count_table[i] = 0; } int[] freq_table = this._freq_table; for (int i = 0; i < 110; i++) { freq_table[i] = 0; } int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; double cpara7 = cpara[7]; double cpara4 = cpara[4]; double cpara1 = cpara[1]; //基準点から4ピクセルを参照パターンとして抽出 for (int i = 0; i < FREQ_SAMPLE_NUM; i++) { int cx0 = 1 + i + i_x1; double cp6_0 = cpara[6] * cx0; double cpx0_0 = cpara[0] * cx0 + cpara[2]; double cpx3_0 = cpara[3] * cx0 + cpara[5]; int pt = 0; for (int i2 = 0; i2 < FRQ_POINTS; i2++) { int cy = 1 + i2 * FRQ_STEP + FRQ_EDGE; double d = cp6_0 + cpara7 * cy + 1.0; int x = (int)((cpx0_0 + cpara1 * cy) / d); int y = (int)((cpx3_0 + cpara4 * cy) / d); if (x < 0 || y < 0 || x >= raster_width || y >= raster_height) { return(-1); } ref_x[pt] = x; ref_y[pt] = y; pt++; } //ピクセルを取得(入力画像を多様化するならここを調整すること) i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp, 0); int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index); //周期は3-10であること if (freq_t < MIN_FREQ || freq_t > MAX_FREQ) { continue; } //周期は等間隔であること if (!checkFreqWidth(o_edge_index, freq_t)) { continue; } //検出カウンタを追加 freq_count_table[freq_t]++; int table_st = (freq_t - 1) * freq_t; for (int i2 = 0; i2 < freq_t * 2; i2++) { freq_table[table_st + i2] += o_edge_index[i2]; } } return(getMaxFreq(freq_count_table, freq_table, o_edge_index)); }
/** * コンストラクタ。 * @param i_screen * スクリーン(入力画像)のサイズを指定します。 * @param i_near * {@link #NyARReality(NyARParam i_param,double i_near,double i_far,int i_max_known_target,int i_max_unknown_target)}を参照 * @param i_far * {@link #NyARReality(NyARParam i_param,double i_near,double i_far,int i_max_known_target,int i_max_unknown_target)}を参照 * @param i_prjmat * ARToolKit形式の射影変換パラメータを指定します。 * @param i_dist_factor * カメラ歪み矯正オブジェクトを指定します。歪み矯正が不要な時は、nullを指定します。 * @param i_max_known_target * {@link #NyARReality(NyARParam i_param,double i_near,double i_far,int i_max_known_target,int i_max_unknown_target)}を参照 * @param i_max_unknown_target * {@link #NyARReality(NyARParam i_param,double i_near,double i_far,int i_max_known_target,int i_max_unknown_target)}を参照 * @throws NyARException */ public NyARReality(NyARIntSize i_screen, double i_near, double i_far, NyARPerspectiveProjectionMatrix i_prjmat, NyARCameraDistortionFactor i_dist_factor, int i_max_known_target, int i_max_unknown_target) { this.MAX_LIMIT_KNOWN = i_max_known_target; this.MAX_LIMIT_UNKNOWN = i_max_unknown_target; this.initInstance(i_screen, i_near, i_far, i_prjmat, i_dist_factor); }
public ARTKDetector(NyARCustomSingleDetectMarker i_parent, NyARIntSize i_size) : base(i_size) { this._parent = i_parent; }
/* カメラのプロジェクションMatrix(RH)を返します。 * このMatrixはMicrosoft.DirectX.Direct3d.Device.Transform.Projectionに設定できます。 */ public static void toCameraFrustumRH(NyARPerspectiveProjectionMatrix i_promat, NyARIntSize i_size, double i_scale, double i_near, double i_far, ref Matrix o_d3d_projection) { NyARDoubleMatrix44 m = new NyARDoubleMatrix44(); i_promat.makeCameraFrustumRH(i_size.w, i_size.h, i_near * i_scale, i_far * i_scale, m); NyARD3dUtil.mat44ToD3dMatrixT(m, ref o_d3d_projection); return; }
public void createHistogram(int i_skip, NyARHistogram o_histogram) { NyARIntSize s = this._gsr.getSize(); this.createHistogram(0, 0, s.w, s.h, i_skip, o_histogram); }
public NyARColorPatt_O3(int i_width, int i_height) { this._size = new NyARIntSize(i_width, i_height); this._patdata = new int[i_height * i_width]; this._pixelreader = new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata, this._size); }
/** * クリッピング付きのライントレーサです。 * * @param i_pos1 * @param i_pos2 * @param i_edge * @param o_coord * @return * @throws NyARException */ public bool traceLineWithClip(NyARDoublePoint2d i_pos1, NyARDoublePoint2d i_pos2, int i_edge, VecLinearCoordinates o_coord) { NyARIntSize s = this._ref_base_raster.getSize(); bool is_p1_inside_area, is_p2_inside_area; NyARIntPoint2d[] pt = this.__pt; // 線分が範囲内にあるかを確認 is_p1_inside_area = s.isInnerPoint(i_pos1); is_p2_inside_area = s.isInnerPoint(i_pos2); // 個数で分岐 if (is_p1_inside_area && is_p2_inside_area) { // 2ならクリッピング必要なし。 if (!this.traceLine(i_pos1, i_pos2, i_edge, o_coord)) { return(false); } return(true); } // 1,0個の場合は、線分を再定義 if (!this.__temp_l.makeLinearWithNormalize(i_pos1, i_pos2)) { return(false); } if (!this.__temp_l.makeSegmentLine(s.w, s.h, pt)) { return(false); } if (is_p1_inside_area != is_p2_inside_area) { // 1ならクリッピング後に、外に出ていた点に近い輪郭交点を得る。 if (is_p1_inside_area) { // p2が範囲外 pt[(i_pos2.sqDist(pt[0]) < i_pos2.sqDist(pt[1])) ? 1 : 0].setValue(i_pos1); } else { // p1が範囲外 pt[(i_pos1.sqDist(pt[0]) < i_pos2.sqDist(pt[1])) ? 1 : 0].setValue(i_pos2); } } else { // 0ならクリッピングして得られた2点を使う。 if (!this.__temp_l.makeLinearWithNormalize(i_pos1, i_pos2)) { return(false); } if (!this.__temp_l.makeSegmentLine(s.w, s.h, pt)) { return(false); } } if (!this.traceLine(pt[0], pt[1], i_edge, o_coord)) { return(false); } return(true); }
public void convertRect(int l, int t, int w, int h, INyARGrayscaleRaster o_raster) { Color32[] c = (Color32[])(this._ref_raster.getBuffer()); NyARIntSize size = this._ref_raster.getSize(); int src = (l + t * size.w) * 4; int b = t + h; int row_padding_dst = (size.w - w); int row_padding_src = row_padding_dst * 4; int pix_count = w; int pix_mod_part = pix_count - (pix_count % 8); // in_buf = (byte[])this._ref_raster.getBuffer(); switch (o_raster.getBufferType()) { case NyARBufferType.INT1D_GRAY_8: int[] out_buf = (int[])o_raster.getBuffer(); int dst_ptr; if (this._is_inverse) { dst_ptr = (h - 1 - t) * size.w + l; row_padding_dst -= size.w * 2; } else { dst_ptr = t * size.w + l; } for (int y = t; y < b; y++) { int x = 0; Color32 p; for (x = pix_count - 1; x >= pix_mod_part; x--) { p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; } for (; x >= 0; x -= 8) { p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; p = c[src++]; out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3; } dst_ptr += row_padding_dst; src += row_padding_src; } return; default: for (int y = t; y < b; y++) { for (int x = 0; x < pix_count; x++) { Color32 p = c[src++]; o_raster.setPixel(x, y, (p.r + p.g + p.b) / 3); } src += row_padding_src; } return; } }
/// <summary> /// Returns a right-handed perspective transformation matrix built from the camera calibration data. /// </summary> /// <param name="arParameters">The camera calibration data.</param> /// <param name="nearPlane">The near view plane of the frustum.</param> /// <param name="farPlane">The far view plane of the frustum.</param> /// <returns>The projection matrix.</returns> internal static Matrix3D GetCameraFrustumRH(this NyARParam arParameters, double nearPlane, double farPlane) { NyARMat transformation = new NyARMat(3, 4); NyARMat icParameters = new NyARMat(3, 4); double[,] p = new double[3, 3]; double[,] q = new double[4, 4]; NyARIntSize size = arParameters.getScreenSize(); int width = size.w; int height = size.h; arParameters.getPerspectiveProjectionMatrix().decompMat(icParameters, transformation); double[][] icpara = icParameters.getArray(); double[][] trans = transformation.getArray(); for (int i = 0; i < 4; i++) { icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i]; } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { p[i, j] = icpara[i][j] / icpara[2][2]; } } q[0, 0] = (2.0 * p[0, 0] / (width - 1)); q[0, 1] = (2.0 * p[0, 1] / (width - 1)); q[0, 2] = ((2.0 * p[0, 2] / (width - 1)) - 1.0); q[0, 3] = 0.0; q[1, 0] = 0.0; q[1, 1] = -(2.0 * p[1, 1] / (height - 1)); q[1, 2] = -((2.0 * p[1, 2] / (height - 1)) - 1.0); q[1, 3] = 0.0; q[2, 0] = 0.0; q[2, 1] = 0.0; q[2, 2] = (farPlane + nearPlane) / (nearPlane - farPlane); q[2, 3] = 2.0 * farPlane * nearPlane / (nearPlane - farPlane); q[3, 0] = 0.0; q[3, 1] = 0.0; q[3, 2] = -1.0; q[3, 3] = 0.0; return(new Matrix3D(q[0, 0] * trans[0][0] + q[0, 1] * trans[1][0] + q[0, 2] * trans[2][0], q[1, 0] * trans[0][0] + q[1, 1] * trans[1][0] + q[1, 2] * trans[2][0], q[2, 0] * trans[0][0] + q[2, 1] * trans[1][0] + q[2, 2] * trans[2][0], q[3, 0] * trans[0][0] + q[3, 1] * trans[1][0] + q[3, 2] * trans[2][0], q[0, 0] * trans[0][1] + q[0, 1] * trans[1][1] + q[0, 2] * trans[2][1], q[1, 0] * trans[0][1] + q[1, 1] * trans[1][1] + q[1, 2] * trans[2][1], q[2, 0] * trans[0][1] + q[2, 1] * trans[1][1] + q[2, 2] * trans[2][1], q[3, 0] * trans[0][1] + q[3, 1] * trans[1][1] + q[3, 2] * trans[2][1], q[0, 0] * trans[0][2] + q[0, 1] * trans[1][2] + q[0, 2] * trans[2][2], q[1, 0] * trans[0][2] + q[1, 1] * trans[1][2] + q[1, 2] * trans[2][2], q[2, 0] * trans[0][2] + q[2, 1] * trans[1][2] + q[2, 2] * trans[2][2], q[3, 0] * trans[0][2] + q[3, 1] * trans[1][2] + q[3, 2] * trans[2][2], q[0, 0] * trans[0][3] + q[0, 1] * trans[1][3] + q[0, 2] * trans[2][3] + q[0, 3], q[1, 0] * trans[0][3] + q[1, 1] * trans[1][3] + q[1, 2] * trans[2][3] + q[1, 3], q[2, 0] * trans[0][3] + q[2, 1] * trans[1][3] + q[2, 2] * trans[2][3] + q[2, 3], q[3, 0] * trans[0][3] + q[3, 1] * trans[1][3] + q[3, 2] * trans[2][3] + q[3, 3])); }
/** * この関数は、引数値がインスタンスのサイズよりも小さいかを返します。 * @param i_size * 比較するサイズ値 * @return * 引数値がインスタンスのサイズよりも小さければ、trueを返します。 * @ */ public bool isInnerSize(NyARIntSize i_size) { return (i_size.w <= this.w && i_size.h <= this.h); }
/** * サイズ値が、このサイズの範囲内であるか判定します。 * @param i_size * @return */ public bool isInnerSize(NyARIntSize i_size) { return(i_size.w <= this.w && i_size.h <= this.h); }
public void InitTracker(params object[] configs) { if (!(configs.Length == 3 || configs.Length == 5)) { throw new MarkerException("Problem in InitTracker in NewNyAR"); } int imgWidth = 0; int imgHeight = 0; try { imgWidth = (int)configs[0]; imgHeight = (int)configs[1]; configFilename = (String)configs[2]; if (configs.Length == 5) { threshold = (int)configs[3]; continuousMode = (bool)configs[4]; } else { threshold = 100; continuousMode = false; } } catch (Exception) { throw new MarkerException("Problem in InitTracker in NewNyAR"); } nyARIntSize = new NyARIntSize(imgWidth, imgHeight); param = new NyARParam(); param.loadARParam(TitleContainer.OpenStream(configFilename)); param.changeScreenSize(nyARIntSize.w, nyARIntSize.h); camProjMat = GetProjectionMatrix(param, zNearPlane, zFarPlane); INyARMarkerSystemConfig arMarkerSystemConfig = new NyARMarkerSystemConfig(param); markerSystem = new NyARMarkerSystem(arMarkerSystemConfig); initialized = true; }
public NyARIntSize(NyARIntSize i_ref_object) { this.w = i_ref_object.w; this.h = i_ref_object.h; return; }
/** * この関数はマーカパターンから、敷居値を決定します。 * @param i_reader * ラスタリーダオブジェクト * @param i_raster_size * ラスのタのサイズ * @param o_threshold * 敷居値を受け取るオブジェクト * @ */ public void detectThresholdValue(INyARGsPixelDriver i_reader, TThreshold o_threshold) { int[] th_pixels = this._th_pixels; NyARIntSize size = i_reader.getSize(); //左上のピックアップ領域からピクセルを得る(00-24) rectPixels(i_reader, size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, 0, th_pixels); //左下のピックアップ領域からピクセルを得る(25-49) rectPixels(i_reader, size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE, th_pixels); //右上のピックアップ領域からピクセルを得る(50-74) rectPixels(i_reader, size, THRESHOLD_SAMPLE_RB, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE * 2, th_pixels); //右下のピックアップ領域からピクセルを得る(75-99) rectPixels(i_reader, size, THRESHOLD_SAMPLE_RB, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE * 3, th_pixels); THighAndLow hl = this.__detectThresholdValue_hl; //Ptailで求めたピクセル平均 getPtailHighAndLow(th_pixels, hl); //閾値中心 int th = (hl.h + hl.l) / 2; //ヒステリシス(差分の20%) int th_sub = (hl.h - hl.l) / 5; o_threshold.th = th; o_threshold.th_h = th + th_sub; //ヒステリシス付き閾値 o_threshold.th_l = th - th_sub; //ヒステリシス付き閾値 //エッジを計算(明点重心) int lt_x, lt_y, lb_x, lb_y, rt_x, rt_y, rb_x, rb_y; NyARIntPoint2d tpt = this.__detectThresholdValue_tpt; //LT if (getHighPixelCenter(0, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt)) { lt_x = tpt.x * THRESHOLD_STEP; lt_y = tpt.y * THRESHOLD_STEP; } else { lt_x = 11; lt_y = 11; } //LB if (getHighPixelCenter(THRESHOLD_SAMPLE * 1, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt)) { lb_x = tpt.x * THRESHOLD_STEP; lb_y = tpt.y * THRESHOLD_STEP; } else { lb_x = 11; lb_y = -1; } //RT if (getHighPixelCenter(THRESHOLD_SAMPLE * 2, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt)) { rt_x = tpt.x * THRESHOLD_STEP; rt_y = tpt.y * THRESHOLD_STEP; } else { rt_x = -1; rt_y = 11; } //RB if (getHighPixelCenter(THRESHOLD_SAMPLE * 3, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt)) { rb_x = tpt.x * THRESHOLD_STEP; rb_y = tpt.y * THRESHOLD_STEP; } else { rb_x = -1; rb_y = -1; } //トラッキング開始位置の決定 o_threshold.lt_x = (lt_x + lb_x) / 2 + THRESHOLD_SAMPLE_LT - 1; o_threshold.rb_x = (rt_x + rb_x) / 2 + THRESHOLD_SAMPLE_RB + 1; o_threshold.lt_y = (lt_y + rt_y) / 2 + THRESHOLD_SAMPLE_LT - 1; o_threshold.rb_y = (lb_y + rb_y) / 2 + THRESHOLD_SAMPLE_RB + 1; return; }
public NyARFixedFloatObserv2IdealMap(NyARCameraDistortionFactor i_distfactor, NyARIntSize i_screen_size) { NyARDoublePoint2d opoint = new NyARDoublePoint2d(); this._mapx = new int[i_screen_size.w * i_screen_size.h]; this._mapy = new int[i_screen_size.w * i_screen_size.h]; this._stride = i_screen_size.w; int ptr = i_screen_size.h * i_screen_size.w - 1; //歪みマップを構築 for (int i = i_screen_size.h - 1; i >= 0; i--) { for (int i2 = i_screen_size.w - 1; i2 >= 0; i2--) { i_distfactor.observ2Ideal(i2, i, opoint); this._mapx[ptr] = (int)(opoint.x * 65536); this._mapy[ptr] = (int)(opoint.y * 65536); ptr--; } } i_distfactor.getValue(this._factor); return; }
/** * この関数は、マーカパターンからデータを読み取ります。 * @param i_reader * ラスタリーダ * @param i_raster_size * ラスタのサイズ * @param i_th * 敷居値情報 * @param o_bitbuffer * データビットの出力先 * @return * 成功するとtrue * @ */ public bool readDataBits(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer) { int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; double[] index_x = this.__readDataBits_index_bit_x; double[] index_y = this.__readDataBits_index_bit_y; //読み出し位置を取得 int size = detectDataBitsIndex(i_reader, i_raster_size, i_th, index_x, index_y); int resolution = size + size - 1; if (size < 0) { return(false); } if (!o_bitbuffer.initEncoder(size - 1)) { return(false); } double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int[] pixcel_temp = this._pixcel_temp; double cpara_0 = cpara[0]; double cpara_1 = cpara[1]; double cpara_3 = cpara[3]; double cpara_6 = cpara[6]; int th = i_th.th; int p = 0; for (int i = 0; i < resolution; i++) { //1列分のピクセルのインデックス値を計算する。 double cy0 = 1 + index_y[i * 2 + 0]; double cy1 = 1 + index_y[i * 2 + 1]; double cpy0_12 = cpara_1 * cy0 + cpara[2]; double cpy0_45 = cpara[4] * cy0 + cpara[5]; double cpy0_7 = cpara[7] * cy0 + 1.0; double cpy1_12 = cpara_1 * cy1 + cpara[2]; double cpy1_45 = cpara[4] * cy1 + cpara[5]; double cpy1_7 = cpara[7] * cy1 + 1.0; int pt = 0; for (int i2 = 0; i2 < resolution; i2++) { int xx, yy; double d; double cx0 = 1 + index_x[i2 * 2 + 0]; double cx1 = 1 + index_x[i2 * 2 + 1]; double cp6_0 = cpara_6 * cx0; double cpx0_0 = cpara_0 * cx0; double cpx3_0 = cpara_3 * cx0; double cp6_1 = cpara_6 * cx1; double cpx0_1 = cpara_0 * cx1; double cpx3_1 = cpara_3 * cx1; d = cp6_0 + cpy0_7; ref_x[pt] = xx = (int)((cpx0_0 + cpy0_12) / d); ref_y[pt] = yy = (int)((cpx3_0 + cpy0_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; d = cp6_0 + cpy1_7; ref_x[pt] = xx = (int)((cpx0_0 + cpy1_12) / d); ref_y[pt] = yy = (int)((cpx3_0 + cpy1_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; d = cp6_1 + cpy0_7; ref_x[pt] = xx = (int)((cpx0_1 + cpy0_12) / d); ref_y[pt] = yy = (int)((cpx3_1 + cpy0_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; d = cp6_1 + cpy1_7; ref_x[pt] = xx = (int)((cpx0_1 + cpy1_12) / d); ref_y[pt] = yy = (int)((cpx3_1 + cpy1_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; } //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい) i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp, 0); //グレースケールにしながら、line→mapへの転写 for (int i2 = 0; i2 < resolution; i2++) { int index = i2 * 4; int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3]) / 4; // +pixcel_temp[index+4]+pixcel_temp[index+5]+ // pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+ // pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3); //暗点を1、明点を0で表現します。 o_bitbuffer.setBitByBitIndex(p, pixel > th ? 0 : 1); p++; } } return(true); }
public RleDetector(NyARSingleDetectMarker i_parent, NyARIntSize i_size) : base(i_size) { this._parent = i_parent; }
public NyARSensor(NyARIntSize i_size) { this.InitInstance(i_size); this._hist_drv = (INyARHistogramFromRaster)this._gs_raster.createInterface(typeof(INyARHistogramFromRaster)); }
public void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) { Debug.Assert(i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr = (int[])i_input.getBuffer(); int[] out_ptr = (int[])i_output.getBuffer(); int width = i_size.w; int idx = 0; int idx2 = width; int fx, fy; int mod_p = (width - 2) - (width - 2) % 4; for (int y = i_size.h - 2; y >= 0; y--) { int p00 = in_ptr[idx++]; int p10 = in_ptr[idx2++]; int p01, p11; int x = width - 2; for (; x >= mod_p; x--) { p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx = (fx * fx + fy * fy) >> SH; out_ptr[idx - 2] = (fx > 255?0:255 - fx); p00 = p01; p10 = p11; } for (; x >= 0; x -= 4) { p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx = (fx * fx + fy * fy) >> SH; out_ptr[idx - 2] = (fx > 255?0:255 - fx); p00 = p01; p10 = p11; p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx = (fx * fx + fy * fy) >> SH; out_ptr[idx - 2] = (fx > 255?0:255 - fx); p00 = p01; p10 = p11; p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx = (fx * fx + fy * fy) >> SH; out_ptr[idx - 2] = (fx > 255?0:255 - fx); p00 = p01; p10 = p11; p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx = (fx * fx + fy * fy) >> SH; out_ptr[idx - 2] = (fx > 255?0:255 - fx); p00 = p01; p10 = p11; } out_ptr[idx - 1] = 255; } for (int x = width - 1; x >= 0; x--) { out_ptr[idx++] = 255; } return; }
public void switchRaster(INyARRgbRaster i_raster) { this._ref_buf = (short[])i_raster.getBuffer(); this._ref_size = i_raster.getSize(); }
/** * この関数は、マーカパターンからデータを読み取ります。 * @param i_reader * ラスタリーダ * @param i_raster_size * ラスタのサイズ * @param o_bitbuffer * データビットの出力先 * @return * 成功するとtrue * @throws NyARException */ public bool readDataBits(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, MarkerPattDecoder o_bitbuffer) { int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; double[] index_x = this.__readDataBits_index_bit_x; double[] index_y = this.__readDataBits_index_bit_y; //読み出し位置を取得 detectDataBitsIndex(index_x, index_y); int resolution = 3; double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int[] pixcel_temp = this._pixcel_temp; double cpara_0 = cpara[0]; double cpara_1 = cpara[1]; double cpara_3 = cpara[3]; double cpara_6 = cpara[6]; int p = 0; for (int i = 0; i < resolution; i++) { //1列分のピクセルのインデックス値を計算する。 double cy0 = 1 + index_y[i * 2 + 0]; double cy1 = 1 + index_y[i * 2 + 1]; double cpy0_12 = cpara_1 * cy0 + cpara[2]; double cpy0_45 = cpara[4] * cy0 + cpara[5]; double cpy0_7 = cpara[7] * cy0 + 1.0; double cpy1_12 = cpara_1 * cy1 + cpara[2]; double cpy1_45 = cpara[4] * cy1 + cpara[5]; double cpy1_7 = cpara[7] * cy1 + 1.0; int pt = 0; for (int i2 = 0; i2 < resolution; i2++) { int xx, yy; double d; double cx0 = 1 + index_x[i2 * 2 + 0]; double cx1 = 1 + index_x[i2 * 2 + 1]; double cp6_0 = cpara_6 * cx0; double cpx0_0 = cpara_0 * cx0; double cpx3_0 = cpara_3 * cx0; double cp6_1 = cpara_6 * cx1; double cpx0_1 = cpara_0 * cx1; double cpx3_1 = cpara_3 * cx1; d = cp6_0 + cpy0_7; ref_x[pt] = xx = (int)((cpx0_0 + cpy0_12) / d); ref_y[pt] = yy = (int)((cpx3_0 + cpy0_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; d = cp6_0 + cpy1_7; ref_x[pt] = xx = (int)((cpx0_0 + cpy1_12) / d); ref_y[pt] = yy = (int)((cpx3_0 + cpy1_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; d = cp6_1 + cpy0_7; ref_x[pt] = xx = (int)((cpx0_1 + cpy0_12) / d); ref_y[pt] = yy = (int)((cpx3_1 + cpy0_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; d = cp6_1 + cpy1_7; ref_x[pt] = xx = (int)((cpx0_1 + cpy1_12) / d); ref_y[pt] = yy = (int)((cpx3_1 + cpy1_45) / d); if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height) { ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx); ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy); } pt++; } //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい) i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp, 0); //グレースケールにしながら、line→mapへの転写 for (int i2 = 0; i2 < resolution; i2++) { int index = i2 * 4; o_bitbuffer.setBit(p, (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3]) / 4); p++; } } return(true); }
public NyARRgbPixelReader_BYTE1D_X8R8G8B8_32(byte[] i_buf, NyARIntSize i_size) { this._ref_buf = i_buf; this._size = i_size; }
public void convert(INyARGrayscaleRaster i_raster) { NyARIntSize s = this._ref_raster.getSize(); this.convertRect(0, 0, s.w, s.h, i_raster); }
/** * コンストラクタです。マーカシステムに対応したレンダラを構築します。 * @param i_ms */ public NyARD3dRender(Device i_dev, NyARSingleCameraSystem i_scs) { this._scs = i_scs; this._screen_size = _scs.getARParam().getScreenSize(); i_scs.addObserver(this); }
public bool isEqualSize(NyARIntSize i_s) { return(this.m_height == i_s.h && this.m_width == i_s.w); }
/** * この関数は、ARToolKitスタイルのProjectionMatrixから、 CameraFrustamを計算します。 * @param i_promat * @param i_size * スクリーンサイズを指定します。 * @param i_scale * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 * @param i_near * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 * @param i_far * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 * @param o_gl_projection * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 */ public static void toCameraFrustumRH(NyARPerspectiveProjectionMatrix i_promat, NyARIntSize i_size, double i_scale, double i_near, double i_far, ref Matrix4x4 o_mat) { NyARDoubleMatrix44 m = new NyARDoubleMatrix44(); i_promat.makeCameraFrustumRH(i_size.w, i_size.h, i_near * i_scale, i_far * i_scale, m); o_mat.m00 = (float)m.m00; o_mat.m01 = (float)m.m01; o_mat.m02 = (float)m.m02; o_mat.m03 = (float)m.m03; o_mat.m10 = (float)m.m10; o_mat.m11 = (float)m.m11; o_mat.m12 = (float)m.m12; o_mat.m13 = (float)m.m13; o_mat.m20 = (float)m.m20; o_mat.m21 = (float)m.m21; o_mat.m22 = (float)m.m22; o_mat.m23 = (float)m.m23; o_mat.m30 = (float)m.m30; o_mat.m31 = (float)m.m31; o_mat.m32 = (float)m.m32; o_mat.m33 = (float)m.m33; return; }
public void switchRaster(INyARRaster i_ref_raster) { this._ref_buf = (int[])i_ref_raster.getBuffer(); this._ref_size = i_ref_raster.getSize(); }
public bool isEqualSize(NyARIntSize i_s) { Debug.Assert(!this._is_dispose); return(i_s.w == this.m_width && i_s.h == this.m_height); }
/** * コンストラクタです。 * @param i_ref_object * 引数値で初期化したインスタンスを生成します。 */ public NyARIntSize(NyARIntSize i_ref_object) { this.w = i_ref_object.w; this.h = i_ref_object.h; return; }
/** * この関数は、マーカ画像のi_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。 * L=暗点、H=明点、LHL=1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを * 検出した場合、関数は失敗します。 * @param i_y1 * ライン1のインデクス * @param i_th_h * 明点の敷居値 * @param i_th_l * 暗点の敷居値 * @param o_edge_index * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列。 * [FRQ_POINTS]以上の配列を指定すること。 * @return * 周波数の値。失敗すると-1 * @ */ public int getRowFrequency(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, int i_y1, int i_th_h, int i_th_l, int[] o_edge_index) { //3,4,5,6,7,8,9,10 int[] freq_count_table = this._freq_count_table; //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列 int[] freq_table = this._freq_table; //初期化 double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int[] pixcel_temp = this._pixcel_temp; for (int i = 0; i < 10; i++) { freq_count_table[i] = 0; } for (int i = 0; i < 110; i++) { freq_table[i] = 0; } int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; double cpara_0 = cpara[0]; double cpara_3 = cpara[3]; double cpara_6 = cpara[6]; //10-20ピクセル目からタイミングパターンを検出 for (int i = 0; i < FREQ_SAMPLE_NUM; i++) { //2行分のピクセルインデックスを計算 double cy0 = 1 + i_y1 + i; double cpy0_12 = cpara[1] * cy0 + cpara[2]; double cpy0_45 = cpara[4] * cy0 + cpara[5]; double cpy0_7 = cpara[7] * cy0 + 1.0; int pt = 0; for (int i2 = 0; i2 < FRQ_POINTS; i2++) { double cx0 = 1 + i2 * FRQ_STEP + FRQ_EDGE; double d = (cpara_6 * cx0) + cpy0_7; int x = (int)((cpara_0 * cx0 + cpy0_12) / d); int y = (int)((cpara_3 * cx0 + cpy0_45) / d); if (x < 0 || y < 0 || x >= raster_width || y >= raster_height) { return(-1); } ref_x[pt] = x; ref_y[pt] = y; pt++; } //ピクセルを取得(入力画像を多様化するならここから先を調整すること) i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp, 0); //o_edge_indexを一時的に破壊して調査する int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index); //周期は3-10であること if (freq_t < MIN_FREQ || freq_t > MAX_FREQ) { continue; } //周期は等間隔であること if (!checkFreqWidth(o_edge_index, freq_t)) { continue; } //検出カウンタを追加 freq_count_table[freq_t]++; int table_st = (freq_t - 1) * freq_t; for (int i2 = 0; i2 < freq_t * 2; i2++) { freq_table[table_st + i2] += o_edge_index[i2]; } } return(getMaxFreq(freq_count_table, freq_table, o_edge_index)); }
protected NyARRaster_BasicClass(int i_width, int i_height, int i_buffer_type) { this._size = new NyARIntSize(i_width, i_height); this._buffer_type=i_buffer_type; }