protected bool initInstance(NyARIntSize i_size, int i_raster_type, bool i_is_alloc) { switch (i_raster_type) { case NyARBufferType.INT1D_X8R8G8B8_32: this._buf = i_is_alloc?new int[i_size.w * i_size.h]:null; this._reader = new NyARRgbPixelReader_INT1D_X8R8G8B8_32((int[])this._buf, i_size); break; case NyARBufferType.BYTE1D_B8G8R8X8_32: this._buf = i_is_alloc?new byte[i_size.w * i_size.h * 4]:null; this._reader = new NyARRgbPixelReader_BYTE1D_B8G8R8X8_32((byte[])this._buf, i_size); break; case NyARBufferType.BYTE1D_R8G8B8_24: this._buf = i_is_alloc?new byte[i_size.w * i_size.h * 3]:null; this._reader = new NyARRgbPixelReader_BYTE1D_R8G8B8_24((byte[])this._buf, i_size); break; default: return(false); } this._is_attached_buffer = i_is_alloc; return(true); }
/** * 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); }
/** * @see INyARColorPatt#pickFromRaster */ public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs) { double[] conv_param = this._convparam; int rx2, ry2; rx2 = this._size.w; ry2 = this._size.h; int[] rgb_tmp = new int[3]; INyARRgbPixelReader reader = image.getRgbPixelReader(); // 変形先領域の頂点を取得 //変換行列から現在の座標系への変換パラメタを作成 calcPara(i_vertexs, conv_param); // 変換パラメータを求める for (int y = 0; y < ry2; y++) { for (int x = 0; x < rx2; x++) { int ttx = (int)((conv_param[0] * x * y + conv_param[1] * x + conv_param[2] * y + conv_param[3]) + 0.5); int tty = (int)((conv_param[4] * x * y + conv_param[5] * x + conv_param[6] * y + conv_param[7]) + 0.5); reader.getPixel((int)ttx, (int)tty, rgb_tmp); this._patdata[x + y * rx2] = (rgb_tmp[0] << 16) | (rgb_tmp[1] << 8) | rgb_tmp[2]; } } return(true); }
public DsRGB565Raster(int i_width, int i_height) : base(i_width, i_height, NyARBufferType.WORD1D_R5G6B5_16LE) { if (i_width % 4 != 0) { throw new NyARException(); } this._buf = new short[i_height * i_width]; this._rgb_reader = new NyARRgbPixelReader_WORD1D_R5G6B5_16LE(this._buf, this._size); return; }
/** * 矩形からピクセルを切り出します * @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 * @throws NyARException */ private bool rectPixels(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, 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[] pixcel_temp = this._pixcel_temp; int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; 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++; } //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい) i_reader.getPixelSet(ref_x, ref_y, i_width, pixcel_temp); //グレースケールにしながら、line→mapへの転写 for (int i2 = 0; i2 < i_width; i2++) { int index = i2 * 3; o_pixel[out_index] = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2]) / 3; out_index++; } } 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 * @throws NyARException */ private bool rectPixels(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, 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[] pixcel_temp = this._pixcel_temp; int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; 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++; } //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい) i_reader.getPixelSet(ref_x, ref_y, i_width, pixcel_temp); //グレースケールにしながら、line→mapへの転写 for (int i2 = 0; i2 < i_width; i2++) { int index = i2 * 3; o_pixel[out_index] = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2]) / 3; out_index++; } } return(true); }
/** * ラスタのコピーを実行します。 * この関数は暫定です。低速なので注意してください。 * @param i_input * @param o_output * @throws NyARException */ public static void copy(INyARRgbRaster i_input, INyARRgbRaster o_output) { Debug.Assert(i_input.getSize().isEqualSize(o_output.getSize())); int width = i_input.getWidth(); int height = i_input.getHeight(); int[] rgb = new int[3]; INyARRgbPixelReader inr = i_input.getRgbPixelReader(); INyARRgbPixelReader outr = o_output.getRgbPixelReader(); for (int i = height - 1; i >= 0; i--) { for (int i2 = width - 1; i2 >= 0; i2--) { inr.getPixel(i2, i, rgb); outr.setPixel(i2, i, rgb); } } }
/** * ANY形式の入力ドライバ。 * @param i_buf * @param i_number_of_pix * @param i_for_mod * @param o_out * pow値 * @return * @throws NyARException */ private static double setRaster_ANY(INyARRgbPixelReader i_reader, NyARIntSize i_size, int i_number_of_pix, int[] o_out) { int width = i_size.w; int[] rgb = new int[3]; int ave; //<PV/> //<平均値計算> ave = 0; for (int y = i_size.h - 1; y >= 0; y--) { for (int x = width - 1; x >= 0; x--) { i_reader.getPixel(x, y, rgb); ave += rgb[0] + rgb[1] + rgb[2]; } } //<平均値計算> ave = i_number_of_pix * 255 * 3 - ave; ave = 255 - (ave / (i_number_of_pix * 3)); //(255-R)-ave を分解するための事前計算 int sum = 0, w_sum; int input_ptr = i_number_of_pix * 3 - 1; //<差分値計算> for (int y = i_size.h - 1; y >= 0; y--) { for (int x = width - 1; x >= 0; x--) { i_reader.getPixel(x, y, rgb); w_sum = (ave - rgb[2]); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - rgb[1]); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - rgb[0]); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R } } //<差分値計算(FORの1/8展開)/> double p = Math.Sqrt((double)sum); return(p != 0.0?p:0.0000001); }
protected bool initInstance(NyARIntSize i_size,int i_raster_type,bool i_is_alloc) { switch(i_raster_type) { case NyARBufferType.INT1D_X8R8G8B8_32: this._buf=i_is_alloc?new int[i_size.w*i_size.h]:null; this._reader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32((int[])this._buf,i_size); break; case NyARBufferType.BYTE1D_B8G8R8X8_32: this._buf=i_is_alloc?new byte[i_size.w*i_size.h*4]:null; this._reader=new NyARRgbPixelReader_BYTE1D_B8G8R8X8_32((byte[])this._buf,i_size); break; case NyARBufferType.BYTE1D_R8G8B8_24: this._buf=i_is_alloc?new byte[i_size.w*i_size.h*3]:null; this._reader=new NyARRgbPixelReader_BYTE1D_R8G8B8_24((byte[])this._buf,i_size); break; default: return false; } this._is_attached_buffer=i_is_alloc; return true; }
public bool readDataBits(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer) { double[] index_x = this.__readDataBits_index_bit_x; double[] index_y = this.__readDataBits_index_bit_y; //読み出し位置を取得 int size = detectDataBitsIndex(i_reader, i_raster_size,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++) { 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] = (int)((cpx0_0 + cpy0_12) / d); ref_y[pt] = (int)((cpx3_0 + cpy0_45) / d); pt++; d = cp6_0 + cpy1_7; ref_x[pt] = (int)((cpx0_0 + cpy1_12) / d); ref_y[pt] = (int)((cpx3_0 + cpy1_45) / d); pt++; d = cp6_1 + cpy0_7; ref_x[pt] = (int)((cpx0_1 + cpy0_12) / d); ref_y[pt] = (int)((cpx3_1 + cpy0_45) / d); pt++; d = cp6_1 + cpy1_7; ref_x[pt] = (int)((cpx0_1 + cpy1_12) / d); ref_y[pt] = (int)((cpx3_1 + cpy1_45) / d); pt++; } //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい) i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp); //グレースケールにしながら、line→mapへの転写 for (int i2 = 0; i2 < resolution; i2++) { int index = i2 * 3 * 4; int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3] + 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++; } } /* for(int i=0;i<225*4;i++){ this.vertex_x[i]=0; this.vertex_y[i]=0; } for(int i=0;i<(resolution)*2;i++){ for(int i2=0;i2<(resolution)*2;i2++){ this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2]; this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i]; } } */ return true; }
private int detectDataBitsIndex(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th, double[] o_index_row, double[] o_index_col) { //周波数を測定 int[] freq_index1 = this.__detectDataBitsIndex_freq_index1; int[] freq_index2 = this.__detectDataBitsIndex_freq_index2; int frq_t = getRowFrequency(i_reader, i_raster_size, i_th.lt_y, i_th.th_h, i_th.th_l, freq_index1); int frq_b = getRowFrequency(i_reader, i_raster_size, i_th.rb_y, i_th.th_h, i_th.th_l, freq_index2); //周波数はまとも? if ((frq_t < 0 && frq_b < 0) || frq_t == frq_b) { return -1; } //タイミングパターンからインデクスを作成 int freq_h, freq_v; int[] index; if (frq_t > frq_b) { freq_h = frq_t; index = freq_index1; } else { freq_h = frq_b; index = freq_index2; } for (int i = 0; i < freq_h + freq_h - 1; i++) { o_index_row[i * 2] = ((index[i + 1] - index[i]) * 2 / 5 + index[i]) + FRQ_EDGE; o_index_row[i * 2 + 1] = ((index[i + 1] - index[i]) * 3 / 5 + index[i]) + FRQ_EDGE; } int frq_l = getColFrequency(i_reader, i_raster_size, i_th.lt_x, i_th.th_h, i_th.th_l, freq_index1); int frq_r = getColFrequency(i_reader, i_raster_size, i_th.rb_x, i_th.th_h, i_th.th_l, freq_index2); //周波数はまとも? if ((frq_l < 0 && frq_r < 0) || frq_l == frq_r) { return -1; } //タイミングパターンからインデクスを作成 if (frq_l > frq_r) { freq_v = frq_l; index = freq_index1; } else { freq_v = frq_r; index = freq_index2; } //同じ周期? if (freq_v != freq_h) { return -1; } for (int i = 0; i < freq_v + freq_v - 1; i++) { int w = index[i]; int w2 = index[i + 1] - w; o_index_col[i * 2] = ((w2) * 2 / 5 + w) + FRQ_EDGE; o_index_col[i * 2 + 1] = ((w2) * 3 / 5 + w) + FRQ_EDGE; } //Lv4以上は無理 if (freq_v > MAX_FREQ) { return -1; } return freq_v; }
/** * @see INyARColorPatt#pickFromRaster */ public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs) { //遠近法のパラメータを計算 double[] cpara = this.__pickFromRaster_cpara; if (!this._perspective_gen.getParam(this._pickup_wh, i_vertexs, cpara)) { return(false); } int resolution = this._resolution; int img_x = image.getWidth(); int img_y = image.getHeight(); int res_pix = resolution * resolution; int[] rgb_tmp = this.__pickFromRaster_rgb_tmp; //ピクセルリーダーを取得 INyARRgbPixelReader reader = image.getRgbPixelReader(); int p = 0; for (int iy = 0; iy < this._size.h * resolution; iy += resolution) { //解像度分の点を取る。 for (int ix = 0; ix < this._size.w * resolution; ix += resolution) { int r, g, b; r = g = b = 0; for (int i2y = iy; i2y < iy + resolution; i2y++) { int cy = this._pickup_lt.y + i2y; for (int i2x = ix; i2x < ix + resolution; i2x++) { //1ピクセルを作成 int cx = this._pickup_lt.x + i2x; double d = cpara[6] * cx + cpara[7] * cy + 1.0; int x = (int)((cpara[0] * cx + cpara[1] * cy + cpara[2]) / d); int y = (int)((cpara[3] * cx + cpara[4] * cy + cpara[5]) / d); if (x < 0) { x = 0; } if (x >= img_x) { x = img_x - 1; } if (y < 0) { y = 0; } if (y >= img_y) { y = img_y - 1; } reader.getPixel(x, y, rgb_tmp); r += rgb_tmp[0]; g += rgb_tmp[1]; b += rgb_tmp[2]; } } r /= res_pix; g /= res_pix; b /= res_pix; this._patdata[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff)); p++; } } //ピクセル問い合わせ //ピクセルセット return(true); }
private int detectDataBitsIndex(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, double[] o_index_row, double[] o_index_col) { //周波数を測定 int[] freq_index1 = this.__detectDataBitsIndex_freq_index1; int[] freq_index2 = this.__detectDataBitsIndex_freq_index2; int frq_t = getRowFrequency(i_reader, i_raster_size, i_th.lt_y, i_th.th_h, i_th.th_l, freq_index1); int frq_b = getRowFrequency(i_reader, i_raster_size, i_th.rb_y, i_th.th_h, i_th.th_l, freq_index2); //周波数はまとも? if ((frq_t < 0 && frq_b < 0) || frq_t == frq_b) { return(-1); } //タイミングパターンからインデクスを作成 int freq_h, freq_v; int[] index; if (frq_t > frq_b) { freq_h = frq_t; index = freq_index1; } else { freq_h = frq_b; index = freq_index2; } for (int i = 0; i < freq_h + freq_h - 1; i++) { o_index_row[i * 2] = ((index[i + 1] - index[i]) * 2 / 5 + index[i]) + FRQ_EDGE; o_index_row[i * 2 + 1] = ((index[i + 1] - index[i]) * 3 / 5 + index[i]) + FRQ_EDGE; } int frq_l = getColFrequency(i_reader, i_raster_size, i_th.lt_x, i_th.th_h, i_th.th_l, freq_index1); int frq_r = getColFrequency(i_reader, i_raster_size, i_th.rb_x, i_th.th_h, i_th.th_l, freq_index2); //周波数はまとも? if ((frq_l < 0 && frq_r < 0) || frq_l == frq_r) { return(-1); } //タイミングパターンからインデクスを作成 if (frq_l > frq_r) { freq_v = frq_l; index = freq_index1; } else { freq_v = frq_r; index = freq_index2; } //同じ周期? if (freq_v != freq_h) { return(-1); } for (int i = 0; i < freq_v + freq_v - 1; i++) { int w = index[i]; int w2 = index[i + 1] - w; o_index_col[i * 2] = ((w2) * 2 / 5 + w) + FRQ_EDGE; o_index_col[i * 2 + 1] = ((w2) * 3 / 5 + w) + FRQ_EDGE; } //Lv4以上は無理 if (freq_v > MAX_FREQ) { return(-1); } return(freq_v); }
/** * 指定した場所のピクセル値を調査して、閾値を計算して返します。 * @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; }
/** * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。 * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを * 検出した場合、関数は失敗します。 * * @param i_y1 * @param i_y2 * @param i_th_h * @param i_th_l * @param o_edge_index * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。 * [FRQ_POINTS]以上の配列を指定してください。 * @return * @throws NyARException */ public int getRowFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_y1, int i_th_h, int i_th_l, int[] o_edge_index) { //3,4,5,6,7,8,9,10 int[] freq_count_table = this._freq_count_table; //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列 int[] freq_table = this._freq_table; //初期化 double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int[] pixcel_temp = this._pixcel_temp; for (int i = 0; i < 10; i++) { freq_count_table[i] = 0; } for (int i = 0; i < 110; i++) { freq_table[i] = 0; } int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; double cpara_0 = cpara[0]; double cpara_3 = cpara[3]; double cpara_6 = cpara[6]; //10-20ピクセル目からタイミングパターンを検出 for (int i = 0; i < FREQ_SAMPLE_NUM; i++) { //2行分のピクセルインデックスを計算 double cy0 = 1 + i_y1 + i; 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 < FRQ_POINTS; i2++) { double cx0 = 1 + i2 * FRQ_STEP + FRQ_EDGE; 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(-1); } ref_x[pt] = x; ref_y[pt] = y; pt++; } //ピクセルを取得(入力画像を多様化するならここから先を調整すること) i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp); //o_edge_indexを一時的に破壊して調査する 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)); }
//分割数16未満になると少し遅くなるかも。 private void updateExtpat(INyARRgbRaster image, NyARMat i_cpara, int i_xdiv2, int i_ydiv2) { int i, j; int r, g, b; //ピクセルリーダーを取得 int pat_size_w = this._size.w; int xdiv = i_xdiv2 / pat_size_w; // xdiv = xdiv2/Config.AR_PATT_SIZE_X; int ydiv = i_ydiv2 / this._size.h; // ydiv = ydiv2/Config.AR_PATT_SIZE_Y; int xdiv_x_ydiv = xdiv * ydiv; double reciprocal; double[][] para = i_cpara.getArray(); double para00 = para[0 * 3 + 0][0]; double para01 = para[0 * 3 + 1][0]; double para02 = para[0 * 3 + 2][0]; double para10 = para[1 * 3 + 0][0]; double para11 = para[1 * 3 + 1][0]; double para12 = para[1 * 3 + 2][0]; double para20 = para[2 * 3 + 0][0]; double para21 = para[2 * 3 + 1][0]; INyARRgbPixelReader reader = image.getRgbPixelReader(); int img_width = image.getWidth(); int img_height = image.getHeight(); //ワークバッファの準備 reservWorkBuffers(xdiv, ydiv); double[] xw = this.__updateExtpat_xw; double[] yw = this.__updateExtpat_yw; int[] xc = this.__updateExtpat_xc; int[] yc = this.__updateExtpat_yc; int[] rgb_set = this.__updateExtpat_rgbset; for (int iy = this._size.h - 1; iy >= 0; iy--) { for (int ix = pat_size_w - 1; ix >= 0; ix--) { //xw,ywマップを作成 reciprocal = 1.0 / i_xdiv2; for (i = xdiv - 1; i >= 0; i--) { xw[i] = LT_POS + SQ_SIZE * (ix * xdiv + i + 0.5) * reciprocal; } reciprocal = 1.0 / i_ydiv2; for (i = ydiv - 1; i >= 0; i--) { yw[i] = LT_POS + SQ_SIZE * (iy * ydiv + i + 0.5) * reciprocal; } //1ピクセルを構成するピクセル座標の集合をxc,yc配列に取得 int number_of_pix = 0; for (i = ydiv - 1; i >= 0; i--) { double para01_x_yw_para02 = para01 * yw[i] + para02; double para11_x_yw_para12 = para11 * yw[i] + para12; double para12_x_yw_para22 = para21 * yw[i] + 1.0; for (j = xdiv - 1; j >= 0; j--) { double d = para20 * xw[j] + para12_x_yw_para22; if (d == 0) { throw new NyARException(); } int xcw = (int)((para00 * xw[j] + para01_x_yw_para02) / d); int ycw = (int)((para10 * xw[j] + para11_x_yw_para12) / d); if (xcw < 0 || xcw >= img_width || ycw < 0 || ycw >= img_height) { continue; } xc[number_of_pix] = xcw; yc[number_of_pix] = ycw; number_of_pix++; } } //1ピクセル分の配列を取得 reader.getPixelSet(xc, yc, number_of_pix, rgb_set); r = g = b = 0; for (i = number_of_pix * 3 - 1; i >= 0; i -= 3) { r += rgb_set[i - 2]; // R g += rgb_set[i - 1]; // G b += rgb_set[i]; // B } //1ピクセル確定 this._patdata[iy * pat_size_w + ix] = (((r / xdiv_x_ydiv) & 0xff) << 16) | (((g / xdiv_x_ydiv) & 0xff) << 8) | (((b / xdiv_x_ydiv) & 0xff)); } } return; }
private void multiPixel_ANY(int pk_l, int pk_t, int in_w, int in_h, int i_resolution, double[] cpara, byte[] i_in_buf, INyARRgbRaster o_out) { int res_pix = i_resolution * i_resolution; INyARRgbPixelReader out_reader = o_out.getRgbPixelReader(); //ピクセルリーダーを取得 double cp0 = cpara[0]; double cp3 = cpara[3]; double cp6 = cpara[6]; double cp1 = cpara[1]; double cp4 = cpara[4]; double cp7 = cpara[7]; double cp2 = cpara[2]; double cp5 = cpara[5]; int out_w = o_out.getWidth(); int out_h = o_out.getHeight(); for (int iy = out_h - 1; iy >= 0; iy--) { //解像度分の点を取る。 for (int ix = out_w - 1; ix >= 0; ix--) { int r, g, b; r = g = b = 0; int cy = pk_t + iy * i_resolution; int cx = pk_l + ix * i_resolution; double cp7_cy_1_cp6_cx_b = cp7 * cy + 1.0 + cp6 * cx; double cp1_cy_cp2_cp0_cx_b = cp1 * cy + cp2 + cp0 * cx; double cp4_cy_cp5_cp3_cx_b = cp4 * cy + cp5 + cp3 * cx; for (int i2y = i_resolution - 1; i2y >= 0; i2y--) { double cp7_cy_1_cp6_cx = cp7_cy_1_cp6_cx_b; double cp1_cy_cp2_cp0_cx = cp1_cy_cp2_cp0_cx_b; double cp4_cy_cp5_cp3_cx = cp4_cy_cp5_cp3_cx_b; for (int i2x = i_resolution - 1; i2x >= 0; i2x--) { //1ピクセルを作成 double d = 1 / (cp7_cy_1_cp6_cx); int x = (int)((cp1_cy_cp2_cp0_cx) * d); int y = (int)((cp4_cy_cp5_cp3_cx) * d); if (x < 0) { x = 0; } else if (x >= in_w) { x = in_w - 1; } if (y < 0) { y = 0; } else if (y >= in_h) { y = in_h - 1; } int bp = (x + y * in_w) * 4; r += (i_in_buf[bp + 2] & 0xff); g += (i_in_buf[bp + 1] & 0xff); b += (i_in_buf[bp + 0] & 0xff); cp7_cy_1_cp6_cx += cp6; cp1_cy_cp2_cp0_cx += cp0; cp4_cy_cp5_cp3_cx += cp3; } cp7_cy_1_cp6_cx_b += cp7; cp1_cy_cp2_cp0_cx_b += cp1; cp4_cy_cp5_cp3_cx_b += cp4; } out_reader.setPixel(ix, iy, r / res_pix, g / res_pix, b / res_pix); } } return; }
private void onePixel_INT1D_X8R8G8B8_32(int pk_l, int pk_t, int in_w, int in_h, double[] cpara, INyARRgbPixelReader i_in_reader, INyARRgbRaster o_out) { Debug.Assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32)); int[] rgb_tmp = this.__pickFromRaster_rgb_tmp; int[] pat_data = (int[])o_out.getBuffer(); //ピクセルリーダーを取得 double cp0 = cpara[0]; double cp3 = cpara[3]; double cp6 = cpara[6]; double cp1 = cpara[1]; double cp4 = cpara[4]; double cp7 = cpara[7]; int out_w = o_out.getWidth(); int out_h = o_out.getHeight(); double cp7_cy_1 = cp7 * pk_t + 1.0 + cp6 * pk_l; double cp1_cy_cp2 = cp1 * pk_t + cpara[2] + cp0 * pk_l; double cp4_cy_cp5 = cp4 * pk_t + cpara[5] + cp3 * pk_l; int p = 0; for (int iy = out_h - 1; iy >= 0; iy--) { //解像度分の点を取る。 double cp7_cy_1_cp6_cx = cp7_cy_1; double cp1_cy_cp2_cp0_cx = cp1_cy_cp2; double cp4_cy_cp5_cp3_cx = cp4_cy_cp5; for (int ix = out_w - 1; ix >= 0; ix--) { //1ピクセルを作成 double d = 1 / (cp7_cy_1_cp6_cx); int x = (int)((cp1_cy_cp2_cp0_cx) * d); int y = (int)((cp4_cy_cp5_cp3_cx) * d); if (x < 0) { x = 0; } else if (x >= in_w) { x = in_w - 1; } if (y < 0) { y = 0; } else if (y >= in_h) { y = in_h - 1; } i_in_reader.getPixel(x, y, rgb_tmp); cp7_cy_1_cp6_cx += cp6; cp1_cy_cp2_cp0_cx += cp0; cp4_cy_cp5_cp3_cx += cp3; pat_data[p] = (rgb_tmp[0] << 16) | (rgb_tmp[1] << 8) | ((rgb_tmp[2] & 0xff)); p++; } cp7_cy_1 += cp7; cp1_cy_cp2 += cp1; cp4_cy_cp5 += cp4; } return; }
private void onePixel_ANY(int pk_l, int pk_t, int in_w, int in_h, double[] cpara, byte[] i_in_buf, INyARRgbRaster o_out) { INyARRgbPixelReader out_reader = o_out.getRgbPixelReader(); //ピクセルリーダーを取得 double cp0 = cpara[0]; double cp3 = cpara[3]; double cp6 = cpara[6]; double cp1 = cpara[1]; double cp4 = cpara[4]; double cp7 = cpara[7]; int out_w = o_out.getWidth(); int out_h = o_out.getHeight(); double cp7_cy_1 = cp7 * pk_t + 1.0 + cp6 * pk_l; double cp1_cy_cp2 = cp1 * pk_t + cpara[2] + cp0 * pk_l; double cp4_cy_cp5 = cp4 * pk_t + cpara[5] + cp3 * pk_l; int r, g, b; for (int iy = 0; iy < out_h; iy++) { //解像度分の点を取る。 double cp7_cy_1_cp6_cx = cp7_cy_1; double cp1_cy_cp2_cp0_cx = cp1_cy_cp2; double cp4_cy_cp5_cp3_cx = cp4_cy_cp5; for (int ix = 0; ix < out_w; ix++) { //1ピクセルを作成 double d = 1 / (cp7_cy_1_cp6_cx); int x = (int)((cp1_cy_cp2_cp0_cx) * d); int y = (int)((cp4_cy_cp5_cp3_cx) * d); if (x < 0) { x = 0; } else if (x >= in_w) { x = in_w - 1; } if (y < 0) { y = 0; } else if (y >= in_h) { y = in_h - 1; } int bp = (x + y * in_w) * 4; r = (i_in_buf[bp + 2] & 0xff); g = (i_in_buf[bp + 1] & 0xff); b = (i_in_buf[bp + 0] & 0xff); cp7_cy_1_cp6_cx += cp6; cp1_cy_cp2_cp0_cx += cp0; cp4_cy_cp5_cp3_cx += cp3; out_reader.setPixel(ix, iy, r, g, b); } cp7_cy_1 += cp7; cp1_cy_cp2 += cp1; cp4_cy_cp5 += cp4; } return; }
private void multiPixel_INT1D_X8R8G8B8_32(int pk_l, int pk_t, int in_w, int in_h, int i_resolution, double[] cpara, INyARRgbPixelReader i_in_reader, INyARRgbRaster o_out) { Debug.Assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32)); int res_pix = i_resolution * i_resolution; int[] rgb_tmp = this.__pickFromRaster_rgb_tmp; int[] pat_data = (int[])o_out.getBuffer(); //ピクセルリーダーを取得 double cp0 = cpara[0]; double cp3 = cpara[3]; double cp6 = cpara[6]; double cp1 = cpara[1]; double cp4 = cpara[4]; double cp7 = cpara[7]; double cp2 = cpara[2]; double cp5 = cpara[5]; int out_w = o_out.getWidth(); int out_h = o_out.getHeight(); int p = (out_w * out_h - 1); for (int iy = out_h - 1; iy >= 0; iy--) { //解像度分の点を取る。 for (int ix = out_w - 1; ix >= 0; ix--) { int r, g, b; r = g = b = 0; int cy = pk_t + iy * i_resolution; int cx = pk_l + ix * i_resolution; double cp7_cy_1_cp6_cx_b = cp7 * cy + 1.0 + cp6 * cx; double cp1_cy_cp2_cp0_cx_b = cp1 * cy + cp2 + cp0 * cx; double cp4_cy_cp5_cp3_cx_b = cp4 * cy + cp5 + cp3 * cx; for (int i2y = i_resolution - 1; i2y >= 0; i2y--) { double cp7_cy_1_cp6_cx = cp7_cy_1_cp6_cx_b; double cp1_cy_cp2_cp0_cx = cp1_cy_cp2_cp0_cx_b; double cp4_cy_cp5_cp3_cx = cp4_cy_cp5_cp3_cx_b; for (int i2x = i_resolution - 1; i2x >= 0; i2x--) { //1ピクセルを作成 double d = 1 / (cp7_cy_1_cp6_cx); int x = (int)((cp1_cy_cp2_cp0_cx) * d); int y = (int)((cp4_cy_cp5_cp3_cx) * d); if (x < 0) { x = 0; } else if (x >= in_w) { x = in_w - 1; } if (y < 0) { y = 0; } else if (y >= in_h) { y = in_h - 1; } i_in_reader.getPixel(x, y, rgb_tmp); r += rgb_tmp[0]; g += rgb_tmp[1]; b += rgb_tmp[2]; cp7_cy_1_cp6_cx += cp6; cp1_cy_cp2_cp0_cx += cp0; cp4_cy_cp5_cp3_cx += cp3; } cp7_cy_1_cp6_cx_b += cp7; cp1_cy_cp2_cp0_cx_b += cp1; cp4_cy_cp5_cp3_cx_b += cp4; } r /= res_pix; g /= res_pix; b /= res_pix; pat_data[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff)); p--; } } return; }
private void onePixel_ANY(int pk_l, int pk_t, int in_w, int in_h, double[] cpara, INyARRgbPixelReader i_in_reader, INyARRgbRaster o_out) { int[] rgb_tmp = this.__pickFromRaster_rgb_tmp; INyARRgbPixelReader out_reader = o_out.getRgbPixelReader(); //ピクセルリーダーを取得 double cp0 = cpara[0]; double cp3 = cpara[3]; double cp6 = cpara[6]; double cp1 = cpara[1]; double cp4 = cpara[4]; double cp7 = cpara[7]; int out_w = o_out.getWidth(); int out_h = o_out.getHeight(); double cp7_cy_1 = cp7 * pk_t + 1.0 + cp6 * pk_l; double cp1_cy_cp2 = cp1 * pk_t + cpara[2] + cp0 * pk_l; double cp4_cy_cp5 = cp4 * pk_t + cpara[5] + cp3 * pk_l; for (int iy = 0; iy < out_h; iy++) { //解像度分の点を取る。 double cp7_cy_1_cp6_cx = cp7_cy_1; double cp1_cy_cp2_cp0_cx = cp1_cy_cp2; double cp4_cy_cp5_cp3_cx = cp4_cy_cp5; for (int ix = 0; ix < out_w; ix++) { //1ピクセルを作成 double d = 1 / (cp7_cy_1_cp6_cx); int x = (int)((cp1_cy_cp2_cp0_cx) * d); int y = (int)((cp4_cy_cp5_cp3_cx) * d); if (x < 0) { x = 0; } else if (x >= in_w) { x = in_w - 1; } if (y < 0) { y = 0; } else if (y >= in_h) { y = in_h - 1; } i_in_reader.getPixel(x, y, rgb_tmp); cp7_cy_1_cp6_cx += cp6; cp1_cy_cp2_cp0_cx += cp0; cp4_cy_cp5_cp3_cx += cp3; out_reader.setPixel(ix, iy, rgb_tmp); } cp7_cy_1 += cp7; cp1_cy_cp2 += cp1; cp4_cy_cp5 += cp4; } return; }
public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt) { int i2x, i2y;//プライム変数 int x, y; int w; int r, g, b; int resolution = this._resolution; int res_pix = resolution * resolution; int img_x = image.getWidth(); int img_y = image.getHeight(); int[] rgb_tmp = this._rgb_temp; int[] rgb_px = this._rgb_px; int[] rgb_py = this._rgb_py; double[] cp1cy_cp2 = this._cp1cy_cp2; double[] cp4cy_cp5 = this._cp4cy_cp5; double[] cp7cy_1 = this._cp7cy_1; double cp0 = i_cpara[0]; double cp3 = i_cpara[3]; double cp6 = i_cpara[6]; double cp1 = i_cpara[1]; double cp2 = i_cpara[2]; double cp4 = i_cpara[4]; double cp5 = i_cpara[5]; double cp7 = i_cpara[7]; int pick_y = this._lt_ref.y; int pick_x = this._lt_ref.x; //ピクセルリーダーを取得 INyARRgbPixelReader reader = image.getRgbPixelReader(); int p = 0; for (int iy = 0; iy < this._size_ref.h * resolution; iy += resolution) { w = pick_y + iy; cp1cy_cp2[0] = cp1 * w + cp2; cp4cy_cp5[0] = cp4 * w + cp5; cp7cy_1[0] = cp7 * w + 1.0; for (i2y = 1; i2y < resolution; i2y++) { cp1cy_cp2[i2y] = cp1cy_cp2[i2y - 1] + cp1; cp4cy_cp5[i2y] = cp4cy_cp5[i2y - 1] + cp4; cp7cy_1[i2y] = cp7cy_1[i2y - 1] + cp7; } //解像度分の点を取る。 for (int ix = 0; ix < this._size_ref.w * resolution; ix += resolution) { int n = 0; w = pick_x + ix; for (i2y = resolution - 1; i2y >= 0; i2y--) { double cp0cx = cp0 * w + cp1cy_cp2[i2y]; double cp6cx = cp6 * w + cp7cy_1[i2y]; double cp3cx = cp3 * w + cp4cy_cp5[i2y]; double m = 1 / (cp6cx); double d = -cp6 / (cp6cx * (cp6cx + cp6)); double m2 = cp0cx * m; double m3 = cp3cx * m; double d2 = cp0cx * d + cp0 * (m + d); double d3 = cp3cx * d + cp3 * (m + d); for (i2x = resolution - 1; i2x >= 0; i2x--) { //1ピクセルを作成 x = rgb_px[n] = (int)(m2); y = rgb_py[n] = (int)(m3); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[n] = 0; } else if (x >= img_x) { rgb_px[n] = img_x - 1; } if (y < 0) { rgb_py[n] = 0; } else if (y >= img_y) { rgb_py[n] = img_y - 1; } } n++; m2 += d2; m3 += d3; } } reader.getPixelSet(rgb_px, rgb_py, res_pix, rgb_tmp); r = g = b = 0; for (int i = res_pix * 3 - 1; i > 0;) { b += rgb_tmp[i--]; g += rgb_tmp[i--]; r += rgb_tmp[i--]; } r /= res_pix; g /= res_pix; b /= res_pix; o_patt[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff)); p++; } } return; }
public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt) { double d0, m0; int x, y; int img_x = image.getWidth(); int img_y = image.getHeight(); int patt_w = this._size_ref.w; int[] rgb_tmp = this._rgb_temp; int[] rgb_px = this._rgb_px; int[] rgb_py = this._rgb_py; double cp0 = i_cpara[0]; double cp3 = i_cpara[3]; double cp6 = i_cpara[6]; double cp1 = i_cpara[1]; double cp4 = i_cpara[4]; double cp7 = i_cpara[7]; int pick_y = this._lt_ref.y; int pick_x = this._lt_ref.x; //ピクセルリーダーを取得 INyARRgbPixelReader reader = image.getRgbPixelReader(); int p = 0; double cp0cx0, cp3cx0; double cp1cy_cp20 = cp1 * pick_y + i_cpara[2] + cp0 * pick_x; double cp4cy_cp50 = cp4 * pick_y + i_cpara[5] + cp3 * pick_x; double cp7cy_10 = cp7 * pick_y + 1.0 + cp6 * pick_x; for (int iy = this._size_ref.h - 1; iy >= 0; iy--) { m0 = 1 / (cp7cy_10); d0 = -cp6 / (cp7cy_10 * (cp7cy_10 + cp6)); cp0cx0 = cp1cy_cp20; cp3cx0 = cp4cy_cp50; //ピックアップシーケンス //0番目のピクセル(検査対象)をピックアップ for (int ix = patt_w - 1; ix >= 0; ix--) { //1ピクセルを作成 x = rgb_px[ix] = (int)(cp0cx0 * m0); y = rgb_py[ix] = (int)(cp3cx0 * m0); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[ix] = 0; } else if (x >= img_x) { rgb_px[ix] = img_x - 1; } if (y < 0) { rgb_py[ix] = 0; } else if (y >= img_y) { rgb_py[ix] = img_y - 1; } } cp0cx0 += cp0; cp3cx0 += cp3; m0 += d0; } cp1cy_cp20 += cp1; cp4cy_cp50 += cp4; cp7cy_10 += cp7; reader.getPixelSet(rgb_px, rgb_py, patt_w, rgb_tmp); for (int ix = patt_w - 1; ix >= 0; ix--) { int idx = ix * 3; o_patt[p] = (rgb_tmp[idx] << 16) | (rgb_tmp[idx + 1] << 8) | ((rgb_tmp[idx + 2] & 0xff)); p++; } } return; }
public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt) { int x, y; double d, m; double cp6cx, cp0cx, cp3cx; int[] rgb_px = this._rgb_px; int[] rgb_py = this._rgb_py; int r, g, b; //遠近法のパラメータを計算 int img_x = image.getWidth(); int img_y = image.getHeight(); int[] rgb_tmp = this._rgb_temp; double cp0 = i_cpara[0]; double cp3 = i_cpara[3]; double cp6 = i_cpara[6]; double cp1 = i_cpara[1]; double cp2 = i_cpara[2]; double cp4 = i_cpara[4]; double cp5 = i_cpara[5]; double cp7 = i_cpara[7]; int pick_lt_x = this._lt_ref.x; //ピクセルリーダーを取得 INyARRgbPixelReader reader = image.getRgbPixelReader(); int p = 0; int py = this._lt_ref.y; for (int iy = this._size_ref.h - 1; iy >= 0; iy--, py += 4) { double cp1cy_cp2_0 = cp1 * py + cp2; double cp4cy_cp5_0 = cp4 * py + cp5; double cp7cy_1_0 = cp7 * py + 1.0; double cp1cy_cp2_1 = cp1cy_cp2_0 + cp1; double cp1cy_cp2_2 = cp1cy_cp2_1 + cp1; double cp1cy_cp2_3 = cp1cy_cp2_2 + cp1; double cp4cy_cp5_1 = cp4cy_cp5_0 + cp4; double cp4cy_cp5_2 = cp4cy_cp5_1 + cp4; double cp4cy_cp5_3 = cp4cy_cp5_2 + cp4; int px = pick_lt_x; //解像度分の点を取る。 for (int ix = this._size_ref.w - 1; ix >= 0; ix--, px += 4) { cp6cx = cp6 * px; cp0cx = cp0 * px; cp3cx = cp3 * px; cp6cx += cp7cy_1_0; m = 1 / cp6cx; d = -cp7 / ((cp6cx + cp7) * cp6cx); //1ピクセルを作成[0,0] x = rgb_px[0] = (int)((cp0cx + cp1cy_cp2_0) * m); y = rgb_py[0] = (int)((cp3cx + cp4cy_cp5_0) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[0] = 0; } else if (x >= img_x) { rgb_px[0] = img_x - 1; } if (y < 0) { rgb_py[0] = 0; } else if (y >= img_y) { rgb_py[0] = img_y - 1; } } //1ピクセルを作成[0,1] m += d; x = rgb_px[4] = (int)((cp0cx + cp1cy_cp2_1) * m); y = rgb_py[4] = (int)((cp3cx + cp4cy_cp5_1) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[4] = 0; } else if (x >= img_x) { rgb_px[4] = img_x - 1; } if (y < 0) { rgb_py[4] = 0; } else if (y >= img_y) { rgb_py[4] = img_y - 1; } } //1ピクセルを作成[0,2] m += d; x = rgb_px[8] = (int)((cp0cx + cp1cy_cp2_2) * m); y = rgb_py[8] = (int)((cp3cx + cp4cy_cp5_2) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[8] = 0; } else if (x >= img_x) { rgb_px[8] = img_x - 1; } if (y < 0) { rgb_py[8] = 0; } else if (y >= img_y) { rgb_py[8] = img_y - 1; } } //1ピクセルを作成[0,3] m += d; x = rgb_px[12] = (int)((cp0cx + cp1cy_cp2_3) * m); y = rgb_py[12] = (int)((cp3cx + cp4cy_cp5_3) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[12] = 0; } else if (x >= img_x) { rgb_px[12] = img_x - 1; } if (y < 0) { rgb_py[12] = 0; } else if (y >= img_y) { rgb_py[12] = img_y - 1; } } cp6cx += cp6; cp0cx += cp0; cp3cx += cp3; m = 1 / cp6cx; d = -cp7 / ((cp6cx + cp7) * cp6cx); //1ピクセルを作成[1,0] x = rgb_px[1] = (int)((cp0cx + cp1cy_cp2_0) * m); y = rgb_py[1] = (int)((cp3cx + cp4cy_cp5_0) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[1] = 0; } else if (x >= img_x) { rgb_px[1] = img_x - 1; } if (y < 0) { rgb_py[1] = 0; } else if (y >= img_y) { rgb_py[1] = img_y - 1; } } //1ピクセルを作成[1,1] m += d; x = rgb_px[5] = (int)((cp0cx + cp1cy_cp2_1) * m); y = rgb_py[5] = (int)((cp3cx + cp4cy_cp5_1) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[5] = 0; } else if (x >= img_x) { rgb_px[5] = img_x - 1; } if (y < 0) { rgb_py[5] = 0; } else if (y >= img_y) { rgb_py[5] = img_y - 1; } } //1ピクセルを作成[1,2] m += d; x = rgb_px[9] = (int)((cp0cx + cp1cy_cp2_2) * m); y = rgb_py[9] = (int)((cp3cx + cp4cy_cp5_2) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[9] = 0; } else if (x >= img_x) { rgb_px[9] = img_x - 1; } if (y < 0) { rgb_py[9] = 0; } else if (y >= img_y) { rgb_py[9] = img_y - 1; } } //1ピクセルを作成[1,3] m += d; x = rgb_px[13] = (int)((cp0cx + cp1cy_cp2_3) * m); y = rgb_py[13] = (int)((cp3cx + cp4cy_cp5_3) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[13] = 0; } else if (x >= img_x) { rgb_px[13] = img_x - 1; } if (y < 0) { rgb_py[13] = 0; } else if (y >= img_y) { rgb_py[13] = img_y - 1; } } cp6cx += cp6; cp0cx += cp0; cp3cx += cp3; m = 1 / cp6cx; d = -cp7 / ((cp6cx + cp7) * cp6cx); //1ピクセルを作成[2,0] x = rgb_px[2] = (int)((cp0cx + cp1cy_cp2_0) * m); y = rgb_py[2] = (int)((cp3cx + cp4cy_cp5_0) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[2] = 0; } else if (x >= img_x) { rgb_px[2] = img_x - 1; } if (y < 0) { rgb_py[2] = 0; } else if (y >= img_y) { rgb_py[2] = img_y - 1; } } //1ピクセルを作成[2,1] m += d; x = rgb_px[6] = (int)((cp0cx + cp1cy_cp2_1) * m); y = rgb_py[6] = (int)((cp3cx + cp4cy_cp5_1) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[6] = 0; } else if (x >= img_x) { rgb_px[6] = img_x - 1; } if (y < 0) { rgb_py[6] = 0; } else if (y >= img_y) { rgb_py[6] = img_y - 1; } } //1ピクセルを作成[2,2] m += d; x = rgb_px[10] = (int)((cp0cx + cp1cy_cp2_2) * m); y = rgb_py[10] = (int)((cp3cx + cp4cy_cp5_2) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[10] = 0; } else if (x >= img_x) { rgb_px[10] = img_x - 1; } if (y < 0) { rgb_py[10] = 0; } else if (y >= img_y) { rgb_py[10] = img_y - 1; } } //1ピクセルを作成[2,3](ここ計算ずれします。) m += d; x = rgb_px[14] = (int)((cp0cx + cp1cy_cp2_3) * m); y = rgb_py[14] = (int)((cp3cx + cp4cy_cp5_3) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[14] = 0; } else if (x >= img_x) { rgb_px[14] = img_x - 1; } if (y < 0) { rgb_py[14] = 0; } else if (y >= img_y) { rgb_py[14] = img_y - 1; } } cp6cx += cp6; cp0cx += cp0; cp3cx += cp3; m = 1 / cp6cx; d = -cp7 / ((cp6cx + cp7) * cp6cx); //1ピクセルを作成[3,0] x = rgb_px[3] = (int)((cp0cx + cp1cy_cp2_0) * m); y = rgb_py[3] = (int)((cp3cx + cp4cy_cp5_0) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[3] = 0; } else if (x >= img_x) { rgb_px[3] = img_x - 1; } if (y < 0) { rgb_py[3] = 0; } else if (y >= img_y) { rgb_py[3] = img_y - 1; } } //1ピクセルを作成[3,1] m += d; x = rgb_px[7] = (int)((cp0cx + cp1cy_cp2_1) * m); y = rgb_py[7] = (int)((cp3cx + cp4cy_cp5_1) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[7] = 0; } else if (x >= img_x) { rgb_px[7] = img_x - 1; } if (y < 0) { rgb_py[7] = 0; } else if (y >= img_y) { rgb_py[7] = img_y - 1; } } //1ピクセルを作成[3,2] m += d; x = rgb_px[11] = (int)((cp0cx + cp1cy_cp2_2) * m); y = rgb_py[11] = (int)((cp3cx + cp4cy_cp5_2) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[11] = 0; } else if (x >= img_x) { rgb_px[11] = img_x - 1; } if (y < 0) { rgb_py[11] = 0; } else if (y >= img_y) { rgb_py[11] = img_y - 1; } } //1ピクセルを作成[3,3] m += d; x = rgb_px[15] = (int)((cp0cx + cp1cy_cp2_3) * m); y = rgb_py[15] = (int)((cp3cx + cp4cy_cp5_3) * m); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[15] = 0; } else if (x >= img_x) { rgb_px[15] = img_x - 1; } if (y < 0) { rgb_py[15] = 0; } else if (y >= img_y) { rgb_py[15] = img_y - 1; } } reader.getPixelSet(rgb_px, rgb_py, 4 * 4, rgb_tmp); r = (rgb_tmp[0] + rgb_tmp[3] + rgb_tmp[6] + rgb_tmp[9] + rgb_tmp[12] + rgb_tmp[15] + rgb_tmp[18] + rgb_tmp[21] + rgb_tmp[24] + rgb_tmp[27] + rgb_tmp[30] + rgb_tmp[33] + rgb_tmp[36] + rgb_tmp[39] + rgb_tmp[42] + rgb_tmp[45]) / 16; g = (rgb_tmp[1] + rgb_tmp[4] + rgb_tmp[7] + rgb_tmp[10] + rgb_tmp[13] + rgb_tmp[16] + rgb_tmp[19] + rgb_tmp[22] + rgb_tmp[25] + rgb_tmp[28] + rgb_tmp[31] + rgb_tmp[34] + rgb_tmp[37] + rgb_tmp[40] + rgb_tmp[43] + rgb_tmp[46]) / 16; b = (rgb_tmp[2] + rgb_tmp[5] + rgb_tmp[8] + rgb_tmp[11] + rgb_tmp[14] + rgb_tmp[17] + rgb_tmp[20] + rgb_tmp[23] + rgb_tmp[26] + rgb_tmp[29] + rgb_tmp[32] + rgb_tmp[35] + rgb_tmp[38] + rgb_tmp[41] + rgb_tmp[44] + rgb_tmp[47]) / 16; o_patt[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff)); p++; } } return; }
/** * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。 * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを * 検出した場合、関数は失敗します。 * * @param i_y1 * @param i_y2 * @param i_th_h * @param i_th_l * @param o_edge_index * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。 * [FRQ_POINTS]以上の配列を指定してください。 * @return * @throws NyARException */ public int getRowFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_y1, int i_th_h, int i_th_l, int[] o_edge_index) { //3,4,5,6,7,8,9,10 int[] freq_count_table = this._freq_count_table; //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列 int[] freq_table = this._freq_table; //初期化 double[] cpara = this._cparam; int[] ref_x = this._ref_x; int[] ref_y = this._ref_y; int[] pixcel_temp = this._pixcel_temp; for (int i = 0; i < 10; i++) { freq_count_table[i] = 0; } for (int i = 0; i < 110; i++) { freq_table[i] = 0; } int raster_width = i_raster_size.w; int raster_height = i_raster_size.h; double cpara_0 = cpara[0]; double cpara_3 = cpara[3]; double cpara_6 = cpara[6]; //10-20ピクセル目からタイミングパターンを検出 for (int i = 0; i < FREQ_SAMPLE_NUM; i++) { //2行分のピクセルインデックスを計算 double cy0 = 1 + i_y1 + i; 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 < FRQ_POINTS; i2++) { double cx0 = 1 + i2 * FRQ_STEP + FRQ_EDGE; 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 -1; } ref_x[pt] = x; ref_y[pt] = y; pt++; } //ピクセルを取得(入力画像を多様化するならここから先を調整すること) i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp); //o_edge_indexを一時的に破壊して調査する 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); }
public int getColFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, 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_size.w; int raster_height = i_raster_size.h; 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_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp); 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)); }
public int getColFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, 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_size.w; int raster_height = i_raster_size.h; 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_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp); 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); }
public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt) { double d0, m0, d1, m1; int x, y; int img_x = image.getWidth(); int img_y = image.getHeight(); int patt_w = this._size_ref.w; int[] rgb_tmp = this._rgb_temp; int[] rgb_px = this._rgb_px; int[] rgb_py = this._rgb_py; double cp0 = i_cpara[0]; double cp3 = i_cpara[3]; double cp6 = i_cpara[6]; double cp1 = i_cpara[1]; double cp4 = i_cpara[4]; double cp7 = i_cpara[7]; int pick_y = this._lt_ref.y; int pick_x = this._lt_ref.x; //ピクセルリーダーを取得 INyARRgbPixelReader reader = image.getRgbPixelReader(); int p = 0; double cp0cx0, cp3cx0; double cp1cy_cp20 = cp1 * pick_y + i_cpara[2] + cp0 * pick_x; double cp4cy_cp50 = cp4 * pick_y + i_cpara[5] + cp3 * pick_x; double cp7cy_10 = cp7 * pick_y + 1.0 + cp6 * pick_x; double cp0cx1, cp3cx1; double cp1cy_cp21 = cp1cy_cp20 + cp1; double cp4cy_cp51 = cp4cy_cp50 + cp4; double cp7cy_11 = cp7cy_10 + cp7; double cw0 = cp1 + cp1; double cw7 = cp7 + cp7; double cw4 = cp4 + cp4; for (int iy = this._size_ref.h - 1; iy >= 0; iy--) { cp0cx0 = cp1cy_cp20; cp3cx0 = cp4cy_cp50; cp0cx1 = cp1cy_cp21; cp3cx1 = cp4cy_cp51; m0 = 1 / (cp7cy_10); d0 = -cp6 / (cp7cy_10 * (cp7cy_10 + cp6)); m1 = 1 / (cp7cy_11); d1 = -cp6 / (cp7cy_11 * (cp7cy_11 + cp6)); int n = patt_w * 2 * 2 - 1; for (int ix = patt_w * 2 - 1; ix >= 0; ix--) { //[n,0] x = rgb_px[n] = (int)(cp0cx0 * m0); y = rgb_py[n] = (int)(cp3cx0 * m0); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[n] = 0; } else if (x >= img_x) { rgb_px[n] = img_x - 1; } if (y < 0) { rgb_py[n] = 0; } else if (y >= img_y) { rgb_py[n] = img_y - 1; } } cp0cx0 += cp0; cp3cx0 += cp3; m0 += d0; n--; //[n,1] x = rgb_px[n] = (int)(cp0cx1 * m1); y = rgb_py[n] = (int)(cp3cx1 * m1); if (x < 0 || x >= img_x || y < 0 || y >= img_y) { if (x < 0) { rgb_px[n] = 0; } else if (x >= img_x) { rgb_px[n] = img_x - 1; } if (y < 0) { rgb_py[n] = 0; } else if (y >= img_y) { rgb_py[n] = img_y - 1; } } cp0cx1 += cp0; cp3cx1 += cp3; m1 += d1; n--; } cp7cy_10 += cw7; cp7cy_11 += cw7; cp1cy_cp20 += cw0; cp4cy_cp50 += cw4; cp1cy_cp21 += cw0; cp4cy_cp51 += cw4; reader.getPixelSet(rgb_px, rgb_py, patt_w * 4, rgb_tmp); for (int ix = patt_w - 1; ix >= 0; ix--) { int idx = ix * 12;//3*2*2 int r = (rgb_tmp[idx + 0] + rgb_tmp[idx + 3] + rgb_tmp[idx + 6] + rgb_tmp[idx + 9]) / 4; int g = (rgb_tmp[idx + 1] + rgb_tmp[idx + 4] + rgb_tmp[idx + 7] + rgb_tmp[idx + 10]) / 4; int b = (rgb_tmp[idx + 2] + rgb_tmp[idx + 5] + rgb_tmp[idx + 8] + rgb_tmp[idx + 11]) / 4; o_patt[p] = (r << 16) | (g << 8) | ((b & 0xff)); p++; } } return; }
/** * 指定した場所のピクセル値を調査して、閾値を計算して返します。 * @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; }
public bool readDataBits(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer) { double[] index_x = this.__readDataBits_index_bit_x; double[] index_y = this.__readDataBits_index_bit_y; //読み出し位置を取得 int size = detectDataBitsIndex(i_reader, i_raster_size, 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++) { 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] = (int)((cpx0_0 + cpy0_12) / d); ref_y[pt] = (int)((cpx3_0 + cpy0_45) / d); pt++; d = cp6_0 + cpy1_7; ref_x[pt] = (int)((cpx0_0 + cpy1_12) / d); ref_y[pt] = (int)((cpx3_0 + cpy1_45) / d); pt++; d = cp6_1 + cpy0_7; ref_x[pt] = (int)((cpx0_1 + cpy0_12) / d); ref_y[pt] = (int)((cpx3_1 + cpy0_45) / d); pt++; d = cp6_1 + cpy1_7; ref_x[pt] = (int)((cpx0_1 + cpy1_12) / d); ref_y[pt] = (int)((cpx3_1 + cpy1_45) / d); pt++; } //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい) i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp); //グレースケールにしながら、line→mapへの転写 for (int i2 = 0; i2 < resolution; i2++) { int index = i2 * 3 * 4; int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3] + 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++; } } /* * for(int i=0;i<225*4;i++){ * this.vertex_x[i]=0; * this.vertex_y[i]=0; * } * for(int i=0;i<(resolution)*2;i++){ * for(int i2=0;i2<(resolution)*2;i2++){ * this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2]; * this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i]; * * } * } */ return(true); }
public NyARRgbRaster_Blank(int i_width, int i_height) : base(i_width, i_height, NyARBufferType.NULL_ALLZERO) { this._reader = new PixelReader(); return; }
/** * 回転方向を指定してラスタをセットします。 * @param i_reader * @param i_direction * 右上の位置です。0=1象限、1=2象限、、2=3象限、、3=4象限の位置に対応します。 * @throws NyARException */ public void setRaster(INyARRgbRaster i_raster, int i_direction) { int width = this._size.w; int height = this._size.h; int i_number_of_pix = width * height; INyARRgbPixelReader reader = i_raster.getRgbPixelReader(); int[] rgb = new int[3]; int[] dout = this._data; int ave; //<PV/> //<平均値計算> ave = 0; for (int y = height - 1; y >= 0; y--) { for (int x = width - 1; x >= 0; x--) { reader.getPixel(x, y, rgb); ave += rgb[0] + rgb[1] + rgb[2]; } } //<平均値計算> ave = i_number_of_pix * 255 * 3 - ave; ave = 255 - (ave / (i_number_of_pix * 3)); //(255-R)-ave を分解するための事前計算 int sum = 0, w_sum; int input_ptr = i_number_of_pix * 3 - 1; switch (i_direction) { case 0: for (int y = height - 1; y >= 0; y--) { for (int x = width - 1; x >= 0; x--) { reader.getPixel(x, y, rgb); w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //R } } break; case 1: for (int x = 0; x < width; x++) { for (int y = height - 1; y >= 0; y--) { reader.getPixel(x, y, rgb); w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //R } } break; case 2: for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { reader.getPixel(x, y, rgb); w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //R } } break; case 3: for (int x = width - 1; x >= 0; x--) { for (int y = 0; y < height; y++) { reader.getPixel(x, y, rgb); w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum; //R } } break; } //<差分値計算> //<差分値計算(FORの1/8展開)/> double p = Math.Sqrt((double)sum); this._pow = (p != 0.0?p:0.0000001); }