/** * この関数は、点が矩形の範囲内にあるか判定します。 * @param i_pos * 調査する座標 * @return * 点が矩形の中にあれば、trueを返します。 */ public bool isInnerPoint(NyARIntPoint2d i_pos) { int x = i_pos.x - this.x; int y = i_pos.y - this.y; return(0 <= x && x < this.w && 0 <= y && y < this.h); }
/** * p2-p1間の距離の二乗値を計算します。 * @param i_p1 * @param i_p2 * @return */ public int sqDist(NyARIntPoint2d i_p1) { int x = this.x - i_p1.x; int y = this.y - i_p1.y; return(x * x + y * y); }
/** * この関数は、ラスタドライバから画像を読み出します。 * @param i_pix_drv * @param i_size * @param i_vertex * @param o_data * @param o_param * @return * @ */ public bool pickFromRaster(INyARGsPixelDriver i_pix_drv, NyARIntPoint2d[] i_vertex, NyIdMarkerPattern o_data, NyIdMarkerParam o_param) { if (!this._perspective_reader.setSourceSquare(i_vertex)) { return false; } return this._pickFromRaster(i_pix_drv, o_data, o_param); }
public void observ2Ideal(int ix, int iy, NyARIntPoint2d o_point) { int idx = ix + iy * this._stride; o_point.x = (int)this._mapx[idx]; o_point.y = (int)this._mapy[idx]; return; }
/** * 座標値を射影変換します。 * @param i_3dvertex * 変換元の座標値 * @param o_2d * 変換後の座標値を受け取るオブジェクト */ public void project(NyARDoublePoint3d i_3dvertex, NyARIntPoint2d o_2d) { double w = 1 / (i_3dvertex.z * this.m22); o_2d.x = (int)((i_3dvertex.x * this.m00 + i_3dvertex.y * this.m01 + i_3dvertex.z * this.m02) * w); o_2d.y = (int)((i_3dvertex.y * this.m11 + i_3dvertex.z * this.m12) * w); return; }
/** * 座標値を射影変換します。 * @param i_x * 変換元の座標値 * @param i_y * 変換元の座標値 * @param i_z * 変換元の座標値 * @param o_2d * 変換後の座標値を受け取るオブジェクト */ public void project(double i_x, double i_y, double i_z, NyARIntPoint2d o_2d) { double w = 1 / (i_z * this.m22); o_2d.x = (int)((i_x * this.m00 + i_y * this.m01 + i_z * this.m02) * w); o_2d.y = (int)((i_y * this.m11 + i_z * this.m12) * w); return; }
/** * この関数は、ラスタドライバから画像を読み出します。 * @param i_pix_drv * @param i_size * @param i_vertex * @param o_data * @param o_param * @return * @throws NyARException */ public bool getARPlayCardId(INyARGsPixelDriver i_pix_drv, NyARIntPoint2d[] i_vertex, PsArIdParam i_result) { if (!this._perspective_reader.setSourceSquare(i_vertex)) { return false; } return this._pickFromRaster(i_pix_drv, i_result); }
public double sqDist(NyARIntPoint2d i_p1) { double x, y; x = this.x - i_p1.x; y = this.y - i_p1.y; return(x * x + y * y); }
/** * 4近傍の画素ベクトルを取得します。 * 0,1,0 * 1,x,1 * 0,1,0 * @param i_raster * @param x * @param y * @param o_v */ public void getPixelVector4(int x, int y, NyARIntPoint2d o_v) { int[] buf = this._ref_buf; int w = this._ref_size.w; int idx = w * y + x; o_v.x = buf[idx + 1] - buf[idx - 1]; o_v.y = buf[idx + w] - buf[idx - w]; }
/** * 配列ファクトリ * @param i_number * @return */ public static NyARIntPoint2d[] createArray(int i_number) { NyARIntPoint2d[] ret = new NyARIntPoint2d[i_number]; for (int i = 0; i < i_number; i++) { ret[i] = new NyARIntPoint2d(); } return(ret); }
public static void copyArray(NyARIntPoint2d[] i_from, NyARIntPoint2d[] i_to) { for (int i = i_from.Length - 1; i >= 0; i--) { i_to[i].x = i_from[i].x; i_to[i].y = i_from[i].y; } return; }
/** * 配列ファクトリ * @param i_number * @return */ public static NyARIntPoint2d[] createArray(int i_number) { NyARIntPoint2d[] ret = new NyARIntPoint2d[i_number]; for (int i = 0; i < i_number; i++) { ret[i] = new NyARIntPoint2d(); } return ret; }
public pickFromRaster_4x(NyARIntPoint2d i_lt, NyARIntSize i_source_size) { this._lt_ref = i_lt; this._size_ref = i_source_size; this._rgb_temp = new int[4 * 4 * 3]; this._rgb_px = new int[4 * 4]; this._rgb_py = new int[4 * 4]; return; }
public bool crossPos(double i_a, double i_b, double i_c, NyARIntPoint2d o_point) { double w1 = this.a * i_b - i_a * this.b; if (w1 == 0.0) { return(false); } o_point.x = (int)((this.b * i_c - i_b * this.c) / w1); o_point.y = (int)((i_a * this.c - this.a * i_c) / w1); return(true); }
/** * 8近傍画素ベクトル * 1,2,1 * 2,x,2 * 1,2,1 * @param i_raster * @param x * @param y * @param o_v */ public void getPixelVector8(int x, int y, NyARIntPoint2d o_v) { int[] buf = this._ref_buf; NyARIntSize s = this._ref_size; int idx_0 = s.w * y + x; int idx_p1 = idx_0 + s.w; int idx_m1 = idx_0 - s.w; int b = buf[idx_m1 - 1]; int d = buf[idx_m1 + 1]; int h = buf[idx_p1 - 1]; int f = buf[idx_p1 + 1]; o_v.x = buf[idx_0 + 1] - buf[idx_0 - 1] + (d - b + f - h) / 2; o_v.y = buf[idx_p1] - buf[idx_m1] + (f - d + h - b) / 2; }
public pickFromRaster_N(NyARIntPoint2d i_lt, int i_resolution, NyARIntSize i_source_size) { this._lt_ref = i_lt; this._resolution = i_resolution; this._size_ref = i_source_size; this._rgb_temp = new int[i_resolution * i_resolution * 3]; this._rgb_px = new int[i_resolution * i_resolution]; this._rgb_py = new int[i_resolution * i_resolution]; this._cp1cy_cp2 = new double[i_resolution]; this._cp4cy_cp5 = new double[i_resolution]; this._cp7cy_1 = new double[i_resolution]; return; }
public bool traceConture(int i_th, NyARIntPoint2d i_entry, VecLinearCoordinates o_coord) { NyARIntCoordinates coord = this._coord_buf; // Robertsラスタから輪郭抽出 if (!this._cpickup.getContour(this._ref_rob_raster, i_th, i_entry.x, i_entry.y, coord)) { // 輪郭線MAXならなにもできないね。 return false; } // 輪郭線のベクトル化 return traceConture(coord, this._rob_resolution, this._rob_resolution * 2, o_coord); }
/** * この関数は、座標点を理想座標系から観察座標系へ変換します。 */ public void ideal2Observ(double i_x, double i_y, NyARIntPoint2d o_out) { double x = (i_x - this._f0) * this._f3; double y = (i_y - this._f1) * this._f3; if (x == 0.0 && y == 0.0) { o_out.x = (int)(this._f0); o_out.y = (int)(this._f1); } else { double d = 1.0 - this._f2 / 100000000.0 * (x * x + y * y); o_out.x = (int)(x * d + this._f0); o_out.y = (int)(y * d + this._f1); } return; }
/** * この直線を、任意の矩形でクリッピングしたときに得られる線分の2頂点を返します。 * @param i_left * @param i_top * @param i_width * @param i_height * @param o_point * @return */ public bool makeSegmentLine(int i_left, int i_top, int i_width, int i_height, NyARIntPoint2d[] o_point) { int bottom = i_top + i_height; int right = i_left + i_width; int idx = 0; NyARIntPoint2d ptr = o_point[0]; if (this.crossPos(0, -1, i_top, ptr) && ptr.x >= i_left && ptr.x < right) { //y=rect.yの線 idx++; ptr = o_point[idx]; } if (this.crossPos(0, -1, bottom - 1, ptr) && ptr.x >= i_left && ptr.x < right) { //y=(rect.y+rect.h-1)の線 idx++; if (idx == 2) { return(true); } ptr = o_point[idx]; } if (this.crossPos(-1, 0, i_left, ptr) && ptr.y >= i_top && ptr.y < bottom) { //x=i_leftの線 idx++; if (idx == 2) { return(true); } ptr = o_point[idx]; } if (this.crossPos(-1, 0, right - 1, ptr) && ptr.y >= i_top && ptr.y < bottom) { //x=i_right-1の線 idx++; if (idx == 2) { return(true); } } return(false); }
public void ideal2Observ(double i_x, double i_y, NyARIntPoint2d o_out) { double k1 = this._k1; double k2 = this._k2; double p1 = this._p1; double p2 = this._p2; double fx = this._fx; double fy = this._fy; double x0 = this._x0; double y0 = this._y0; double s = this._s; double x = (i_x - x0) * s / fx; double y = (i_y - y0) * s / fy; double l = x * x + y * y; o_out.x = (int)((x * (1.0 + k1 * l + k2 * l * l) + 2.0 * p1 * x * y + p2 * (l + 2.0 * x * x)) * fx + x0); o_out.y = (int)((y * (1.0 + k1 * l + k2 * l * l) + p1 * (l + 2.0 * y * y) + 2.0 * p2 * x * y) * fy + y0); }
/** * i_x,i_yを通るこの直線の法線上での、この直線とi_linearの距離の二乗値を返します。 * i_x,i_yに直線上の点を指定すると、この直線の垂線上での、もう一方の直線との距離の二乗値が得られます。 * @param i_linear * @param i_x * @param i_y * @param o_point * @return * 交点が無い場合、無限大を返します。 *//* * public final double sqDistWithLinear(NyARLinear i_linear, double i_x,double i_y) * { * //thisを法線に変換 * double la=this.b; * double lb=-this.a; * double lc=-(la*i_x+lb*i_y); * //交点を計算 * final double w1 = i_linear.a * lb - la * i_linear.b; * if (w1 == 0.0) { * return Double.POSITIVE_INFINITY; * } * double x=i_x-((i_linear.b * lc - lb * i_linear.c) / w1); * double y=i_y-((la * i_linear.c - i_linear.a * lc) / w1); * return x*x+y*y; * }*/ /** * この矩形を任意の範囲でクリッピングしたときの2頂点を返します。 * @param i_width * @param i_height * @param o_point * @return */ public bool makeSegmentLine(int i_width, int i_height, NyARIntPoint2d[] o_point) { int idx = 0; NyARIntPoint2d ptr = o_point[0]; if (this.crossPos(0, -1, 0, ptr) && ptr.x >= 0 && ptr.x < i_width) { //y=rect.yの線 idx++; ptr = o_point[idx]; } if (this.crossPos(0, -1, i_height - 1, ptr) && ptr.x >= 0 && ptr.x < i_width) { //y=(rect.y+rect.h-1)の線 idx++; if (idx == 2) { return(true); } ptr = o_point[idx]; } if (this.crossPos(-1, 0, 0, ptr) && ptr.y >= 0 && ptr.y < i_height) { //x=i_leftの線 idx++; if (idx == 2) { return(true); } ptr = o_point[idx]; } if (this.crossPos(-1, 0, i_width - 1, ptr) && ptr.y >= 0 && ptr.y < i_height) { //x=i_right-1の線 idx++; if (idx == 2) { return(true); } } return(false); }
/** * [readonly]マーカにマッチした{@link NyARMatchPattDeviationColorData}インスタンスを得る。 * @ */ public NyARMatchPattDeviationColorData getDeviationColorData(ARMarkerList.Item i_marker, INyARPerspectiveCopy i_pix_drv, NyARIntPoint2d[] i_vertex) { int mk_edge = i_marker.patt_edge_percentage; for (int i = this.items.Count - 1; i >= 0; i--) { Item ptr = this.items[i]; if (!ptr._patt.getSize().isEqualSize(i_marker.patt_w, i_marker.patt_h) || ptr._patt_edge != mk_edge) { //サイズとエッジサイズが合致しない物はスルー continue; } //古かったら更新 i_pix_drv.copyPatt(i_vertex, ptr._patt_edge, ptr._patt_edge, ptr._patt_resolution, ptr._patt); ptr._patt_d.setRaster(ptr._patt); return ptr._patt_d; } //無い。新しく生成 Item item = new Item(i_marker.patt_w, i_marker.patt_h, mk_edge); //タイムスタンプの更新とデータの生成 i_pix_drv.copyPatt(i_vertex, item._patt_edge, item._patt_edge, item._patt_resolution, item._patt); item._patt_d.setRaster(item._patt); this.items.Add(item); return item._patt_d; }
// /** // * i_x,i_yを通るこの直線の法線上での、この直線とi_linearの距離の二乗値を返します。 // * i_x,i_yに直線上の点を指定すると、この直線の垂線上での、もう一方の直線との距離の二乗値が得られます。 // * @param i_linear // * @param i_x // * @param i_y // * @param o_point // * @return // * 交点が無い場合、無限大を返します。 // */ // public const double sqDistWithLinear(NyARLinear i_linear, double i_x,double i_y) // { // //thisを法線に変換 // double la=this.b; // double lb=-this.a; // double lc=-(la*i_x+lb*i_y); // //交点を計算 // const double w1 = i_linear.a * lb - la * i_linear.b; // if (w1 == 0.0) { // return Double.POSITIVE_INFINITY; // } // double x=i_x-((i_linear.b * lc - lb * i_linear.c) / w1); // double y=i_y-((la * i_linear.c - i_linear.a * lc) / w1); // return x*x+y*y; // } /** * この関数は、直線を0,0基点(左上)の矩形でクリッピングしたときの、端点を計算します。 * @param i_width * 矩形の幅 * @param i_height * 矩形の高さ * @param o_point * 端点を返すオブジェクト配列。2要素である必要があります。 * @return * 端点が求まればtrue */ public bool makeSegmentLine(int i_width, int i_height, NyARIntPoint2d[] o_point) { int idx = 0; NyARIntPoint2d ptr = o_point[0]; if (this.crossPos(0, -1, 0, ptr) && ptr.x >= 0 && ptr.x < i_width) { //y=rect.yの線 idx++; ptr = o_point[idx]; } if (this.crossPos(0, -1, i_height - 1, ptr) && ptr.x >= 0 && ptr.x < i_width) { //y=(rect.y+rect.h-1)の線 idx++; if (idx == 2) { return true; } ptr = o_point[idx]; } if (this.crossPos(-1, 0, 0, ptr) && ptr.y >= 0 && ptr.y < i_height) { //x=i_leftの線 idx++; if (idx == 2) { return true; } ptr = o_point[idx]; } if (this.crossPos(-1, 0, i_width - 1, ptr) && ptr.y >= 0 && ptr.y < i_height) { //x=i_right-1の線 idx++; if (idx == 2) { return true; } } return false; }
/** * この関数は、直線の交点を計算します。 * @param i_a * 交点を求める直線式の係数a * @param i_b * 交点を求める直線式の係数b * @param i_c * 交点を求める直線式の係数c * @param o_point * 交点座標を格納するオブジェクト * @return * 交点が求まればtrue */ public bool crossPos(double i_a, double i_b, double i_c, NyARIntPoint2d o_point) { double w1 = this.a * i_b - i_a * this.b; if (w1 == 0.0) { return false; } o_point.x = (int)((this.b * i_c - i_b * this.c) / w1); o_point.y = (int)((i_a * this.c - this.a * i_c) / w1); return true; }
/** * この関数は、2点を結ぶ直線式を計算して、インスタンスに格納します。 * 式の係数値は、正規化されます。 * @param i_point1 * 点1 * @param i_point2 * 点2 * @return * 直線式が求まれば、true */ public bool makeLinearWithNormalize(NyARIntPoint2d i_point1, NyARIntPoint2d i_point2) { return makeLinearWithNormalize(i_point1.x, i_point1.y, i_point2.x, i_point2.y); }
public NyARDoublePoint2d(NyARIntPoint2d i_src) { this.x = (double)i_src.x; this.y = (double)i_src.y; return; }
public void setValue(NyARIntPoint2d i_src) { this.x = (double)i_src.x; this.y = (double)i_src.y; return; }
public bool setSquare(NyARIntPoint2d[] i_vertex) { if (!this._param_gen.getParam(i_vertex, this._cparam)) { return false; } return true; }
private bool getHighPixelCenter(int i_st, int[] i_pixels, int i_width, int i_height, int i_th, NyARIntPoint2d o_point) { int rp = i_st; int pos_x = 0; int pos_y = 0; int number_of_pos = 0; for (int i = 0; i < i_height; i++) { for (int i2 = 0; i2 < i_width; i2++) { if (i_pixels[rp++] > i_th) { pos_x += i2; pos_y += i; number_of_pos++; } } } if (number_of_pos > 0) { pos_x /= number_of_pos; pos_y /= number_of_pos; } else { return false; } o_point.x = pos_x; o_point.y = pos_y; return true; }
/** * i_sourceの値を、thisへセットします。 * @param i_source */ public void setValue(NyARIntPoint2d i_source) { this.x = i_source.x; this.y = i_source.y; }
/** * この関数は、遠近法のパラメータを計算して、返却します。 * @param i_width * 変換先の矩形のサイズを指定します。 * @param i_height * 変換先の矩形のサイズを指定します。 * @param i_vertex * 変換元の頂点を指定します。要素数は4でなければなりません。 * @param o_param * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。 * @return * 成功するとtrueを返します。 * @ */ public bool getParam(int i_width, int i_height, NyARIntPoint2d[] i_vertex, double[] o_param) { return this.getParam(i_width, i_height, i_vertex[0].x, i_vertex[0].y, i_vertex[1].x, i_vertex[1].y, i_vertex[2].x, i_vertex[2].y, i_vertex[3].x, i_vertex[3].y, o_param); }
public NyARIntCoordinates(int i_length) { this.items = NyARIntPoint2d.createArray(i_length); this.length = 0; }
/** * 2点を結ぶ直線の式を得る。この式は正規化されている。 * @param i_point1 * @param i_point2 * @return */ public bool makeLinearWithNormalize(NyARIntPoint2d i_point1, NyARIntPoint2d i_point2) { return(makeLinearWithNormalize(i_point1.x, i_point1.y, i_point2.x, i_point2.y)); }
/** * この関数は、マーカ四角形をインスタンスにセットします。 * @param i_vertex * セットする四角形頂点座標。4要素である必要があります。 * @return * 成功するとtrueです。 * @throws NyARException */ public bool setSourceSquare(NyARIntPoint2d[] i_vertex) { return this._param_gen.getParam(READ_RESOLUTION, READ_RESOLUTION, i_vertex, this._cparam); }
/** * この関数は、複数の座標点を、一括して理想座標系から観察座標系へ変換します。 * @param i_in * 変換元の座標配列 * @param o_out * 変換後の座標を受け取る配列 * @param i_size * 変換する座標の個数。 */ public void ideal2ObservBatch(NyARDoublePoint2d[] i_in, NyARIntPoint2d[] o_out, int i_size) { double x, y; double d0 = this._f0; double d1 = this._f1; double d3 = this._f3; double d2_w = this._f2 / 100000000.0; for (int i = 0; i < i_size; i++) { x = (i_in[i].x - d0) * d3; y = (i_in[i].y - d1) * d3; if (x == 0.0 && y == 0.0) { o_out[i].x = (int)d0; o_out[i].y = (int)d1; } else { double d = 1.0 - d2_w * (x * x + y * y); o_out[i].x = (int)(x * d + d0); o_out[i].y = (int)(y * d + d1); } } return; }
/** * この関数は、直線を矩形でクリッピングしたときの、端点を計算します。 * @param i_left * 矩形の左上座標(X) * @param i_top * 矩形の左上座標(Y) * @param i_width * 矩形の幅 * @param i_height * 矩形の高さ * @param o_point * 端点を返すオブジェクト配列。2要素である必要があります。 * @return * 端点が求まればtrue */ public bool makeSegmentLine(int i_left, int i_top, int i_width, int i_height, NyARIntPoint2d[] o_point) { int bottom = i_top + i_height; int right = i_left + i_width; int idx = 0; NyARIntPoint2d ptr = o_point[0]; if (this.crossPos(0, -1, i_top, ptr) && ptr.x >= i_left && ptr.x < right) { //y=rect.yの線 idx++; ptr = o_point[idx]; } if (this.crossPos(0, -1, bottom - 1, ptr) && ptr.x >= i_left && ptr.x < right) { //y=(rect.y+rect.h-1)の線 idx++; if (idx == 2) { return true; } ptr = o_point[idx]; } if (this.crossPos(-1, 0, i_left, ptr) && ptr.y >= i_top && ptr.y < bottom) { //x=i_leftの線 idx++; if (idx == 2) { return true; } ptr = o_point[idx]; } if (this.crossPos(-1, 0, right - 1, ptr) && ptr.y >= i_top && ptr.y < bottom) { //x=i_right-1の線 idx++; if (idx == 2) { return true; } } return false; }
/** * この関数は、座標点を理想座標系から観察座標系へ変換します。 */ public void ideal2Observ(NyARDoublePoint2d i_in, NyARIntPoint2d o_out) { this.ideal2Observ(i_in.x, i_in.y, o_out); return; }
/** * {@link #makeCenter}の出力型違いの関数です。 * @param i_points * @param i_number_of_data * @param o_out */ public static void makeCenter(NyARDoublePoint2d[] i_points, int i_number_of_data, NyARIntPoint2d o_out) { double lx, ly; lx = ly = 0; for (int i = i_number_of_data - 1; i >= 0; i--) { lx += i_points[i].x; ly += i_points[i].y; } o_out.x = (int)(lx / i_number_of_data); o_out.y = (int)(ly / i_number_of_data); }
/** * 点1と点2の間に線分を定義して、その線分上のベクトルを得ます。点は、画像の内側でなければなりません。 320*240の場合、(x>=0 && * x<320 x+w>0 && x+w<320),(y>0 && y<240 y+h>=0 && y+h<=319)となります。 * * @param i_pos1 * 点1の座標です。 * @param i_pos2 * 点2の座標です。 * @param i_area * ベクトルを検出するカーネルサイズです。1の場合(n*2-1)^2のカーネルになります。 点2の座標です。 * @param o_coord * 結果を受け取るオブジェクトです。 * @return * @throws NyARException */ public bool traceLine(NyARIntPoint2d i_pos1, NyARIntPoint2d i_pos2, int i_edge, VecLinearCoordinates o_coord) { NyARIntCoordinates coord = this._coord_buf; NyARIntSize base_s=this._ref_base_raster.getSize(); // (i_area*2)の矩形が範囲内に収まるように線を引く // 移動量 // 点間距離を計算 int dist = (int) Math.Sqrt(i_pos1.sqDist(i_pos2)); // 最低AREA*2以上の大きさが無いなら、ラインのトレースは不可能。 if (dist < 4) { return false; } // dist最大数の決定 if (dist > 12) { dist = 12; } // サンプリングサイズを決定(移動速度とサイズから) int s = i_edge * 2 + 1; int dx = (i_pos2.x - i_pos1.x); int dy = (i_pos2.y - i_pos1.y); int r = base_s.w - s; int b = base_s.h - s; // 最大14点を定義して、そのうち両端を除いた点を使用する。 for (int i = 1; i < dist - 1; i++) { int x = i * dx / dist + i_pos1.x - i_edge; int y = i * dy / dist + i_pos1.y - i_edge; // limit coord.items[i - 1].x = x < 0 ? 0 : (x >= r ? r : x); coord.items[i - 1].y = y < 0 ? 0 : (y >= b ? b : y); } coord.length = dist - 2; // 点数は20点程度を得る。 return traceConture(coord, 1, s, o_coord); }
public override bool getParam(NyARIntPoint2d[] i_vertex, double[] o_param) { double ltx = this._local_x; double lty = this._local_y; double rbx = ltx + this._width; double rby = lty + this._height; double det_1; double a13, a14, a23, a24, a33, a34, a43, a44; double b11, b12, b13, b14, b21, b22, b23, b24, b31, b32, b33, b34, b41, b42, b43, b44; double t1, t2, t3, t4, t5, t6; double v1, v2, v3, v4; double kx0, kx1, kx2, kx3, kx4, kx5, kx6, kx7; double ky0, ky1, ky2, ky3, ky4, ky5, ky6, ky7; { v1 = i_vertex[0].x; v2 = i_vertex[1].x; v3 = i_vertex[2].x; v4 = i_vertex[3].x; a13 = -ltx * v1; a14 = -lty * v1; a23 = -rbx * v2; a24 = -lty * v2; a33 = -rbx * v3; a34 = -rby * v3; a43 = -ltx * v4; a44 = -rby * v4; t1 = a33 * a44 - a34 * a43; t4 = a34 * ltx - rbx * a44; t5 = rbx * a43 - a33 * ltx; t2 = rby * (a34 - a44); t3 = rby * (a43 - a33); t6 = rby * (rbx - ltx); b21 = -a23 * t4 - a24 * t5 - rbx * t1; b11 = (a23 * t2 + a24 * t3) + lty * t1; b31 = (a24 * t6 - rbx * t2) + lty * t4; b41 = (-rbx * t3 - a23 * t6) + lty * t5; t1 = a43 * a14 - a44 * a13; t2 = a44 * lty - rby * a14; t3 = rby * a13 - a43 * lty; t4 = ltx * (a44 - a14); t5 = ltx * (a13 - a43); t6 = ltx * (lty - rby); b12 = -rby * t1 - a33 * t2 - a34 * t3; b22 = (a33 * t4 + a34 * t5) + rbx * t1; b32 = (-a34 * t6 - rby * t4) + rbx * t2; b42 = (-rby * t5 + a33 * t6) + rbx * t3; t1 = a13 * a24 - a14 * a23; t4 = a14 * rbx - ltx * a24; t5 = ltx * a23 - a13 * rbx; t2 = lty * (a14 - a24); t3 = lty * (a23 - a13); t6 = lty * (ltx - rbx); b23 = -a43 * t4 - a44 * t5 - ltx * t1; b13 = (a43 * t2 + a44 * t3) + rby * t1; b33 = (a44 * t6 - ltx * t2) + rby * t4; b43 = (-ltx * t3 - a43 * t6) + rby * t5; t1 = a23 * a34 - a24 * a33; t2 = a24 * rby - lty * a34; t3 = lty * a33 - a23 * rby; t4 = rbx * (a24 - a34); t5 = rbx * (a33 - a23); t6 = rbx * (rby - lty); b14 = -lty * t1 - a13 * t2 - a14 * t3; b24 = a13 * t4 + a14 * t5 + ltx * t1; b34 = -a14 * t6 - lty * t4 + ltx * t2; b44 = -lty * t5 + a13 * t6 + ltx * t3; det_1 = (ltx * (b11 + b14) + rbx * (b12 + b13)); if (det_1 == 0) { det_1 = 0.0001; //System.out.println("Could not get inverse matrix(1)."); //return false; } det_1 = 1 / det_1; kx0 = (b11 * v1 + b12 * v2 + b13 * v3 + b14 * v4) * det_1; kx1 = (b11 + b12 + b13 + b14) * det_1; kx2 = (b21 * v1 + b22 * v2 + b23 * v3 + b24 * v4) * det_1; kx3 = (b21 + b22 + b23 + b24) * det_1; kx4 = (b31 * v1 + b32 * v2 + b33 * v3 + b34 * v4) * det_1; kx5 = (b31 + b32 + b33 + b34) * det_1; kx6 = (b41 * v1 + b42 * v2 + b43 * v3 + b44 * v4) * det_1; kx7 = (b41 + b42 + b43 + b44) * det_1; } { v1 = i_vertex[0].y; v2 = i_vertex[1].y; v3 = i_vertex[2].y; v4 = i_vertex[3].y; a13 = -ltx * v1; a14 = -lty * v1; a23 = -rbx * v2; a24 = -lty * v2; a33 = -rbx * v3; a34 = -rby * v3; a43 = -ltx * v4; a44 = -rby * v4; t1 = a33 * a44 - a34 * a43; t4 = a34 * ltx - rbx * a44; t5 = rbx * a43 - a33 * ltx; t2 = rby * (a34 - a44); t3 = rby * (a43 - a33); t6 = rby * (rbx - ltx); b21 = -a23 * t4 - a24 * t5 - rbx * t1; b11 = (a23 * t2 + a24 * t3) + lty * t1; b31 = (a24 * t6 - rbx * t2) + lty * t4; b41 = (-rbx * t3 - a23 * t6) + lty * t5; t1 = a43 * a14 - a44 * a13; t2 = a44 * lty - rby * a14; t3 = rby * a13 - a43 * lty; t4 = ltx * (a44 - a14); t5 = ltx * (a13 - a43); t6 = ltx * (lty - rby); b12 = -rby * t1 - a33 * t2 - a34 * t3; b22 = (a33 * t4 + a34 * t5) + rbx * t1; b32 = (-a34 * t6 - rby * t4) + rbx * t2; b42 = (-rby * t5 + a33 * t6) + rbx * t3; t1 = a13 * a24 - a14 * a23; t4 = a14 * rbx - ltx * a24; t5 = ltx * a23 - a13 * rbx; t2 = lty * (a14 - a24); t3 = lty * (a23 - a13); t6 = lty * (ltx - rbx); b23 = -a43 * t4 - a44 * t5 - ltx * t1; b13 = (a43 * t2 + a44 * t3) + rby * t1; b33 = (a44 * t6 - ltx * t2) + rby * t4; b43 = (-ltx * t3 - a43 * t6) + rby * t5; t1 = a23 * a34 - a24 * a33; t2 = a24 * rby - lty * a34; t3 = lty * a33 - a23 * rby; t4 = rbx * (a24 - a34); t5 = rbx * (a33 - a23); t6 = rbx * (rby - lty); b14 = -lty * t1 - a13 * t2 - a14 * t3; b24 = a13 * t4 + a14 * t5 + ltx * t1; b34 = -a14 * t6 - lty * t4 + ltx * t2; b44 = -lty * t5 + a13 * t6 + ltx * t3; det_1 = (ltx * (b11 + b14) + rbx * (b12 + b13)); if (det_1 == 0) { det_1 = 0.0001; //System.out.println("Could not get inverse matrix(2)."); //return false; } det_1 = 1 / det_1; ky0 = (b11 * v1 + b12 * v2 + b13 * v3 + b14 * v4) * det_1; ky1 = (b11 + b12 + b13 + b14) * det_1; ky2 = (b21 * v1 + b22 * v2 + b23 * v3 + b24 * v4) * det_1; ky3 = (b21 + b22 + b23 + b24) * det_1; ky4 = (b31 * v1 + b32 * v2 + b33 * v3 + b34 * v4) * det_1; ky5 = (b31 + b32 + b33 + b34) * det_1; ky6 = (b41 * v1 + b42 * v2 + b43 * v3 + b44 * v4) * det_1; ky7 = (b41 + b42 + b43 + b44) * det_1; } det_1 = kx5 * (-ky7) - (-ky5) * kx7; if (det_1 == 0) { det_1 = 0.0001; //System.out.println("Could not get inverse matrix(3)."); //return false; } det_1 = 1 / det_1; double C, F; o_param[2] = C = (-ky7 * det_1) * (kx4 - ky4) + (ky5 * det_1) * (kx6 - ky6); // C o_param[5] = F = (-kx7 * det_1) * (kx4 - ky4) + (kx5 * det_1) * (kx6 - ky6); // F o_param[6] = kx4 - C * kx5; o_param[7] = kx6 - C * kx7; o_param[0] = kx0 - C * kx1; o_param[1] = kx2 - C * kx3; o_param[3] = ky0 - F * ky1; o_param[4] = ky2 - F * ky3; return true; }
/** * この関数は、遠近法のパラメータを計算して、返却します。 * @param i_size * 変換先の矩形のサイズを指定します。 * @param i_vertex * 変換元の頂点を指定します。要素数は4でなければなりません。 * @param o_param * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。 * @return * 成功するとtrueを返します。 * @ */ public bool getParam(NyARIntSize i_size, NyARIntPoint2d[] i_vertex, double[] o_param) { Debug.Assert(i_vertex.Length == 4); return this.getParam(i_size.w, i_size.h, i_vertex[0].x, i_vertex[0].y, i_vertex[1].x, i_vertex[1].y, i_vertex[2].x, i_vertex[2].y, i_vertex[3].x, i_vertex[3].y, o_param); }
/** * この関数は、2つの座標点配列同士の距離値を一括してマップにセットします。 * <p> * 実装メモ - * 点のフォーマットが合わない場合は、この関数参考にオーバーロードしてください。 * </p> * @param i_vertex_r * 比較する頂点群を格納した配列。 * @param i_row_len * i_vertex_rの有効な要素数 * @param i_vertex_c * 基準となる頂点群を格納した配列 * @param i_col_len * i_vertex_cの有効な要素数 */ public void setPointDists(NyARIntPoint2d[] i_vertex_r, int i_row_len, NyARIntPoint2d[] i_vertex_c, int i_col_len) { DistItem[] map = this._map; //distortionMapを作成。ついでに最小値のインデクスも取得 int min_index = 0; int min_dist = int.MaxValue; int idx = 0; for (int r = 0; r < i_row_len; r++) { for (int c = 0; c < i_col_len; c++) { map[idx].col = c; map[idx].row = r; int d = i_vertex_r[r].sqDist(i_vertex_c[c]); map[idx].dist = d; if (min_dist > d) { min_index = idx; min_dist = d; } idx++; } } this._min_dist = min_dist; this._min_dist_index = min_index; this._size_col = i_col_len; this._size_row = i_row_len; return; }
/** * この関数は、ラスタのi_vertexsで定義される四角形からパターンを取得して、インスタンスに格納します。 */ public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs) { if (this._last_input_raster != image) { this._raster_driver = (INyARPerspectiveCopy)image.createInterface(typeof(INyARPerspectiveCopy)); this._last_input_raster = image; } //遠近法のパラメータを計算 return this._raster_driver.copyPatt(i_vertexs, this._edge.x, this._edge.y, this._sample_per_pixel, this); }
/** * i_imageから、idマーカを読みだします。 * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。 * @param image * @param i_square * @param o_data * @param o_param * @return * @throws NyARException */ public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertex, NyIdMarkerPattern o_data, NyIdMarkerParam o_param) { //遠近法のパラメータを計算 if (!this._perspective_reader.setSourceSquare(i_vertex)) { return false; }; INyARRgbPixelReader reader = image.getRgbPixelReader(); NyARIntSize raster_size = image.getSize(); PerspectivePixelReader.TThreshold th = this.__pickFromRaster_th; MarkerPattEncoder encoder = this.__pickFromRaster_encoder; //マーカパラメータを取得 this._perspective_reader.detectThresholdValue(reader, raster_size, th); if (!this._perspective_reader.readDataBits(reader, raster_size,th, encoder)) { return false; } int d = encoder.encode(o_data); if (d < 0) { return false; } o_param.direction = d; o_param.threshold = th.th; return true; }
/** * i_srcの値をthisへセットします。 * @param i_src */ public NyARDoublePoint2d(NyARIntPoint2d i_src) { this.x = (double)i_src.x; this.y = (double)i_src.y; return; }
/** * この関数は、座標点を理想座標系から観察座標系へ変換します。 * @param i_in * 変換元の座標 * @param o_out * 変換後の座標を受け取るオブジェクト */ public void ideal2Observ(NyARDoublePoint2d i_in, NyARIntPoint2d o_out) { this.ideal2Observ(i_in.x, i_in.y, o_out); return; }
/** * i_srcの値をthisへセットします。 * @param i_src */ public void setValue(NyARIntPoint2d i_src) { this.x = (double)i_src.x; this.y = (double)i_src.y; return; }
/** * この関数は、座標点を理想座標系から観察座標系へ変換します。 * @param i_x * 変換元の座標 * @param i_y * 変換元の座標 * @param o_out * 変換後の座標を受け取るオブジェクト */ public void ideal2Observ(double i_x, double i_y, NyARIntPoint2d o_out) { double x = (i_x - this._f0) * this._f3; double y = (i_y - this._f1) * this._f3; if (x == 0.0 && y == 0.0) { o_out.x = (int)(this._f0); o_out.y = (int)(this._f1); } else { double d = 1.0 - this._f2 / 100000000.0 * (x * x + y * y); o_out.x = (int)(x * d + this._f0); o_out.y = (int)(y * d + this._f1); } return; }