public void finish() { //一致率の最も高いアイテムを得る。 ARMarkerSortList.Item top_item = this._mkmap.getTopItem(); //アイテムを検出できなくなるまで、一致率が高い順にアイテムを得る。 while (top_item != null) { //検出したアイテムのARmarkerIndexのデータをセット ARMarkerList.Item target = top_item.marker; if (target.lost_count > 0) { //未割当のマーカのみ検出操作を実行。 target.cf = top_item.cf; target.lost_count = 0; //消失カウンタをリセット target.life++; //ライフ値を加算 target.sq = top_item.ref_sq; target.sq.rotateVertexL(4 - top_item.dir); NyARIntPoint2d.shiftCopy(top_item.ref_sq.ob_vertex, target.tl_vertex, 4 - top_item.dir); target.tl_center.setValue(top_item.ref_sq.center2d); target.tl_rect_area = top_item.ref_sq.rect_area; } //基準アイテムと重複するアイテムを削除する。 this._mkmap.disableMatchItem(top_item); top_item = this._mkmap.getTopItem(); } //消失カウンタが敷居値を越えたら、lifeを0にする。 }
public void finish() { //一致率の最も高いアイテムを得る。 VertexSortTable.Item top_item = this._tracking_list.getTopItem(); //アイテムを検出できなくなるまで、一致率が高い順にアイテムを得る。 while (top_item != null) { //検出したアイテムのARmarkerIndexのデータをセット TMarkerData target = top_item.marker; //検出カウンタが1以上(未検出の場合のみ検出) if (target.lost_count > 0) { target.lost_count = 0; target.life++; target.sq = top_item.ref_sq; target.sq.rotateVertexL(4 - top_item.shift); NyARIntPoint2d.shiftCopy(top_item.ref_sq.ob_vertex, target.tl_vertex, 4 - top_item.shift); target.tl_center.setValue(top_item.ref_sq.center2d); target.tl_rect_area = top_item.ref_sq.rect_area; } //基準アイテムと重複するアイテムを削除する。 this._tracking_list.disableMatchItem(top_item); top_item = this._tracking_list.getTopItem(); } }
/** * この関数は、インスタンスの座標と、指定点との距離の2乗値を返します。 * @param i_p1 * 点の座標 * @return * i_p1との距離の二乗値 */ 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); }
private void ShowMarkerLayoutDir(MarkerInfo oMarkerInfo) { NyARIntPoint2d oCenterPoint = oMarkerInfo.Center; string sDir = "方向: 未检测出"; TextBlock oTbkDir = this.GetVertexPointLabel(); Canvas.SetLeft(oTbkDir, oCenterPoint.x - 30); Canvas.SetTop(oTbkDir, oCenterPoint.y - 60); if (oMarkerInfo.CurLayoutDir == LayoutDirType.ldtUp) { sDir = "方向: 上"; } else if (oMarkerInfo.CurLayoutDir == LayoutDirType.ldtLeft) { sDir = "方向: 左"; } else if (oMarkerInfo.CurLayoutDir == LayoutDirType.ldtRight) { sDir = "方向: 右"; } else if (oMarkerInfo.CurLayoutDir == LayoutDirType.ldtDown) { sDir = "方向: 下"; } oTbkDir.Text = sDir; this.CvMainZm.Children.Add(oTbkDir); }
/** * この関数は、ラスタのi_vertexsで定義される四角形からパターンを取得して、インスタンスに格納します。 */ public override bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs) { NyARMat cpara = this.wk_pickFromRaster_cpara; // xdiv2,ydiv2の計算 int xdiv2, ydiv2; int l1, l2; int w1, w2; // x計算 w1 = i_vertexs[0].x - i_vertexs[1].x; w2 = i_vertexs[0].y - i_vertexs[1].y; l1 = (w1 * w1 + w2 * w2); w1 = i_vertexs[2].x - i_vertexs[3].x; w2 = i_vertexs[2].y - i_vertexs[3].y; l2 = (w1 * w1 + w2 * w2); if (l2 > l1) { l1 = l2; } l1 = l1 / 4; xdiv2 = this._size.w; while (xdiv2 * xdiv2 < l1) { xdiv2 *= 2; } if (xdiv2 > AR_PATT_SAMPLE_NUM) { xdiv2 = AR_PATT_SAMPLE_NUM; } // y計算 w1 = i_vertexs[1].x - i_vertexs[2].x; w2 = i_vertexs[1].y - i_vertexs[2].y; l1 = (w1 * w1 + w2 * w2); w1 = i_vertexs[3].x - i_vertexs[0].x; w2 = i_vertexs[3].y - i_vertexs[0].y; l2 = (w1 * w1 + w2 * w2); if (l2 > l1) { l1 = l2; } ydiv2 = this._size.h; l1 = l1 / 4; while (ydiv2 * ydiv2 < l1) { ydiv2 *= 2; } if (ydiv2 > AR_PATT_SAMPLE_NUM) { ydiv2 = AR_PATT_SAMPLE_NUM; } // cparaの計算 if (!get_cpara(i_vertexs, cpara)) { return false; } updateExtpat(image, cpara, xdiv2, ydiv2); return true; }
public void Update(NyARIntPoint2d[] oPoints, NyARIntPoint2d oCenterPoint, double dConfidence) { this.Vertex = oPoints; this.Center = oCenterPoint; this.Confidence = dConfidence; this.CalcDir(); this.CalcDegree(); }
/** * この関数は、インスタンスの座標と、指定点との距離の2乗値を返します。 * @param i_p1 * 点の座標 * @return * i_p1との距離の二乗値 */ 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); }
/** * この関数は、観察座標を理想座標へ変換します。 * 入力できる値範囲は、コンストラクタに設定したスクリーンサイズの範囲内です。 * @param ix * 観察座標の値 * @param iy * 観察座標の値 * @param o_point * 理想座標を受け取るオブジェクト。 */ 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_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; }
/** * この関数は、配列の値をコピーします。 * 配列の長さは、同じである必要があります。 * @param i_from * コピー元の配列 * @param i_to * コピー先の配列 */ 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 MarkerInfo(int nMarkerID, NyARIntPoint2d[] oPoints, NyARIntPoint2d oCenterPoint, double dConfidence) { this.MarkerID = nMarkerID; this.Vertex = oPoints; this.Center = oCenterPoint; this.Confidence = dConfidence; this.CalcDir(); this.CalcDegree(); }
public static void shiftCopy(NyARDoublePoint2d[] i_src, NyARIntPoint2d[] i_dst, int i_shift) { int l = i_src.Length; for (int i = l - 1; i >= 0; i--) { int n = (i + i_shift) % l; i_dst[i].x = (int)i_src[n].x; i_dst[i].y = (int)i_src[n].y; } }
/// <summary> /// Initialize a new SquareDetectionListener. /// </summary> /// <param name="patternMatchers">The pattern matchers with the marker data.</param> /// <param name="cameraParameters">The camera calibration data.</param> /// <param name="colorPattern">The used color pattern.</param> /// <param name="patternMatchDeviationData">The pattern match deviation data.</param> public SquareDetectionListener(List <PatternMatcher> patternMatchers, NyARParam cameraParameters, INyARColorPatt colorPattern, NyARMatchPattDeviationColorData patternMatchDeviationData) { this.patternMatchers = patternMatchers; this.colorPattern = colorPattern; this.patternMatchDeviationData = patternMatchDeviationData; this.coordinationMapper = new Coord2Linear(cameraParameters.getScreenSize(), cameraParameters.getDistortionFactor()); this.matrixCalculator = new NyARTransMat(cameraParameters); this.points = NyARIntPoint2d.createArray(4); this.evaluationResult = new NyARMatchPattResult(); Reset(); }
private void ShowMarkerRotate(MarkerInfo oMarkerInfo) { NyARIntPoint2d oCenterPoint = oMarkerInfo.Center; TextBlock oTbkRotate = this.GetVertexPointLabel(); Canvas.SetLeft(oTbkRotate, oCenterPoint.x - 60); Canvas.SetTop(oTbkRotate, oCenterPoint.y + 20); oTbkRotate.Text = "旋转: " + Math.Round(oMarkerInfo.Rotate, 3); this.CvMainZm.Children.Add(oTbkRotate); }
private void ShowMarkerCenter(MarkerInfo oMarkerInfo) { NyARIntPoint2d oCenterPoint = oMarkerInfo.Center; Ellipse oEllipse = new Ellipse() { Width = 5, Height = 5, Fill = new SolidColorBrush(Colors.Green), }; Canvas.SetLeft(oEllipse, oCenterPoint.x); Canvas.SetTop(oEllipse, oCenterPoint.y); this.CvMainZm.Children.Add(oEllipse); }
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)); }
/** * この関数は、座標点を理想座標系から観察座標系へ変換します。 * 範囲外の場合、境界の値を返します。 * @param i_x * 変換元の座標 * @param i_y * 変換元の座標 * @param o_out * 変換後の座標を受け取るオブジェクト */ public override void ideal2Observ(double i_x, double i_y, NyARIntPoint2d o_out) { int px = (int)(i_x + 0.5) + this._xOff; int py = (int)(i_y + 0.5) + this._yOff; if (px < 0 || px >= this._xsize || py < 0 || py >= this._ysize) { this._base_factor.ideal2Observ(i_x, i_y, o_out); return; } int lt = (py * this._xsize + px) * 2; o_out.x = (int)this._i2o[lt + 0]; o_out.y = (int)this._i2o[lt + 1]; return; }
/** * @param world * @param vertex * @param o_para * @ */ private bool get_cpara(NyARIntPoint2d[] i_vertex, NyARMat o_para) { double[][] world = CPARAM_WORLD; NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 ); double[][] a_array = a.getArray(); NyARMat b = wk_get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 ); double[][] b_array = b.getArray(); double[] a_pt0, a_pt1; double[] world_pti; for (int i = 0; i < 4; i++) { a_pt0 = a_array[i * 2]; a_pt1 = a_array[i * 2 + 1]; world_pti = world[i]; a_pt0[0] = (double)world_pti[0];// a->m[i*16+0] = world[i][0]; a_pt0[1] = (double)world_pti[1];// a->m[i*16+1] = world[i][1]; a_pt0[2] = 1.0;// a->m[i*16+2] = 1.0; a_pt0[3] = 0.0;// a->m[i*16+3] = 0.0; a_pt0[4] = 0.0;// a->m[i*16+4] = 0.0; a_pt0[5] = 0.0;// a->m[i*16+5] = 0.0; a_pt0[6] = (double)(-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0]; a_pt0[7] = (double)(-world_pti[1] * i_vertex[i].x);// a->m[i*16+7]=-world[i][1]*vertex[i][0]; a_pt1[0] = 0.0;// a->m[i*16+8] = 0.0; a_pt1[1] = 0.0;// a->m[i*16+9] = 0.0; a_pt1[2] = 0.0;// a->m[i*16+10] = 0.0; a_pt1[3] = (double)world_pti[0];// a->m[i*16+11] = world[i][0]; a_pt1[4] = (double)world_pti[1];// a->m[i*16+12] = world[i][1]; a_pt1[5] = 1.0;// a->m[i*16+13] = 1.0; a_pt1[6] = (double)(-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1]; a_pt1[7] = (double)(-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1]; b_array[i * 2 + 0][0] = (double)i_vertex[i].x;// b->m[i*2+0] =vertex[i][0]; b_array[i * 2 + 1][0] = (double)i_vertex[i].y;// b->m[i*2+1] =vertex[i][1]; } if (!a.inverse()) { return false; } o_para.mul(a, b); return true; }
override 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); return; }
private void DrawARDetectInfo(int nMarkerID, string sMarkerName) { double dConfidence = Math.Round(this.ARMarkerSystem.getConfidence(nMarkerID), 5); NyARIntPoint2d oCenterPoint = this.ARMarkerSystem.getCenter(nMarkerID); NyARIntPoint2d[] oPoints = this.ARMarkerSystem.getVertex2D(nMarkerID); if (MarkerInfos.Contains(nMarkerID)) { MarkerInfo oMarkerInfo = this.MarkerInfos[nMarkerID] as MarkerInfo; oMarkerInfo.Update(oPoints, oCenterPoint, dConfidence); this.ShowMarkerInfo(oMarkerInfo); } else { MarkerInfo oMarkerInfo = new MarkerInfo(nMarkerID, oPoints, oCenterPoint, dConfidence); this.MarkerInfos.Add(nMarkerID, oMarkerInfo); this.ShowMarkerInfo(oMarkerInfo); } }
/** * 点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 void finish() { for (int i = this.Count - 1; i >= 0; i--) { Item target = this[i]; if (target.sq == null) { continue; } if (target.lost_count > 0) { //参照はそのままで、dirだけ調整する。 target.lost_count = 0; target.life++; target.sq.rotateVertexL(4 - target.dir); NyARIntPoint2d.shiftCopy(target.sq.ob_vertex, target.tl_vertex, 4 - target.dir); target.tl_center.setValue(target.sq.center2d); target.tl_rect_area = target.sq.rect_area; } } }
/** * この関数は、頂点集合から、中央値(Σp[n]/n)を求めます。 * @param i_points * 頂点集合を格納した配列です。 * @param i_number_of_data * 配列中の有効な頂点数です。 * @param o_out * 中央値を受け取るオブジェクトです。 * @deprecated * {@link #setCenterPos(NyARIntPoint2d[], int)を使用してください。 */ public static void makeCenter(NyARIntPoint2d[] i_points, int i_number_of_data, NyARIntPoint2d o_out) { o_out.setCenterPos(i_points, i_number_of_data); }
/** * 点が、サイズの内部にあるか判定します。 * @param i_x * @param i_y * @return */ public bool isInnerPoint(NyARIntPoint2d i_pos) { return(i_pos.x < this.w && i_pos.y < this.h && 0 <= i_pos.x && 0 <= i_pos.y); }
/** * この関数は、オブジェクトからインスタンスに値をセットします。 * @param i_src * コピー元のオブジェクト。 */ public void setValue(NyARIntPoint2d i_src) { this.x = (double)i_src.x; this.y = (double)i_src.y; return; }
/** * この関数は、頂点集合から、中央値(Σp[n]/n)を求めます。 * @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); }
/** * コンストラクタです。 * i_srcの値で初期化したインスタンスを生成します。 * @param i_src * 初期値とするオブジェクト */ public NyARDoublePoint2d(NyARIntPoint2d i_src) { this.x = (double)i_src.x; this.y = (double)i_src.y; return; }
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_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。 * @param i_xcoord * @param i_ycoord * @param i_coord_num * @return */ private static int getFarPoint(NyARIntPoint2d[] i_coord, int i_coord_num, int i_point) { // int sx = i_coord[i_point].x; int sy = i_coord[i_point].y; int d = 0; int w, x, y; int ret = 0; for (int i = i_point + 1; i < i_coord_num; i++) { x = i_coord[i].x - sx; y = i_coord[i].y - sy; w = x * x + y * y; if (w > d) { d = w; ret = i; } } for (int i = 0; i < i_point; i++) { x = i_coord[i].x - sx; y = i_coord[i].y - sy; w = x * x + y * y; if (w > d) { d = w; ret = i; } } return ret; }
/** * この関数は、一括して観察座標を理想座標へ変換します。 * 入力できる値範囲は、コンストラクタに設定したスクリーンサイズの範囲内です。 * @param i_coord * 観察座標の配列 * @param i_start * 変換対象にする配列の開始インデクス。 * @param i_num * 変換対象にする要素の数。 * i_startから、i_start+i_num-1までの要素を変換します。 * @param o_x_coord * 変換したX座標を受け取る配列。 * @param o_y_coord * 変換したY座標を受け取る配列。 * @param i_out_start_index * 出力先配列の開始インデクス。指定した位置から先に結果を返します。 */ public void observ2IdealBatch(NyARIntPoint2d[] i_coord, int i_start, int i_num, double[] o_x_coord, double[] o_y_coord, int i_out_start_index) { int idx; int ptr = i_out_start_index; double[] mapx = this._mapx; double[] mapy = this._mapy; int stride = this._stride; for (int j = 0; j < i_num; j++) { idx = i_coord[i_start + j].x + i_coord[i_start + j].y * stride; o_x_coord[ptr] = mapx[idx]; o_y_coord[ptr] = mapy[idx]; ptr++; } return; }
/** * {@link #getTargetCenter}の出力型違いの関数です。 * @param o_center */ public void getTargetCenter(NyARIntPoint2d o_center) { Debug.Assert(this._target_type == RT_UNKNOWN || this._target_type == RT_KNOWN); NyARDoublePoint2d.makeCenter(((NyARRectTargetStatus)(this._ref_tracktarget._ref_status)).vertex,4,o_center); }
/** * この関数は、座標がサイズの範囲内(0,0-w,hの矩形)にあるかを返します。 * @param i_pos * 調査する座標点 * @return * 引数値が範囲内ならば、trueを返します。 * @ */ public bool isInnerPoint(NyARIntPoint2d i_pos) { return (i_pos.x < this.w && i_pos.y < this.h && 0 <= i_pos.x && 0 <= i_pos.y); }
public bool getVertex(NyARIntPoint2d[] i_coord, int i_coord_len, int st, int ed, double i_thresh) { this.number_of_vertex = 0; this.thresh = i_thresh; this._coord = i_coord; return get_vertex(st, ed, i_coord_len); }
private void DrawARDetectInfo(int nMarkerID, string sMarkerName) { //double dConfidence = Math.Round(this.ARMarkerSystem.getConfidence(nMarkerID), 5); double dConfidence = this.ARMarkerSystem.getConfidence(nMarkerID); NyARIntPoint2d oCenterPoint = this.ARMarkerSystem.getCenter(nMarkerID); NyARIntPoint2d[] oPoints = this.ARMarkerSystem.getVertex2D(nMarkerID); Polygon oPolygon = new Polygon() { SnapsToDevicePixels = true, Opacity = 0.8, Stroke = new SolidColorBrush(Colors.Green) }; if (nMarkerID == this.MarkerID_VTT) { oPolygon.Fill = new SolidColorBrush(Colors.Violet); } else if (nMarkerID == this.MarkerID_Hiro) { oPolygon.Fill = new SolidColorBrush(Colors.Aqua); } else if (nMarkerID == this.MarkerID_KanJi) { oPolygon.Fill = new SolidColorBrush(Colors.DarkKhaki); } oPolygon.Points = new PointCollection(new Point[] { new Point(oPoints[0].x, oPoints[0].y), new Point(oPoints[1].x, oPoints[1].y), new Point(oPoints[2].x, oPoints[2].y), new Point(oPoints[3].x, oPoints[3].y) }); this.CalcRotateDegree(oPoints); this.TbkPoint1Zm.Text = oPoints[0].x + " " + oPoints[0].y; this.TbkPoint2Zm.Text = oPoints[1].x + " " + oPoints[1].y; this.TbkPoint3Zm.Text = oPoints[2].x + " " + oPoints[2].y; this.TbkPoint4Zm.Text = oPoints[3].x + " " + oPoints[3].y; Ellipse oEllipse = new Ellipse() { Width = 5, Height = 5, Fill = new SolidColorBrush(Colors.Green), }; Canvas.SetLeft(oEllipse, oCenterPoint.x); Canvas.SetTop(oEllipse, oCenterPoint.y); this.CvMainZm.Children.Add(oPolygon); this.CvMainZm.Children.Add(oEllipse); string sResult = "识别结果: " + sMarkerName + " 匹配度:" + dConfidence; this.ShowARDetectInfo(sResult); this.CalcVertex(oPoints); }
/** * この関数は、オブジェクトからインスタンスに値をセットします。 * @param i_source * コピー元のオブジェクト。 */ public void setValue(NyARIntPoint2d i_source) { this.x = i_source.x; this.y = i_source.y; }
/** * この関数は、インスタンスの座標と、指定点との距離の2乗値を返します。 * @param i_p1 * 点の座標 * @return * i_p1との距離の二乗値 */ 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; }
/** * この関数は、座標点を理想座標系から観察座標系へ変換します。 * @param i_x * 変換元の座標 * @param i_y * 変換元の座標 * @param o_out * 変換後の座標を受け取るオブジェクト */ override public void ideal2Observ(double i_x, double i_y, NyARIntPoint2d o_out) { this._base_factor.ideal2Observ(i_x, i_y, o_out); }
/** * コンストラクタです。 * 最大長さを指定して、有効要素数0のインスタンスを作ります。 * @param i_length * 輪郭の最大長 */ public NyARIntCoordinates(int i_length) { this.items = NyARIntPoint2d.createArray(i_length); this.length = 0; }
/** * 指定した場所のピクセル値を調査して、閾値を計算して返します。 * @param i_reader * @param i_x * @param i_y * @return * @throws NyARException */ public void detectThresholdValue(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, TThreshold o_threshold) { int[] th_pixels = this._th_pixels; //左上のピックアップ領域からピクセルを得る(00-24) rectPixels(i_reader, i_raster_size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, 0, th_pixels); //左下のピックアップ領域からピクセルを得る(25-49) rectPixels(i_reader, i_raster_size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE, th_pixels); //右上のピックアップ領域からピクセルを得る(50-74) rectPixels(i_reader, i_raster_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, i_raster_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; }
/** * この関数は、インスタンスの座標と、指定点との距離の2乗値を返します。 * @param i_p1 * 点の座標 * @return * i_p1との距離の二乗値 */ 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; }
/** * この関数は、頂点集合から、中央値(Σp[n]/n)を求めて、インスタンスにセットします。 * @param i_point * 頂点集合を格納した配列です。 * @param i_number_of_vertex * 配列中の有効な頂点数です。 */ public void setCenterPos(NyARIntPoint2d[] i_point, int i_number_of_vertex) { int cx, cy; cx = cy = 0; for (int i = i_number_of_vertex - 1; i >= 0; i--) { cx += i_point[i].x; cy += i_point[i].y; } this.x = cx / i_number_of_vertex; this.y = cy / i_number_of_vertex; }
/** * この関数は、頂点集合を包括する矩形のサイズ値(幅、高さ)を計算して、インスタンスにセットします。 * @param i_vertex * 頂点集合を格納した配列 * @param i_num_of_vertex * 計算対象とする要素の数 */ public void setAreaRect(NyARIntPoint2d[] i_vertex, int i_num_of_vertex) { //エリアを求める。 int xmax, xmin, ymax, ymin; xmin = xmax = (int)i_vertex[i_num_of_vertex - 1].x; ymin = ymax = (int)i_vertex[i_num_of_vertex - 1].y; for (int i = i_num_of_vertex - 2; i >= 0; i--) { if (i_vertex[i].x < xmin) { xmin = (int)i_vertex[i].x; } else if (i_vertex[i].x > xmax) { xmax = (int)i_vertex[i].x; } if (i_vertex[i].y < ymin) { ymin = (int)i_vertex[i].y; } else if (i_vertex[i].y > ymax) { ymax = (int)i_vertex[i].y; } } this.h = ymax - ymin + 1; this.w = xmax - xmin + 1; }
public bool copyPatt(NyARIntPoint2d[] i_vertex, int i_edge_x, int i_edge_y, int i_resolution, INyARRgbRaster i_out) { return this.copyPatt(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, i_edge_x, i_edge_y, i_resolution, i_out); }