public double get_similarity(INyARGrayscaleRaster imageBW, int cx, int cy) { int ts1 = this._ts1; int ts2 = this._ts2; int xsize = imageBW.getWidth(); int ysize = imageBW.getHeight(); if (cy - ts1 < 0 || cy + ts2 >= ysize || cx - ts1 < 0 || cx + ts2 >= xsize) { return(-1); } int tp = 0; double p_sum = 0.0f; double pxp_sum = 0; double img_sum = 0; double img_p_sum = 0; for (int j = -ts1; j <= ts2; j++) { for (int i = -ts1; i <= ts2; i++) { int p = (imageBW.getPixel(cx + i, cy + j)); double t = this.img[tp++]; pxp_sum += p * p; p_sum += p; img_sum += t; img_p_sum += t * p; } } double ave = p_sum / ((ts1 + ts2 + 1) * (ts1 + ts2 + 1)); double w1 = img_p_sum - img_sum * ave; double vlen2 = Math.Sqrt((pxp_sum - 2 * p_sum * ave) + (ave * ave * (ts1 + ts2 + 1) * (ts1 + ts2 + 1))); return(w1 / (this.vlen * vlen2)); }
/** * 検索ウインドウは(i_px*2+1)*(i_py*2+1)サイズの矩形。 * @param i_ref_raster * @param i_search_x * 検索ウインドウの範囲を指定する。 * @param i_search_y */ public NyARTemplateMatchingDriver_INT1D(INyARGrayscaleRaster i_ref_raster, int i_search_x, int i_search_y) { Debug.Assert(i_ref_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); this._i_ref_raster = i_ref_raster; this._mbuf = new byte[i_ref_raster.getWidth() * i_ref_raster.getHeight()]; this._search_area.x = i_search_x; this._search_area.y = i_search_y; }
public NyARTemplateMatchingDriver_ANY(INyARGrayscaleRaster i_ref_raster) { Debug.Assert(i_ref_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); this._i_ref_raster = i_ref_raster; this._mbuf = new byte[i_ref_raster.getWidth() * i_ref_raster.getHeight()]; this._search_area.x = AR2_DEFAULT_SEARCH_SIZE; this._search_area.y = AR2_DEFAULT_SEARCH_SIZE; }
/** * GrayscaleRasterから任意サイズのパッチイメージを生成する。 * @param i_src * @param i_src_dpi * @param i_dest_dpi */ public ReferenceImage(INyARGrayscaleRaster i_src, double i_src_dpi, double i_dest_dpi) : this( (int)lroundf(i_src.getWidth() * i_dest_dpi / i_src_dpi), (int)lroundf(i_src.getHeight() * i_dest_dpi / i_src_dpi), i_dest_dpi) { ; int p2 = 0;//dst->imgBW; int wx = this.width; int wy = this.height; int sh = i_src.getHeight(); int sw = i_src.getWidth(); for (int jj = 0; jj < wy; jj++) { int sy = (int)lroundf(jj * i_src_dpi / dpi); int ey = (int)lroundf((jj + 1) * i_src_dpi / dpi) - 1; if (ey >= sh) { ey = sh - 1; } for (int ii = 0; ii < wx; ii++) { int sx = (int)lroundf(ii * i_src_dpi / dpi); int ex = (int)lroundf((ii + 1) * i_src_dpi / dpi) - 1; if (ex >= sw) { ex = sw - 1; } int co = 0; int value = 0; for (int jjj = sy; jjj <= ey; jjj++) { for (int iii = sx; iii <= ex; iii++) { value += i_src.getPixel(iii, jjj) & 0xff; co++; } } this.img[p2++] = (value / co); } } return; }
public void copyTo(int i_left, int i_top, int i_skip, INyARGrayscaleRaster o_output) { Debug.Assert(this._raster.getSize().isInnerSize(i_left + o_output.getWidth() * i_skip, i_top + o_output.getHeight() * i_skip)); int[] input = (int[])this._raster.getBuffer(); switch (o_output.getBufferType()) { case NyARBufferType.INT1D_GRAY_8: int[] output = (int[])o_output.getBuffer(); NyARIntSize dest_size = o_output.getSize(); NyARIntSize src_size = this._raster.getSize(); int skip_src_y = (src_size.w - dest_size.w * i_skip) + src_size.w * (i_skip - 1); int pix_count = dest_size.w; int pix_mod_part = pix_count - (pix_count % 8); // 左上から1行づつ走査していく int pt_dst = 0; int pt_src = (i_top * src_size.w + i_left); for (int y = dest_size.h - 1; y >= 0; y -= 1) { int x; for (x = pix_count - 1; x >= pix_mod_part; x--) { output[pt_dst++] = input[pt_src]; pt_src += i_skip; } for (; x >= 0; x -= 8) { output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; output[pt_dst++] = input[pt_src]; pt_src += i_skip; } // スキップ pt_src += skip_src_y; } return; default: throw new NyARException(); } }
public bool make_template(INyARGrayscaleRaster imageBW, int cx, int cy, double sd_thresh) { int ts1 = this._ts1; int ts2 = this._ts2; int xsize = imageBW.getWidth(); int ysize = imageBW.getHeight(); if (cy - ts1 < 0 || cy + ts2 >= ysize || cx - ts1 < 0 || cx + ts2 >= xsize) { return(false); } double ave = 0.0f; for (int j = -ts1; j <= ts2; j++) { // int ip = (cy+j)*xsize+(cx-ts1); for (int i = -ts1; i <= ts2; i++) { // ave += *(ip++); ave += imageBW.getPixel(cx + i, cy + j); } } ave /= (ts1 + ts2 + 1) * (ts1 + ts2 + 1); int tp = 0; double vlen1 = 0.0f; for (int j = -ts1; j <= ts2; j++) { for (int i = -ts1; i <= ts2; i++) { double p = (imageBW.getPixel(cx + i, cy + j)) - ave; this.img[tp] = p; vlen1 += p * p; tp++; } } if (vlen1 == 0.0f) { return(false); } if (vlen1 / ((ts1 + ts2 + 1) * (ts1 + ts2 + 1)) < sd_thresh * sd_thresh) { return(false); } this.vlen = Math.Sqrt(vlen1); return(true); }
/** * ラスタから射影変換したピクセルを得ます。 * @param i_lt_x * @param i_lt_y * @param i_step_x * @param i_step_y * @param i_width * @param i_height * @param i_out_st * 格納バッファo_pixelの先頭のインデクス。 * @param o_pixel * グレースケールのピクセルを格納するバッファ * @ */ private bool rectPixels(INyARGrayscaleRaster i_raster, int i_lt_x, int i_lt_y, int i_step_x, int i_step_y, int i_width, int i_height, int i_out_st, int[] o_pixel) { double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int raster_width = i_raster.getWidth();; int raster_height = i_raster.getHeight(); int out_index = i_out_st; double cpara_6 = cpara[6]; double cpara_0 = cpara[0]; double cpara_3 = cpara[3]; for (int i = 0; i < i_height; i++) { //1列分のピクセルのインデックス値を計算する。 int cy0 = 1 + i * i_step_y + i_lt_y; 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 < i_width; i2++) { int cx0 = 1 + i2 * i_step_x + i_lt_x; 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(false); } ref_x[pt] = x; ref_y[pt] = y; pt++; } //GS値を配列に取得 i_raster.getPixelSet(ref_x, ref_y, i_width, o_pixel, out_index); out_index += i_width; } return(true); }
public static NyARNftIsetFile genImageSet(INyARGrayscaleRaster i_raster, double srcdpi) { double[] dpis = makeDpiList(i_raster.getWidth(), i_raster.getHeight(), srcdpi); return(genImageSet(i_raster, srcdpi, dpis)); }
/** * この関数は、マーカパターンからデータを読み取ります。 * @param i_reader * ラスタリーダ * @param i_raster_size * ラスタのサイズ * @param o_bitbuffer * データビットの出力先 * @return * 成功するとtrue * @throws NyARException */ public bool readDataBits(INyARGrayscaleRaster i_raster, MarkerPattDecoder o_bitbuffer) { int raster_width = i_raster.getWidth(); int raster_height = i_raster.getHeight(); 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_raster.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); }
private void apply_filter(KpmImage dst, INyARGrayscaleRaster src) { Debug.Assert(src.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); binomial_4th_order((double[])dst.getBuffer(), this.mTemp_us16, (int[])src.getBuffer(), src.getWidth(), src.getHeight()); }
/** * この関数は、マーカパターンからデータを読み取ります。 * @param i_reader * ラスタリーダ * @param i_raster_size * ラスタのサイズ * @param i_th * 敷居値情報 * @param o_bitbuffer * データビットの出力先 * @return * 成功するとtrue * @ */ public bool readDataBits(INyARGrayscaleRaster i_raster, PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer) { int raster_width = i_raster.getWidth(); int raster_height = i_raster.getHeight(); double[] index_x = this.__readDataBits_index_bit_x; double[] index_y = this.__readDataBits_index_bit_y; //読み出し位置を取得 int size = detectDataBitsIndex(i_raster, 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_raster.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); }
/** * この関数は、マーカ画像の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(INyARGrayscaleRaster i_raster, 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.getWidth(); int raster_height = i_raster.getHeight(); 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_raster.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)); }