public override bool labeling(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th) { //配列初期化 this.label_stack.clear(); //ラベルの検出 bool ret = base.labeling(i_raster, i_area, i_th); //ソート this.label_stack.sortByArea(); return ret; }
/** * この関数は、ラスタの指定点を基点に、画像の特定の範囲内から輪郭線を抽出します。 * 開始点は、輪郭の一部である必要があります。 * 通常は、ラべリングの結果の上辺クリップとX軸エントリポイントを開始点として入力します。 * @param i_raster * 輪郭線を抽出するラスタを指定します。 * @param i_area * 輪郭線の抽出範囲を指定する矩形。i_rasterのサイズ内である必要があります。 * @param i_th * 輪郭とみなす暗点の敷居値を指定します。 * @param i_entry_x * 輪郭抽出の開始点です。 * @param i_entry_y * 輪郭抽出の開始点です。 * @param o_coord * 輪郭点を格納するオブジェクトを指定します。 * @return * 輪郭線がo_coordの長さを超えた場合、falseを返します。 * @ */ public bool getContour(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th, int i_entry_x, int i_entry_y, NyARIntCoordinates o_coord) { //ラスタドライバの切り替え if (i_raster != this._ref_last_input_raster) { this._imdriver = (IRasterDriver)i_raster.createInterface(typeof(IRasterDriver)); this._ref_last_input_raster = i_raster; } return(this._imdriver.getContour(i_area.x, i_area.y, i_area.x + i_area.w - 1, i_area.h + i_area.y - 1, i_entry_x, i_entry_y, i_th, o_coord)); }
/** * この関数は、引数の矩形が、この矩形内にあるか判定します。 * @param i_rect * 内側にあるか調べる矩形 * @return * 矩形が内側にあれば、trueを返します。 */ public bool isInnerRect(NyARIntRect i_rect) { Debug.Assert(i_rect.w >= 0 && i_rect.h >= 0); int lx = i_rect.x - this.x; int ly = i_rect.y - this.y; int lw = lx + i_rect.w; int lh = ly + i_rect.h; return(0 <= lx && lx < this.w && 0 <= ly && ly < this.h && lw <= this.w && lh <= this.h); }
public override bool labeling(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th) { //配列初期化 this.label_stack.clear(); //ラベルの検出 bool ret = base.labeling(i_raster, i_area, i_th); //ソート this.label_stack.sortByArea(); return(ret); }
/** * この関数は、2つの矩形の対角点同士の距離の二乗値を計算します。 * @param i_rect2 * 比較する矩形 * @return * 左上、右下の点同士の距離の二乗値 */ public int sqDiagonalPointDiff(NyARIntRect i_rect2) { int w1, w2; int ret; w1 = this.x - i_rect2.x; w2 = this.y - i_rect2.y; ret = w1 * w1 + w2 * w2; w1 += this.w - i_rect2.w; w2 += this.h - i_rect2.h; ret += w1 * w1 + w2 * w2; return(ret); }
public void analyzeRaster(INyARRaster i_input, NyARIntRect i_area, NyARHistogram o_histogram) { NyARIntSize size = i_input.getSize(); //最大画像サイズの制限 Debug.Assert(size.w * size.h < 0x40000000); Debug.Assert(o_histogram.length == 256);//現在は固定 int[] h = o_histogram.data; //ヒストグラム初期化 for (int i = o_histogram.length - 1; i >= 0; i--) { h[i] = 0; } o_histogram.total_of_data = i_area.w * i_area.h / this._vertical_skip; this._histImpl.createHistogram(i_input, i_area.x, i_area.y, i_area.w, i_area.h, o_histogram.data, this._vertical_skip); return; }
/** * この関数は、引数の矩形が、この矩形内にあるか判定します。 * @param i_rect * 内側にあるか調べる矩形 * @return * 矩形が内側にあれば、trueを返します。 */ public bool isInnerRect(NyARIntRect i_rect) { Debug.Assert(i_rect.w >= 0 && i_rect.h >= 0); int lx = i_rect.x - this.x; int ly = i_rect.y - this.y; int lw = lx + i_rect.w; int lh = ly + i_rect.h; return (0 <= lx && lx < this.w && 0 <= ly && ly < this.h && lw <= this.w && lh <= this.h); }
public int analyzeRaster(INyARRaster i_input, NyARIntRect i_area) { throw new NyARException(); }
/** * このデータが初期チェック(CoordからRectへの遷移)をパスするかチェックします。 * 条件は、 * 1.検出四角形の対角点は元の検出矩形内か? * 2.一番長い辺と短い辺の比は、0.1~10の範囲か? * 3.位置倍長い辺、短い辺が短すぎないか? * @param i_sample_area * この矩形を検出するために使った元データの範囲(ターゲット検出範囲) */ private bool checkInitialRectCondition(NyARIntRect i_sample_area) { NyARDoublePoint2d[] this_vx=this.vertex; //検出した四角形の対角点が検出エリア内か? int cx=(int)(this_vx[0].x+this_vx[1].x+this_vx[2].x+this_vx[3].x)/4; int cy=(int)(this_vx[0].y+this_vx[1].y+this_vx[2].y+this_vx[3].y)/4; if(!i_sample_area.isInnerPoint(cx,cy)){ return false; } //一番長い辺と短い辺の比を確認(10倍の比があったらなんか変) int max = int.MinValue; int min = int.MaxValue; for(int i=0;i<4;i++){ int t=(int)this_vx[i].sqDist(this_vx[(i+1)%4]); if(t>max){max=t;} if(t<min){min=t;} } //比率係数の確認 if(max<(5*5) ||min<(5*5)){ return false; } //10倍スケールの2乗 if((10*10)*min/max<(3*3)){ return false; } return true; }
/** * 輪郭情報を元に矩形パラメータを推定し、値をセットします。 * この関数は、処理の成功失敗に関わらず、内容変更を行います。 * @param i_contour_status * 関数を実行すると、このオブジェクトの内容は破壊されます。 * @return * @throws NyARException */ public bool setValueWithInitialCheck(NyARContourTargetStatus i_contour_status, NyARIntRect i_sample_area) { //ベクトルのマージ(マージするときに、3,4象限方向のベクトルは1,2象限のベクトルに変換する。) i_contour_status.vecpos.limitQuadrantTo12(); this._ref_my_pool._vecpos_op.margeResembleCoords(i_contour_status.vecpos); if(i_contour_status.vecpos.length<4){ return false; } //キーベクトルを取得 i_contour_status.vecpos.getKeyCoord(this._ref_my_pool._indexbuf); //点に変換 NyARDoublePoint2d[] this_vx=this.vertex; if(!this._ref_my_pool._line_detect.line2SquareVertex(this._ref_my_pool._indexbuf,this_vx)){ return false; } // //点から直線を再計算 // for(int i=3;i>=0;i--){ // this_sq.line[i].makeLinearWithNormalize(this_sq.sqvertex[i],this_sq.sqvertex[(i+1)%4]); // } this.setEstimateParam(null); if(!checkInitialRectCondition(i_sample_area)) { return false; } this.detect_type=DT_SQINIT; return true; }
/** * 同一サイズのラスタi_inputとi_outputの間で、一部の領域だけにラスタ処理を実行します。 * @param i_input * @param i_rect * @param i_output * @throws NyARException */ public void doFilter(INyARRgbRaster i_input, NyARIntRect i_rect, NyARGrayscaleRaster i_output) { Debug.Assert(i_input.getSize().isEqualSize(i_output.getSize()) == true); this._do_filter_impl.doFilter(i_input, (int[])i_output.getBuffer(), i_rect.x, i_rect.y, i_rect.w, i_rect.h); }
/** * この関数は、ラスタから矩形を検出して、自己コールバック関数{@link #onSquareDetect}で通知します。 * @param i_raster * 検出元のラスタ画像 * 入力できるラスタの画素形式は、{@link NyARLabeling_Rle#labeling(INyARRaster, int)}と同じです。 * @param i_area * 検出する範囲。検出元のラスタの内側である必要があります。 * @param i_th * ラベルと判定する敷居値 * @ */ public void detectMarker(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th, NyARSquareContourDetector.CbHandler i_cb) { Debug.Assert(i_area.w * i_area.h > 0); NyARRleLabelFragmentInfoPtrStack flagment = this._labeling.label_stack; NyARLabelOverlapChecker<NyARRleLabelFragmentInfo> overlap = this._overlap_checker; //ラベルの生成エラーならここまで if (!this._labeling.labeling(i_raster, i_area, i_th)) { return; } // ラベル数が0ならここまで int label_num = flagment.getLength(); if (label_num < 1) { return; } //ラベルリストを取得 NyARRleLabelFragmentInfo[] labels = flagment.getArray(); NyARIntCoordinates coord = this._coord; int[] mkvertex = this.__detectMarker_mkvertex; //重なりチェッカの最大数を設定 overlap.setMaxLabels(label_num); for (int i = 0; i < label_num; i++) { NyARRleLabelFragmentInfo label_pt = labels[i]; // 既に検出された矩形との重なりを確認 if (!overlap.check(label_pt)) { // 重なっているようだ。 continue; } //輪郭を取得 if (!this._cpickup.getContour(i_raster, i_area, i_th, label_pt.entry_x, label_pt.clip_t, coord)) { continue; } int label_area = label_pt.area; //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得 if (!this._coord2vertex.getVertexIndexes(coord, label_area, mkvertex)) { // 頂点の取得が出来なかった continue; } //矩形を発見したことをコールバック関数で通知 i_cb.detectMarkerCallback(coord, mkvertex); // 検出済の矩形の属したラベルを重なりチェックに追加する。 overlap.push(label_pt); } return; }
/** * 画面上の点が、このターゲットを包括する矩形の内側にあるかを判定します。 * この関数は、Known/Unknownターゲットに使用できます。 * @param i_x * @param i_y * @return * <p>メモ:この関数にはnewが残ってるので注意</p> */ public bool isInnerRectPoint2d(int i_x, int i_y) { Debug.Assert(this._target_type == RT_UNKNOWN || this._target_type == RT_KNOWN); NyARIntRect rect=new NyARIntRect(); NyARDoublePoint2d[] vx=((NyARRectTargetStatus)(this._ref_tracktarget._ref_status)).vertex; rect.setAreaRect(vx,4); return rect.isInnerPoint(i_x, i_y); }
/** * この関数は、ラスタから矩形を検出して、自己コールバック関数{@link #onSquareDetect}で通知します。 * @param i_raster * 検出元のラスタ画像 * 入力できるラスタの画素形式は、{@link NyARLabeling_Rle#labeling(INyARRaster, int)}と同じです。 * @param i_area * 検出する範囲。検出元のラスタの内側である必要があります。 * @param i_th * ラベルと判定する敷居値 * @ */ public void detectMarker(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th, NyARSquareContourDetector.CbHandler i_cb) { Debug.Assert(i_area.w * i_area.h > 0); NyARRleLabelFragmentInfoPtrStack flagment = this._labeling.label_stack; NyARLabelOverlapChecker <NyARRleLabelFragmentInfo> overlap = this._overlap_checker; //ラベルの生成エラーならここまで if (!this._labeling.labeling(i_raster, i_area, i_th)) { return; } // ラベル数が0ならここまで int label_num = flagment.getLength(); if (label_num < 1) { return; } //ラベルリストを取得 NyARRleLabelFragmentInfo[] labels = flagment.getArray(); NyARIntCoordinates coord = this._coord; int[] mkvertex = this.__detectMarker_mkvertex; //重なりチェッカの最大数を設定 overlap.setMaxLabels(label_num); for (int i = 0; i < label_num; i++) { NyARRleLabelFragmentInfo label_pt = labels[i]; // 既に検出された矩形との重なりを確認 if (!overlap.check(label_pt)) { // 重なっているようだ。 continue; } //輪郭を取得 if (!this._cpickup.getContour(i_raster, i_area, i_th, label_pt.entry_x, label_pt.clip_t, coord)) { continue; } int label_area = label_pt.area; //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得 if (!this._coord2vertex.getVertexIndexes(coord, label_area, mkvertex)) { // 頂点の取得が出来なかった continue; } //矩形を発見したことをコールバック関数で通知 i_cb.detectMarkerCallback(coord, mkvertex); // 検出済の矩形の属したラベルを重なりチェックに追加する。 overlap.push(label_pt); } return; }
/** * 範囲付きでGSラスタの2値ラべリングを実行します。 * @param i_gs_raster * @param i_area * @param i_th * @param o_stack * 結果を蓄積するスタックオブジェクトを指定します。 * 関数は、このオブジェクトに結果を追記します。 * @return * @throws NyARException */ public virtual void labeling(NyARGrayscaleRaster i_gs_raster, NyARIntRect i_area, int i_th) { Debug.Assert(i_gs_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); this.imple_labeling(i_gs_raster, i_th, i_area.x, i_area.y, i_area.w, i_area.h); }
public virtual void labeling(NyARBinRaster i_bin_raster, NyARIntRect i_area) { Debug.Assert(i_bin_raster.isEqualBufferType(NyARBufferType.INT1D_BIN_8)); this.imple_labeling(i_bin_raster, 0, i_area.x, i_area.y, i_area.w, i_area.h); }
public void doFilter(INyARRgbRaster i_input, NyARIntRect i_area, NyARBinRaster i_output) { this._do_threshold_impl.doThFilter(i_input, i_area.x, i_area.y, i_area.w, i_area.h, this._threshold, i_output); return; }
public bool getContour(NyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th, int i_entry_x, int i_entry_y, NyARIntCoordinates o_coord) { Debug.Assert(i_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); return(impl_getContour(i_raster, i_area.x, i_area.y, i_area.x + i_area.w - 1, i_area.h + i_area.y - 1, i_th, i_entry_x, i_entry_y, o_coord)); }
/** * この関数は、ラスタを敷居値i_thで2値化して、ラベリングします。 * 検出したラベルは、自己コールバック関数{@link #onLabelFound}で通知します。 * @param i_bin_raster * 入力画像。対応する形式は、クラスの説明を参照してください。 * @param i_area * ラべリングする画像内の範囲 * @param i_th * 敷居値 * @ */ public virtual bool labeling(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th) { return(this.imple_labeling(i_raster, 0, i_area.x, i_area.y, i_area.w, i_area.h)); }
/** * この関数は、ラスタの指定点を基点に、画像の特定の範囲内から輪郭線を抽出します。 * 開始点は、輪郭の一部である必要があります。 * 通常は、ラべリングの結果の上辺クリップとX軸エントリポイントを開始点として入力します。 * @param i_raster * 輪郭線を抽出するラスタを指定します。 * @param i_area * 輪郭線の抽出範囲を指定する矩形。i_rasterのサイズ内である必要があります。 * @param i_th * 輪郭とみなす暗点の敷居値を指定します。 * @param i_entry_x * 輪郭抽出の開始点です。 * @param i_entry_y * 輪郭抽出の開始点です。 * @param o_coord * 輪郭点を格納するオブジェクトを指定します。 * @return * 輪郭線がo_coordの長さを超えた場合、falseを返します。 * @ */ public bool getContour(INyARGrayscaleRaster i_raster, NyARIntRect i_area, int i_th, int i_entry_x, int i_entry_y, NyARIntCoordinates o_coord) { //ラスタドライバの切り替え if (i_raster != this._ref_last_input_raster) { this._imdriver = (IRasterDriver)i_raster.createInterface(typeof(IRasterDriver)); this._ref_last_input_raster = i_raster; } return this._imdriver.getContour(i_area.x, i_area.y, i_area.x + i_area.w - 1, i_area.h + i_area.y - 1, i_entry_x, i_entry_y, i_th, o_coord); }
/** * この関数は、オブジェクトの値をインスタンスにセットします。 * @param i_source * セットする値を格納したオブジェクト。 */ public void setValue(NyARIntRect i_source) { this.x = i_source.x; this.y = i_source.y; this.h = i_source.h; this.w = i_source.w; }
/** * この関数は、2つの矩形の対角点同士の距離の二乗値を計算します。 * @param i_rect2 * 比較する矩形 * @return * 左上、右下の点同士の距離の二乗値 */ public int sqDiagonalPointDiff(NyARIntRect i_rect2) { int w1, w2; int ret; w1 = this.x - i_rect2.x; w2 = this.y - i_rect2.y; ret = w1 * w1 + w2 * w2; w1 += this.w - i_rect2.w; w2 += this.h - i_rect2.h; ret += w1 * w1 + w2 * w2; return ret; }
public void doFilter(INyARRgbRaster i_input, NyARIntRect i_area, NyARBinRaster i_output) { Debug.Assert(i_input.getSize().isEqualSize(i_output.getSize()) == true); this._do_threshold_impl.doThFilter(i_input, i_area.x, i_area.y, i_area.w, i_area.h, this._threshold, i_output); return; }