public override bool encode(NyIdMarkerPattern i_data, INyIdMarkerData o_dest) { //対象か調べるん if (i_data.ctrl_domain != 0) { return false; } //受け入れられるMaskは0のみ if (i_data.ctrl_mask != 0) { return false; } //受け入れられるModelは5未満 if (i_data.model >= 5) { return false; } //エンコードしてみる if (!base.encode(i_data, this._tmp)) { return false; } //SerialIDの再構成 ulong s = 0; //最大4バイト繋げて1個のint値に変換 for (int i = 0; i < this._tmp.length; i++) { s = (s << 8) | (uint)this._tmp.packet[i]; } ((NyIdMarkerData_RawBitId)o_dest).marker_id = (long)s; return true; }
/** * この関数は、i_sourceからインスタンスにマーカデータをコピーします。 * 引数には、{@link NyIdMarkerData_RawBit}型のオブジェクトを指定してください。 */ public void copyFrom(INyIdMarkerData i_source) { NyIdMarkerData_RawBitId s = (NyIdMarkerData_RawBitId)i_source; this.marker_id = s.marker_id; return; }
/** * この関数は、i_sourceからインスタンスにマーカデータをコピーします。 * 引数には、{@link NyIdMarkerData_RawBit}型のオブジェクトを指定してください。 */ public void copyFrom(INyIdMarkerData i_source) { NyIdMarkerData_RawBit s = (NyIdMarkerData_RawBit)i_source; Array.Copy(s.packet, 0, this.packet, 0, s.length); this.length = s.length; return; }
public bool encode(NyIdMarkerPattern i_data, INyIdMarkerData o_dest) { NyIdMarkerData_RawBit dest = (NyIdMarkerData_RawBit)o_dest; if (i_data.ctrl_domain != _DOMAIN_ID) { return(false); } //パケット数計算 int resolution_len = (i_data.model + i_data.model - 1); //データドットの数 int packet_length = (resolution_len * resolution_len) / 8 + 1; int sum = 0; for (int i = 0; i < packet_length; i++) { dest.packet[i] = i_data.data[i]; sum += i_data.data[i]; } //チェックドット値計算 sum = sum % _mod_data[i_data.model - 2]; //チェックドット比較 if (i_data.check != sum) { return(false); } dest.length = packet_length; return(true); }
/** * この関数は、インスタンスを初期化します。 * 継承先のクラスから呼び出してください。 * @param i_param * カメラパラメータオブジェクト。このサイズは、{@link #detectMarker}に入力する画像と同じサイズである必要があります。 * @param i_encoder * IDマーカの値エンコーダを指定します。 * @param i_marker_width * マーカの物理縦横サイズをmm単位で指定します。 * @ */ protected void initInstance(NyARParam i_param, INyIdMarkerDataEncoder i_encoder, double i_marker_width) { //初期化済? Debug.Assert(this._initialized == false); NyARIntSize scr_size = i_param.getScreenSize(); // 解析オブジェクトを作る this._square_detect = new RleDetector( i_param, i_encoder, new NyIdMarkerPickup()); this._transmat = new NyARTransMat(i_param); // 2値画像バッファを作る this._gs_raster = new NyARGrayscaleRaster(scr_size.w, scr_size.h); this._histmaker = (INyARHistogramFromRaster)this._gs_raster.createInterface(typeof(INyARHistogramFromRaster)); //ワーク用のデータオブジェクトを2個作る this._data_current = i_encoder.createDataInstance(); this._threshold_detect = new NyARHistogramAnalyzer_SlidePTile(15); this._initialized = true; this._is_active = false; this._offset = new NyARRectOffset(); this._offset.setSquare(i_marker_width); return; }
public override bool encode(NyIdMarkerPattern i_data, INyIdMarkerData o_dest) { //対象か調べるん if (i_data.ctrl_domain != 0) { return(false); } //受け入れられるMaskは0のみ if (i_data.ctrl_mask != 0) { return(false); } //受け入れられるModelは5未満 if (i_data.model >= 5) { return(false); } //エンコードしてみる if (!base.encode(i_data, this._tmp)) { return(false); } //SerialIDの再構成 ulong s = 0; //最大4バイト繋げて1個のint値に変換 for (int i = 0; i < this._tmp.length; i++) { s = (s << 8) | (uint)this._tmp.packet[i]; } ((NyIdMarkerData_RawBitId)o_dest).marker_id = (long)s; return(true); }
public bool encode(NyIdMarkerPattern i_data, INyIdMarkerData o_dest) { NyIdMarkerData_RawBit dest = (NyIdMarkerData_RawBit)o_dest; if (i_data.ctrl_domain != _DOMAIN_ID) { return false; } //パケット数計算 int resolution_len = (i_data.model + 1); int packet_length = (resolution_len * resolution_len) / 8 + 1; int sum = 0; for (int i = 0; i < packet_length; i++) { dest.packet[i] = i_data.data[i]; sum += i_data.data[i]; } //チェックドット値計算 sum = sum % _mod_data[i_data.model - 2]; //チェックドット比較 if (i_data.check != sum) { return false; } dest.length = packet_length; return true; }
public DetectSquareCB(NyARParam i_param, INyIdMarkerDataEncoder i_encoder) { this._coordline = new Coord2Linear(i_param.getScreenSize(), i_param.getDistortionFactor()); this._data_temp = i_encoder.createDataInstance(); this._current_data = i_encoder.createDataInstance(); this._encoder = i_encoder; return; }
/**オブジェクトのステータスを更新し、必要に応じて自己コールバック関数を駆動します。 */ private bool updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data) { bool is_id_found = false; if (!this._is_active) { // 未認識中 if (i_marker_data == null) { // 未認識から未認識の遷移 // なにもしないよーん。 this._is_active = false; } else {// 未認識から認識の遷移 this._data_current.copyFrom(i_marker_data); // イベント生成 // OnEnter this.onEnterHandler(this._data_current); // 変換行列を作成 this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param); // OnUpdate this.onUpdateHandler(i_square, this._transmat_result); this._lost_delay_count = 0; this._is_active = true; is_id_found = true; } } else {// 認識中 if (i_marker_data == null) { // 認識から未認識の遷移 this._lost_delay_count++; if (this._lost_delay < this._lost_delay_count) { // OnLeave this.onLeaveHandler(); this._is_active = false; } } else if (this._data_current.isEqual(i_marker_data)) { //同じidの再認識 if (!this._transmat.transMatContinue(i_square, this._offset, this._transmat_result, this._last_result_param.last_error, this._transmat_result, this._last_result_param)) { this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param); } // OnUpdate this.onUpdateHandler(i_square, this._transmat_result); this._lost_delay_count = 0; is_id_found = true; } else {// 異なるコードの認識→今はサポートしない。 throw new NyARException(); } } return(is_id_found); }
public RleDetector(NyARParam i_param, INyIdMarkerDataEncoder i_encoder, NyIdMarkerPickup i_id_pickup) : base(i_param.getScreenSize()) { this._coordline = new NyARCoord2Linear(i_param.getScreenSize(), i_param.getDistortionFactor()); this._data_temp = i_encoder.createDataInstance(); this._current_data = i_encoder.createDataInstance(); this._encoder = i_encoder; this._id_pickup = i_id_pickup; return; }
public RleDetector(NyARParam i_param, INyIdMarkerDataEncoder i_encoder, NyIdMarkerPickup i_id_pickup): base(i_param.getScreenSize()) { this._coordline = new NyARCoord2Linear(i_param.getScreenSize(), i_param.getDistortionFactor()); this._data_temp = i_encoder.createDataInstance(); this._current_data = i_encoder.createDataInstance(); this._encoder = i_encoder; this._id_pickup = i_id_pickup; return; }
/** * この関数は、i_targetのマーカデータとインスタンスのデータを比較します。 * 引数には、{@link NyIdMarkerData_RawBit}型のオブジェクトを指定してください。 */ public bool isEqual(INyIdMarkerData i_target) { NyIdMarkerData_RawBit s = (NyIdMarkerData_RawBit)i_target; if (s.length != this.length) { return false; } for (int i = s.length - 1; i >= 0; i--) { if (s.packet[i] != this.packet[i]) { return false; } } return true; }
/** * この関数は、i_targetのマーカデータとインスタンスのデータを比較します。 * 引数には、{@link NyIdMarkerData_RawBit}型のオブジェクトを指定してください。 */ public bool isEqual(INyIdMarkerData i_target) { NyIdMarkerData_RawBit s = (NyIdMarkerData_RawBit)i_target; if (s.length != this.length) { return(false); } for (int i = s.length - 1; i >= 0; i--) { if (s.packet[i] != this.packet[i]) { return(false); } } return(true); }
/** * アプリケーションフレームワークのハンドラ(マーカ出現) */ protected override void onEnterHandler(INyIdMarkerData i_code) { NyIdMarkerData_RawBit code = (NyIdMarkerData_RawBit)i_code; if (code.length > 4) { //4バイト以上の時はint変換しない。 this.current_id = -1;//undefined_id } else { this.current_id = 0; //最大4バイト繋げて1個のint値に変換 for (int i = 0; i < code.length; i++) { this.current_id = (this.current_id << 8) | code.packet[i]; } } }
protected void initInstance(NyARParam i_param, INyIdMarkerDataEncoder i_encoder, double i_marker_width, int i_raster_format) { //初期化済? Debug.Assert(this._initialized == false); NyARIntSize scr_size = i_param.getScreenSize(); // 解析オブジェクトを作る this._square_detect = new RleDetector(i_param, i_encoder); this._transmat = new NyARTransMat(i_param); // 2値画像バッファを作る this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h); //ワーク用のデータオブジェクトを2個作る this._data_current = i_encoder.createDataInstance(); this._tobin_filter = new NyARRasterFilter_ARToolkitThreshold(110, i_raster_format); this._threshold_detect = new NyARRasterThresholdAnalyzer_SlidePTile(15, i_raster_format, 4); this._initialized = true; this._is_active = false; this._offset = new NyARRectOffset(); this._offset.setSquare(i_marker_width); return; }
/** * Initialize call back handler. */ public void init(INyARGrayscaleRaster i_raster, INyIdMarkerData i_prev_data) { this.marker_data = null; this._prev_data = i_prev_data; this._ref_raster = i_raster; }
/** * 自己コールバック関数です。 * 継承したクラスで、マーカ発見時の処理を実装してください。 * @param i_code * 検出したIDマーカの内容をエンコードしたデータです。 * 使用したエンコーダに合せて、キャストしてください。 * (例えば、{@link NyIdMarkerDataEncoder_RawBit}をエンコーダに用いた時は、{@link NyIdMarkerDataEncoder_RawBit}にキャストできます。) */ protected abstract void onEnterHandler(INyIdMarkerData i_code);
/**オブジェクトのステータスを更新し、必要に応じて自己コールバック関数を駆動します。 */ private bool updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data) { bool is_id_found = false; if (!this._is_active) {// 未認識中 if (i_marker_data == null) {// 未認識から未認識の遷移 // なにもしないよーん。 this._is_active = false; } else {// 未認識から認識の遷移 this._data_current.copyFrom(i_marker_data); // イベント生成 // OnEnter this.onEnterHandler(this._data_current); // 変換行列を作成 this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param); // OnUpdate this.onUpdateHandler(i_square, this._transmat_result); this._lost_delay_count = 0; this._is_active = true; is_id_found = true; } } else {// 認識中 if (i_marker_data == null) { // 認識から未認識の遷移 this._lost_delay_count++; if (this._lost_delay < this._lost_delay_count) { // OnLeave this.onLeaveHandler(); this._is_active = false; } } else if (this._data_current.isEqual(i_marker_data)) { //同じidの再認識 if (!this._transmat.transMatContinue(i_square, this._offset, this._transmat_result, this._last_result_param.last_error, this._transmat_result, this._last_result_param)) { this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param); } // OnUpdate this.onUpdateHandler(i_square, this._transmat_result); this._lost_delay_count = 0; is_id_found = true; } else {// 異なるコードの認識→今はサポートしない。 throw new NyARException(); } } return is_id_found; }
/** * 矩形が見付かるたびに呼び出されます。 * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。 */ public void detectMarkerCallback(NyARIntCoordinates i_coord,int[] i_vertex_index) { //既に発見済なら終了 if (this.marker_data != null) { return; } //輪郭座標から頂点リストに変換 NyARIntPoint2d[] vertex = this.__ref_vertex; vertex[0] = i_coord.items[i_vertex_index[0]]; vertex[1] = i_coord.items[i_vertex_index[1]]; vertex[2] = i_coord.items[i_vertex_index[2]]; vertex[3] = i_coord.items[i_vertex_index[3]]; NyIdMarkerParam param = this._marker_param; NyIdMarkerPattern patt_data = this._marker_data; // 評価基準になるパターンをイメージから切り出す if (!this._id_pickup.pickFromRaster(this._ref_raster.getGsPixelDriver(), vertex, patt_data, param)) { return; } //エンコード if (!this._encoder.encode(patt_data, this._data_temp)) { return; } //継続認識要求されている? if (this._prev_data == null) { //継続認識要求なし this._current_data.copyFrom(this._data_temp); } else { //継続認識要求あり if (!this._prev_data.isEqual((this._data_temp))) { return;//認識請求のあったIDと違う。 } } //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。 //ココから先はこの条件でしか実行されない。 NyARSquare sq = this.square; //directionを考慮して、squareを更新する。 for (int i = 0; i < 4; i++) { int idx = (i + 4 - param.direction) % 4; this._coordline.coord2Line(i_vertex_index[idx], i_vertex_index[(idx + 1) % 4], i_coord, sq.line[i]); } for (int i = 0; i < 4; i++) { //直線同士の交点計算 if (!sq.line[i].crossPos(sq.line[(i + 3) % 4], sq.sqvertex[i])) { throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK } } this.threshold = param.threshold; this.marker_data = this._current_data;//みつかった。 }
/** * この関数は、i_targetのマーカデータとインスタンスのデータを比較します。 * 引数には、{@link NyIdMarkerData_RawBitId}型のオブジェクトを指定してください。 */ public bool isEqual(INyIdMarkerData i_target) { NyIdMarkerData_RawBitId s = (NyIdMarkerData_RawBitId)i_target; return(s.marker_id == this.marker_id); }
/** * 矩形が見付かるたびに呼び出されます。 * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。 */ public void onSquareDetect(NyARSquareContourDetector i_sender, int[] i_coordx, int[] i_coordy, int i_coor_num, int[] i_vertex_index) { //既に発見済なら終了 if (this.marker_data != null) { return; } //輪郭座標から頂点リストに変換 NyARIntPoint2d[] vertex = this.__tmp_vertex; vertex[0].x = i_coordx[i_vertex_index[0]]; vertex[0].y = i_coordy[i_vertex_index[0]]; vertex[1].x = i_coordx[i_vertex_index[1]]; vertex[1].y = i_coordy[i_vertex_index[1]]; vertex[2].x = i_coordx[i_vertex_index[2]]; vertex[2].y = i_coordy[i_vertex_index[2]]; vertex[3].x = i_coordx[i_vertex_index[3]]; vertex[3].y = i_coordy[i_vertex_index[3]]; NyIdMarkerParam param = this._marker_param; NyIdMarkerPattern patt_data = this._marker_data; // 評価基準になるパターンをイメージから切り出す if (!this._id_pickup.pickFromRaster(this._ref_raster, vertex, patt_data, param)) { return; } //エンコード if (!this._encoder.encode(patt_data, this._data_temp)) { return; } //継続認識要求されている? if (this._prev_data == null) { //継続認識要求なし this._current_data.copyFrom(this._data_temp); } else { //継続認識要求あり if (!this._prev_data.isEqual((this._data_temp))) { return;//認識請求のあったIDと違う。 } } //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。 //ココから先はこの条件でしか実行されない。 NyARSquare sq = this.square; //directionを考慮して、squareを更新する。 for (int i = 0; i < 4; i++) { int idx = (i + 4 - param.direction) % 4; this._coordline.coord2Line(i_vertex_index[idx], i_vertex_index[(idx + 1) % 4], i_coordx, i_coordy, i_coor_num, sq.line[i]); } for (int i = 0; i < 4; i++) { //直線同士の交点計算 if (!NyARLinear.crossPos(sq.line[i], sq.line[(i + 3) % 4], sq.sqvertex[i])) { throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK } } this.threshold = param.threshold; this.marker_data = this._current_data;//みつかった。 }
/** * Initialize call back handler. */ public void init(INyARRgbRaster i_raster, INyIdMarkerData i_prev_data) { this.marker_data = null; this._prev_data = i_prev_data; this._ref_raster = i_raster; }
//通知ハンドラ protected abstract void onEnterHandler(INyIdMarkerData i_code);
/** * この関数は、i_targetのマーカデータとインスタンスのデータを比較します。 * 引数には、{@link NyIdMarkerData_RawBitId}型のオブジェクトを指定してください。 */ public bool isEqual(INyIdMarkerData i_target) { NyIdMarkerData_RawBitId s = (NyIdMarkerData_RawBitId)i_target; return s.marker_id == this.marker_id; }
protected void initInstance(NyARParam i_param, INyIdMarkerDataEncoder i_encoder, double i_marker_width, int i_raster_format) { //初期化済? Debug.Assert(this._initialized == false); NyARIntSize scr_size = i_param.getScreenSize(); // 解析オブジェクトを作る this._square_detect = new NyARSquareContourDetector_Rle(scr_size); this._transmat = new NyARTransMat(i_param); this._callback = new DetectSquareCB(i_param, i_encoder); // 2値画像バッファを作る this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h); //ワーク用のデータオブジェクトを2個作る this._data_current = i_encoder.createDataInstance(); this._tobin_filter = new NyARRasterFilter_ARToolkitThreshold(110, i_raster_format); this._threshold_detect = new NyARRasterThresholdAnalyzer_SlidePTile(15, i_raster_format, 4); this._initialized = true; this._is_active = false; this._offset = new NyARRectOffset(); this._offset.setSquare(i_marker_width); return; }