/** * コンストラクタです。 * 入力画像のサイズを指定して、インスタンスを生成します。 * @param i_size * 入力画像のサイズ */ public NyARSquareContourDetector_Rle(NyARIntSize i_size) { this.setupImageDriver(i_size); //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。 this._coord = new NyARIntCoordinates((i_size.w + i_size.h) * 2); return; }
/** * Readerとbufferを初期化する関数です。コンストラクタから呼び出します。 * 継承クラスでこの関数を拡張することで、対応するバッファタイプの種類を増やせます。 * @param i_size * ラスタのサイズ * @param i_raster_type * バッファタイプ * @param i_is_alloc * 外部参照/内部バッファのフラグ * @return * 初期化が成功すると、trueです。 * @ */ protected override void initInstance(NyARIntSize i_size, int i_raster_type, bool i_is_alloc) { //バッファの構築 switch (i_raster_type) { case NyARBufferType.OBJECT_CS_Bitmap: this._rgb_pixel_driver = new NyARRgbPixelDriver_CsBitmap(); if (i_is_alloc) { this._buf = new Bitmap(i_size.w, i_size.h, PixelFormat.Format32bppRgb); this._rgb_pixel_driver.switchRaster(this); } else { this._buf = null; } this._is_attached_buffer = i_is_alloc; break; default: base.initInstance(i_size,i_raster_type,i_is_alloc); break; } //readerの構築 return; }
public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) { Debug.Assert(i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr =(int[])i_input.getBuffer(); int[] out_ptr=(int[])i_output.getBuffer(); int width=i_size.w; int idx=0; int idx2=width; int fx,fy; int mod_p=(width-2)-(width-2)%4; for(int y=i_size.h-2;y>=0;y--){ int p00=in_ptr[idx++]; int p10=in_ptr[idx2++]; int p01,p11; int x=width-2; for(;x>=mod_p;x--){ p01=in_ptr[idx++];p11=in_ptr[idx2++]; fx=p11-p00;fy=p10-p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx=(fx*fx+fy*fy)>>SH;out_ptr[idx-2]=(fx>255?0:255-fx); p00=p01; p10=p11; } for(;x>=0;x-=4){ p01=in_ptr[idx++];p11=in_ptr[idx2++]; fx=p11-p00; fy=p10-p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx=(fx*fx+fy*fy)>>SH;out_ptr[idx-2]=(fx>255?0:255-fx); p00=p01;p10=p11; p01=in_ptr[idx++];p11=in_ptr[idx2++]; fx=p11-p00; fy=p10-p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx=(fx*fx+fy*fy)>>SH;out_ptr[idx-2]=(fx>255?0:255-fx); p00=p01;p10=p11; p01=in_ptr[idx++];p11=in_ptr[idx2++]; fx=p11-p00; fy=p10-p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx=(fx*fx+fy*fy)>>SH;out_ptr[idx-2]=(fx>255?0:255-fx); p00=p01;p10=p11; p01=in_ptr[idx++];p11=in_ptr[idx2++]; fx=p11-p00; fy=p10-p01; // out_ptr[idx-2]=255-(((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1); fx=(fx*fx+fy*fy)>>SH;out_ptr[idx-2]=(fx>255?0:255-fx); p00=p01;p10=p11; } out_ptr[idx-1]=255; } for(int x=width-1;x>=0;x--){ out_ptr[idx++]=255; } return; }
/** * コンストラクタです。 * @param i_width * このラスタの幅 * @param i_height * このラスタの高さ * @ */ public NyARColorPatt_PseudoAffine(int i_width, int i_height) { this._size = new NyARIntSize(i_width, i_height); this._patdata = new int[i_height * i_width]; this._pixelreader = NyARRgbPixelDriverFactory.createDriver(this); //疑似アフィン変換のパラメタマトリクスを計算します。 //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。 NyARDoubleMatrix44 mat = this._invmat; mat.m00 = 0; mat.m01 = 0; mat.m02 = 0; mat.m03 = 1.0; mat.m10 = 0; mat.m11 = i_width - 1; mat.m12 = 0; mat.m13 = 1.0; mat.m20 = (i_width - 1) * (i_height - 1); mat.m21 = i_width - 1; mat.m22 = i_height - 1; mat.m23 = 1.0; mat.m30 = 0; mat.m31 = 0; mat.m32 = i_height - 1; mat.m33 = 1.0; mat.inverse(mat); return; }
public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) { Debug.Assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); Debug.Assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr =(int[])i_input.getBuffer(); int[] out_ptr=(int[])i_output.getBuffer(); int width=i_size.w; int height=i_size.h; for(int y=0;y<height-1;y++){ int idx=y*width; int p00=in_ptr[idx]; int p10=in_ptr[width+idx]; int p01,p11; for(int x=0;x<width-1;x++){ p01=in_ptr[idx+1]; p11=in_ptr[idx+width+1]; int fx=p11-p00; int fy=p10-p01; out_ptr[idx]=(int)Math.Sqrt(fx*fx+fy*fy)>>1; p00=p01; p10=p11; idx++; } } return; }
public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) { Debug.Assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); Debug.Assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr =(int[])i_input.getBuffer(); int[] out_ptr=(int[])i_output.getBuffer(); int width=i_size.w; int height=i_size.h; int col0,col1,col2; int bptr=0; //1行目 col1=in_ptr[bptr ]*2+in_ptr[bptr+width ]; col2=in_ptr[bptr+1]*2+in_ptr[bptr+width+1]; out_ptr[bptr]=(col1*2+col2)/9; bptr++; for(int x=0;x<width-2;x++){ col0=col1; col1=col2; col2=in_ptr[bptr+1]*2+in_ptr[bptr+width+1]; out_ptr[bptr]=(col0+col1*2+col2)/12; bptr++; } out_ptr[bptr]=(col1+col2)/9; bptr++; //2行目-末行-1 for(int y=0;y<height-2;y++){ //左端 col1=in_ptr[bptr ]*2+in_ptr[bptr-width ]+in_ptr[bptr+width ]; col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]+in_ptr[bptr+width+1]; out_ptr[bptr]=(col1+col2)/12; bptr++; for(int x=0;x<width-2;x++){ col0=col1; col1=col2; col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]+in_ptr[bptr+width+1]; out_ptr[bptr]=(col0+col1*2+col2)/16; bptr++; } //右端 out_ptr[bptr]=(col1*2+col2)/12; bptr++; } //末行目 col1=in_ptr[bptr ]*2+in_ptr[bptr-width ]; col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]; out_ptr[bptr]=(col1+col2)/9; bptr++; for(int x=0;x<width-2;x++){ col0=col1; col1=col2; col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]; out_ptr[bptr]=(col0+col1*2+col2)/12; bptr++; } out_ptr[bptr]=(col1*2+col2)/9; bptr++; return; }
/** * コンストラクタです。 * 解像度を指定して、インスタンスを生成します。 * @param i_width * ラスタのサイズ * @param i_height * ラスタのサイズ * @ */ public NyARColorPatt_Base(int i_width, int i_height) { //入力制限 Debug.Assert(i_width <= 64 && i_height <= 64); this._size = new NyARIntSize(i_width, i_height); this._patdata = new int[i_height * i_width]; this._pixelreader = NyARRgbPixelDriverFactory.createDriver(this); return; }
private void initializeInstance(int i_width, int i_height,int i_point_per_pix) { Debug.Assert(i_width>2 && i_height>2); this._resolution=i_point_per_pix; this._size=new NyARIntSize(i_width,i_height); this._patdata = new int[i_height*i_width]; this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size); return; }
/** * 共通初期化関数。 * @param i_param * @param i_drv_factory * ラスタドライバのファクトリ。 * @param i_gs_type * @param i_rgb_type * @return * @ */ private void initInstance(NyARIntSize i_size) { //リソースの生成 this.initResource(i_size); this._gs_hist = new NyARHistogram(256); this._src_ts = 0; this._gs_id_ts = 0; this._gs_hist_ts = 0; }
private void initInstance(int i_width, int i_height, int i_point_per_pix) { Debug.Assert(i_width > 2 && i_height > 2); this._sample_per_pixel = i_point_per_pix; this._size = new NyARIntSize(i_width, i_height); this._patdata = new int[i_height * i_width]; this._pixelreader = NyARRgbPixelDriverFactory.createDriver(this); return; }
public override void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) { Debug. Assert( i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] out_buf = (int[]) i_output.getBuffer(); int[] in_buf = (int[]) i_input.getBuffer(); for(int i=i_size.h*i_size.w-1;i>=0;i--) { out_buf[i]=this._table_ref[in_buf[i]]; } return; }
protected bool initInstance(NyARIntSize i_size,int i_buf_type,bool i_is_alloc) { switch(i_buf_type) { case NyARBufferType.INT1D_GRAY_8: this._buf =i_is_alloc?new int[i_size.w*i_size.h]:null; break; default: return false; } this._is_attached_buffer=i_is_alloc; return true; }
public Coord2Linear(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref) { //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。 //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。 this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size); // 輪郭バッファ this._pca=new NyARPca2d_MatrixPCA_O2(); this._xpos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height this._ypos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height return; }
/* * この関数は、インスタンスの初期化シーケンスを実装します。 * コンストラクタから呼び出します。 * @param i_size * ラスタのサイズ * @param i_buf_type * バッファ形式定数 * @param i_is_alloc * 内部バッファ/外部バッファのフラグ * @return * 初期化に成功するとtrue * @ */ protected override void initInstance(NyARIntSize i_size, int i_buf_type, bool i_is_alloc) { switch (i_buf_type) { case NyARBufferType.INT1D_BIN_8: this._buf = i_is_alloc ? new int[i_size.w * i_size.h] : null; break; default: base.initInstance(i_size, i_buf_type, i_is_alloc); return; } this._pixdrv = NyARGsPixelDriverFactory.createDriver(this); this._is_attached_buffer = i_is_alloc; return; }
public void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) { Debug.Assert(i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr = (int[])i_input.getBuffer(); int[] out_ptr = (int[])i_output.getBuffer(); int number_of_pixel = i_size.h * i_size.w; for (int i = 0; i < number_of_pixel; i++) { out_ptr[i] = 255 - in_ptr[i]; } return; }
public pickFromRaster_N(NyARIntPoint2d i_lt, int i_resolution, NyARIntSize i_source_size) { this._lt_ref = i_lt; this._resolution = i_resolution; this._size_ref = i_source_size; this._rgb_temp = new int[i_resolution * i_resolution * 3]; this._rgb_px = new int[i_resolution * i_resolution]; this._rgb_py = new int[i_resolution * i_resolution]; this._cp1cy_cp2 = new double[i_resolution]; this._cp4cy_cp5 = new double[i_resolution]; this._cp7cy_1 = new double[i_resolution]; 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; }
/** * 最大i_squre_max個のマーカーを検出するクラスを作成する。 * * @param i_param */ public NyARSquareContourDetector_ARToolKit(NyARIntSize i_size) { this._width = i_size.w; this._height = i_size.h; this._labeling = new NyARLabeling_ARToolKit(); this._limage = new NyARLabelingImage(this._width, this._height); // 輪郭の最大長は画面に映りうる最大の長方形サイズ。 int number_of_coord = (this._width + this._height) * 2; // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。 this._max_coord = number_of_coord; this._xcoord = new int[number_of_coord]; this._ycoord = new int[number_of_coord]; return; }
/** * This function is not optimized. */ public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) { Debug.Assert(i_input.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24)); Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] out_buf = (int[]) i_output.getBuffer(); byte[] in_buf = (byte[]) i_input.getBuffer(); int bp = 0; for (int y = 0; y < i_size.h; y++){ for (int x = 0; x < i_size.w; x++){ out_buf[y*i_size.w+x]=(306*(in_buf[bp+2] & 0xff)+601*(in_buf[bp + 1] & 0xff)+117 * (in_buf[bp + 0] & 0xff))>>10; bp += 3; } } return; }
/** * 最大i_squre_max個のマーカーを検出するクラスを作成する。 * * @param i_param */ public NyARSquareDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) { this._width = i_size.w; this._height = i_size.h; this._dist_factor_ref = i_dist_factor_ref; this._labeling = new NyARLabeling_ARToolKit(); this._limage = new NyARLabelingImage(this._width, this._height); this._labeling.attachDestination(this._limage); // 輪郭の最大長は画面に映りうる最大の長方形サイズ。 int number_of_coord = (this._width + this._height) * 2; // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。 this._max_coord = number_of_coord; this._xcoord = new int[number_of_coord * 2]; this._ycoord = new int[number_of_coord * 2]; }
/** * Readerとbufferを初期化する関数です。コンストラクタから呼び出します。 * 継承クラスでこの関数を拡張することで、対応するバッファタイプの種類を増やせます。 * @param i_size * ラスタのサイズ * @param i_raster_type * バッファタイプ * @param i_is_alloc * 外部参照/内部バッファのフラグ * @return * 初期化が成功すると、trueです。 * @ */ protected override void initInstance(NyARIntSize i_size, int i_raster_type, bool i_is_alloc) { //バッファの構築 switch (i_raster_type) { case NyARBufferType.OBJECT_CS_Unity: this._buf = i_is_alloc?new Color32[i_size.w*i_size.h]:null; this._rgb_pixel_driver = new NyARRgbPixelDriver_CsUnity(); this._rgb_pixel_driver.switchRaster(this); this._is_attached_buffer = i_is_alloc; break; default: base.initInstance(i_size,i_raster_type,i_is_alloc); return; } //readerの構築 return; }
/** * 最大i_squre_max個のマーカーを検出するクラスを作成する。 * * @param i_param */ public NyARSquareContourDetector_Rle(NyARIntSize i_size) { this._width = i_size.w; this._height = i_size.h; //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。 this._labeling = new NyARLabeling_Rle(this._width, this._height); this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN); this._stack = new RleLabelFragmentInfoStack(i_size.w * i_size.h * 2048 / (320 * 240) + 32);//検出可能な最大ラベル数 // 輪郭の最大長は画面に映りうる最大の長方形サイズ。 int number_of_coord = (this._width + this._height) * 2; // 輪郭バッファ this._max_coord = number_of_coord; this._xcoord = new int[number_of_coord]; this._ycoord = new int[number_of_coord]; return; }
public NyARObserv2IdealMap(NyARCameraDistortionFactor i_distfactor, NyARIntSize i_screen_size) { NyARDoublePoint2d opoint = new NyARDoublePoint2d(); this._mapx = new double[i_screen_size.w * i_screen_size.h]; this._mapy = new double[i_screen_size.w * i_screen_size.h]; this._stride = i_screen_size.w; int ptr = i_screen_size.h * i_screen_size.w - 1; //歪みマップを構築 for (int i = i_screen_size.h - 1; i >= 0; i--) { for (int i2 = i_screen_size.w - 1; i2 >= 0; i2--) { i_distfactor.observ2Ideal(i2, i, opoint); this._mapx[ptr] = opoint.x; this._mapy[ptr] = opoint.y; ptr--; } } return; }
public NyARFixedFloatObserv2IdealMap(NyARCameraDistortionFactor i_distfactor, NyARIntSize i_screen_size) { NyARDoublePoint2d opoint = new NyARDoublePoint2d(); this._mapx = new int[i_screen_size.w * i_screen_size.h]; this._mapy = new int[i_screen_size.w * i_screen_size.h]; this._stride = i_screen_size.w; int ptr = i_screen_size.h * i_screen_size.w - 1; //歪みマップを構築 for (int i = i_screen_size.h - 1; i >= 0; i--) { for (int i2 = i_screen_size.w - 1; i2 >= 0; i2--) { i_distfactor.observ2Ideal(i2, i, opoint); this._mapx[ptr] = (int)(opoint.x * 65536); this._mapy[ptr] = (int)(opoint.y * 65536); ptr--; } } i_distfactor.getValue(this._factor); return; }
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; }
/** * この関数は、ARToolKitスタイルのProjectionMatrixから、 CameraFrustamを計算します。 * @param i_promat * @param i_size * スクリーンサイズを指定します。 * @param i_scale * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 * @param i_near * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 * @param i_far * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 * @param o_gl_projection * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。 */ public static void toCameraFrustumRH(NyARPerspectiveProjectionMatrix i_promat,NyARIntSize i_size,double i_scale,double i_near,double i_far,ref Matrix4x4 o_mat) { NyARDoubleMatrix44 m=new NyARDoubleMatrix44(); i_promat.makeCameraFrustumRH(i_size.w,i_size.h,i_near*i_scale,i_far*i_scale,m); o_mat.m00=(float)m.m00; o_mat.m01=(float)m.m01; o_mat.m02=(float)m.m02; o_mat.m03=(float)m.m03; o_mat.m10=(float)m.m10; o_mat.m11=(float)m.m11; o_mat.m12=(float)m.m12; o_mat.m13=(float)m.m13; o_mat.m20=(float)m.m20; o_mat.m21=(float)m.m21; o_mat.m22=(float)m.m22; o_mat.m23=(float)m.m23; o_mat.m30=(float)m.m30; o_mat.m31=(float)m.m31; o_mat.m32=(float)m.m32; o_mat.m33=(float)m.m33; return; }
public static INyARGrayscaleRaster createInstance(NyARIntSize i_size) { return(NyARGrayscaleRaster.createInstance(i_size.w, i_size.h, true)); }
/** * この関数は、ラスタをラべリングします。 * 結果は、o_destinationに出力します。 * <p>メモ - * この関数の元になるARToolKitの関数は、static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )です。 * </p> * @param i_raster * 入力元の二値ラスタオブジェクトです。画素形式は、{@link NyARBufferType#INT1D_BIN_8}である必要があります。 * @param o_destination * ラべリング画像の出力先オブジェクトです。i_rasterと同じサイズである必要があります。 * @ */ public int labeling(INyARBinRaster i_raster, NyARLabelingImage o_destination) { Debug.Assert(i_raster.getBufferType() == NyARBufferType.INT1D_BIN_8); int label_img_ptr1, label_pixel; int i, j; int n, k; /* work */ // サイズチェック NyARIntSize in_size = i_raster.getSize(); Debug.Assert(o_destination.getSize().isEqualSize(in_size)); int lxsize = in_size.w; // lxsize = arUtil_c.arImXsize; int lysize = in_size.h; // lysize = arUtil_c.arImYsize; int[] label_img = (int[])o_destination.getBuffer(); // 枠作成はインスタンスを作った直後にやってしまう。 // ラベリング情報のリセット(ラベリングインデックスを使用) o_destination.reset(true); int[] label_idxtbl = o_destination.getIndexArray(); int[] raster_buf = (int[])i_raster.getBuffer(); int[] work2_pt; int wk_max = 0; int pixel_index; int[][] work2 = this._work_holder.work2; // [1,1](ptr0)と、[0,1](ptr1)のインデクス値を計算する。 for (j = 1; j < lysize - 1; j++) { // for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) { pixel_index = j * lxsize + 1; label_img_ptr1 = pixel_index - lxsize; // label_img_pt1 = label_img[j - 1]; for (i = 1; i < lxsize - 1; i++, pixel_index++, label_img_ptr1++) { // for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) { // RGBの合計値が閾値より小さいかな? if (raster_buf[pixel_index] != 0) { label_img[pixel_index] = 0;// label_img_pt0[i] = 0;// *pnt2 = 0; } else { // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]); if (label_img[label_img_ptr1] > 0) { // if (label_img_pt1[i] > 0) {// if( *pnt1 > 0 ) { label_pixel = label_img[label_img_ptr1]; // label_pixel = label_img_pt1[i];// *pnt2 = *pnt1; work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; work2_pt[6] = j; // work2[((*pnt2)-1)*7+6] = j; } else if (label_img[label_img_ptr1 + 1] > 0) { // } else if (label_img_pt1[i + 1] > 0) {// }else if(*(pnt1+1) > 0 ) { if (label_img[label_img_ptr1 - 1] > 0) { // if (label_img_pt1[i - 1] > 0) {// if( *(pnt1-1) > 0 ) { label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1]; // m = label_idxtbl[label_img_pt1[i + 1] - 1];// m // =work[*(pnt1+1)-1]; n = label_idxtbl[label_img[label_img_ptr1 - 1] - 1]; // n = label_idxtbl[label_img_pt1[i - 1] - 1];// n =work[*(pnt1-1)-1]; if (label_pixel > n) { // wk=IntPointer.wrap(work, 0);//wk = &(work[0]); for (k = 0; k < wk_max; k++) { if (label_idxtbl[k] == label_pixel) { // if( *wk == m ) label_idxtbl[k] = n; // *wk = n; } } label_pixel = n;// *pnt2 = n; } else if (label_pixel < n) { // wk=IntPointer.wrap(work,0);//wk = &(work[0]); for (k = 0; k < wk_max; k++) { if (label_idxtbl[k] == n) { // if( *wk == n ){ label_idxtbl[k] = label_pixel; // *wk = m; } } } work2_pt = work2[label_pixel - 1]; work2_pt[0]++; work2_pt[1] += i; work2_pt[2] += j; work2_pt[6] = j; } else if ((label_img[pixel_index - 1]) > 0) { // } else if ((label_img_pt0[i - 1]) > 0) {// }else if(*(pnt2-1) > 0) { label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1]; // m = label_idxtbl[label_img_pt1[i + 1] - 1];// m =work[*(pnt1+1)-1]; n = label_idxtbl[label_img[pixel_index - 1] - 1]; // n = label_idxtbl[label_img_pt0[i - 1] - 1];// n =work[*(pnt2-1)-1]; if (label_pixel > n) { for (k = 0; k < wk_max; k++) { if (label_idxtbl[k] == label_pixel) { // if( *wk == m ){ label_idxtbl[k] = n; // *wk = n; } } label_pixel = n;// *pnt2 = n; } else if (label_pixel < n) { for (k = 0; k < wk_max; k++) { if (label_idxtbl[k] == n) { // if( *wk == n ){ label_idxtbl[k] = label_pixel; // *wk = m; } } } work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; } else { label_pixel = label_img[label_img_ptr1 + 1];// label_pixel = label_img_pt1[i + 1];// *pnt2 = // *(pnt1+1); work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; if (work2_pt[3] > i) { // if(work2[((*pnt2)-1)*7+3] > i ){ work2_pt[3] = i; // work2[((*pnt2)-1)*7+3] = i; } work2_pt[6] = j; // work2[((*pnt2)-1)*7+6] = j; } } else if ((label_img[label_img_ptr1 - 1]) > 0) { // } else if ((label_img_pt1[i - 1]) > 0) {// }else if( // *(pnt1-1) > 0 ) { label_pixel = label_img[label_img_ptr1 - 1]; // label_pixel = label_img_pt1[i - 1];// *pnt2 = // *(pnt1-1); work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; if (work2_pt[4] < i) { // if( work2[((*pnt2)-1)*7+4] <i ){ work2_pt[4] = i; // work2[((*pnt2)-1)*7+4] = i; } work2_pt[6] = j; // work2[((*pnt2)-1)*7+6] = j; } else if (label_img[pixel_index - 1] > 0) { // } else if (label_img_pt0[i - 1] > 0) {// }else if(*(pnt2-1) > 0) { label_pixel = label_img[pixel_index - 1]; // label_pixel = label_img_pt0[i - 1];// *pnt2 =*(pnt2-1); work2_pt = work2[label_pixel - 1]; work2_pt[0]++; // work2[((*pnt2)-1)*7+0] ++; work2_pt[1] += i; // work2[((*pnt2)-1)*7+1] += i; work2_pt[2] += j; // work2[((*pnt2)-1)*7+2] += j; if (work2_pt[4] < i) { // if( work2[((*pnt2)-1)*7+4] <i ){ work2_pt[4] = i; // work2[((*pnt2)-1)*7+4] = i; } } else { // 現在地までの領域を予約 this._work_holder.reserv(wk_max); wk_max++; label_idxtbl[wk_max - 1] = wk_max; label_pixel = wk_max;// work[wk_max-1] = *pnt2 = wk_max; work2_pt = work2[wk_max - 1]; work2_pt[0] = 1; work2_pt[1] = i; work2_pt[2] = j; work2_pt[3] = i; work2_pt[4] = i; work2_pt[5] = j; work2_pt[6] = j; } label_img[pixel_index] = label_pixel;// label_img_pt0[i] = label_pixel; } } } // インデックステーブルとラベル数の計算 int wlabel_num = 1;// *label_num = *wlabel_num = j - 1; for (i = 0; i < wk_max; i++) { // for(int i = 1; i <= wk_max; i++,wk++) { label_idxtbl[i] = (label_idxtbl[i] == i + 1) ? wlabel_num++ : label_idxtbl[label_idxtbl[i] - 1]; // *wk=(*wk==i)?j++:work[(*wk)-1]; } wlabel_num -= 1; // *label_num = *wlabel_num = j - 1; if (wlabel_num == 0) { // if( *label_num == 0 ) { // 発見数0 o_destination.getLabelStack().clear(); return(0); } // ラベル情報の保存等 NyARLabelingLabelStack label_list = o_destination.getLabelStack(); // ラベルバッファを予約 label_list.init(wlabel_num); // エリアと重心、クリップ領域を計算 NyARLabelingLabel label_pt; NyARLabelingLabel[] labels = label_list.getArray(); for (i = 0; i < wlabel_num; i++) { label_pt = labels[i]; label_pt.id = (short)(i + 1); label_pt.area = 0; label_pt.pos_x = label_pt.pos_y = 0; label_pt.clip_l = lxsize; // wclip[i*4+0] = lxsize; label_pt.clip_t = lysize; // wclip[i*4+2] = lysize; label_pt.clip_r = label_pt.clip_b = 0; // wclip[i*4+3] = 0; } for (i = 0; i < wk_max; i++) { label_pt = labels[label_idxtbl[i] - 1]; work2_pt = work2[i]; label_pt.area += work2_pt[0]; label_pt.pos_x += work2_pt[1]; label_pt.pos_y += work2_pt[2]; if (label_pt.clip_l > work2_pt[3]) { label_pt.clip_l = work2_pt[3]; } if (label_pt.clip_r < work2_pt[4]) { label_pt.clip_r = work2_pt[4]; } if (label_pt.clip_t > work2_pt[5]) { label_pt.clip_t = work2_pt[5]; } if (label_pt.clip_b < work2_pt[6]) { label_pt.clip_b = work2_pt[6]; } } for (i = 0; i < wlabel_num; i++) {// for(int i = 0; i < *label_num; i++ ) { label_pt = labels[i]; label_pt.pos_x /= label_pt.area; label_pt.pos_y /= label_pt.area; } return(wlabel_num); }
/** * 継承クラスから使うコンストラクタです。 * 引数に有効な値を設定してください。 * @param i_size * @param i_is_alloc */ protected NyARGrayscaleRaster(int i_width, int i_height, bool i_is_alloc) { this._size = new NyARIntSize(i_width, i_height); this._is_attached_buffer = i_is_alloc; }
public void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) { Debug.Assert(i_input.isEqualBufferType(NyARBufferType.INT1D_X7H9S8V8_32)); int[] out_buf = (int[])i_output.getBuffer(); byte[] in_buf = (byte[])i_input.getBuffer(); int s; for (int i = i_size.h * i_size.w - 1; i >= 0; i--) { int r = (in_buf[i * 3 + 2] & 0xff); int g = (in_buf[i * 3 + 1] & 0xff); int b = (in_buf[i * 3 + 0] & 0xff); int cmax, cmin; //最大値と最小値を計算 if (r > g) { cmax = r; cmin = g; } else { cmax = g; cmin = r; } if (b > cmax) { cmax = b; } if (b < cmin) { cmin = b; } int h; if (cmax == 0) { s = 0; h = 0; } else { s = (cmax - cmin) * 255 / cmax; int cdes = cmax - cmin; //H成分を計算 if (cdes != 0) { if (cmax == r) { h = (g - b) * 60 / cdes; } else if (cmax == g) { h = (b - r) * 60 / cdes + 2 * 60; } else { h = (r - g) * 60 / cdes + 4 * 60; } } else { h = 0; } } if (h < 0) { h += 360; } //hsv変換(h9s8v8) out_buf[i] = (0x1ff0000 & (h << 16)) | (0x00ff00 & (s << 8)) | (cmax & 0xff); } return; }
/** * コンストラクタです。 * @param i_width * ラスタの幅に設定する値 * @param i_height * ラスタの高さに設定する値 * @param i_buffer_type * バッファタイプ値に設定する値 */ protected NyARRgbRaster_BasicClass(int i_width, int i_height, int i_buffer_type) { this._size = new NyARIntSize(i_width, i_height); this._buffer_type = i_buffer_type; }
/** * N個の基準点から、最もテンプレートに一致した座標を返却する。 * 検索範囲は、{@link #setSearchArea}で与えたpx,pyについて、xn+i_px>=xn>=xn-i_px,yn+i_py>=yn>=yn-i_pyの矩形範囲。 * i_pointsそれぞれについて検索する。 * @param i_template * 探索範囲。単三区店を中心に、 * @param ry * @param i_points * 検索する座標セット。(近い場所の場合に、同一条件の探索をキャンセルできる?) * @param o_obs_point * 観察座標系での一致点。returnが0の場合は無効。 * @return * 一致率(値範囲調査中) * 0の場合は一致せず。 * @throws NyARException */ public double ar2GetBestMatching(NyARTemplatePatchImage i_template, NyARIntPoint2d[] i_points, int i_number_of_point, NyARDoublePoint2d o_obs_point) { //最大テンプレートサイズの制限 Debug.Assert(i_template.xsize * i_template.ysize < 100 * 100); //NULLピクセルを持つテンプレートか判定する。 bool is_full_template = i_template.xsize * i_template.ysize == i_template.valid_pixels; NyARIntSize s = this._i_ref_raster.getSize(); int yts = i_template.yts; int xts = i_template.xts; int[] sbuf = (int[])this._i_ref_raster.getBuffer(); //パッチの探索 int ret = 1; int sw = this._search_area.x; int sh = this._search_area.y; //パッチエリアの初期化 for (int ii = i_number_of_point - 1; ii >= 0; ii--) { if (i_points[ii].y < 0) { break; } // 検索するパッチ中心を決定 int px = (i_points[ii].x / (SKIP_INTERVAL + 1)) * (SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1) / 2; int py = (i_points[ii].y / (SKIP_INTERVAL + 1)) * (SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1) / 2; //検索範囲を画面内に制限 int search_left = px - sw; if (search_left < 0) { search_left = 0; } int search_right = px + sw; // if( ex >= xsize ) ex = xsize-1; if (search_right >= s.w) { search_right = s.w - 1; } int search_top = py - sh; if (search_top < 0) { search_top = 0; } int search_bottom = py + sh; if (search_bottom >= s.h) { search_bottom = s.h - 1; } //利用するパッチエリアの初期化 initWorkArea(search_left, search_top, search_right, search_bottom); } MatchingCandidateList ml = this.__ml; ml.init(); for (int ii = i_number_of_point - 1; ii >= 0; ii--) { if (i_points[ii].x < 0) { // if( ret ){ if (ret != 0) { return(-1); } else { break; } } int px = (i_points[ii].x / (SKIP_INTERVAL + 1)) * (SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1) / 2; int py = (i_points[ii].y / (SKIP_INTERVAL + 1)) * (SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1) / 2; for (int j = py - sh; j <= py + sh; j += SKIP_INTERVAL + 1) { if (j - yts * NyARTemplatePatchImage.AR2_TEMP_SCALE < 0) { continue; } // if( j + yts2*AR2_TEMP_SCALE >= ysize ){ if (j + yts * NyARTemplatePatchImage.AR2_TEMP_SCALE >= s.h) { break; } for (int i = px - sw; i <= px + sw; i += SKIP_INTERVAL + 1) { if (i - xts * NyARTemplatePatchImage.AR2_TEMP_SCALE < 0) { continue; } // if( i + mtemp.xts2*AR2_TEMP_SCALE >= xsize ){ if (i + xts * NyARTemplatePatchImage.AR2_TEMP_SCALE >= s.w) { break; } // 既に検出済のエリア? if (this._mbuf[i + j * s.w] != 0) { // mfImage[j*xsize+i] ){ continue; } this._mbuf[i + j * s.w] = 1;//ii番目のパッチで検索済みをマーク int wval = is_full_template ? ar2GetBestMatchingSubFineFull(sbuf, s.w, i_template, i, j) : ar2GetBestMatchingSubFine(sbuf, s.w, i_template, i, j); if (wval <= 0) { continue; } //ログへ追加 ml.tryToAdd(i, j, wval); ret = 0; } } } double ret_sim = 0; //一番スコアの良いパッチを得る int wval2 = 0; ret = -1; for (int l = ml.num_of_item - 1; l >= 0; l--) { for (int j = ml.items[l].y - SKIP_INTERVAL; j <= ml.items[l].y + SKIP_INTERVAL; j++) { if (j - i_template.yts * NyARTemplatePatchImage.AR2_TEMP_SCALE < 0) { continue; } // if( j+mtemp.yts2*AR2_TEMP_SCALE >= ysize ){ if (j + i_template.yts * NyARTemplatePatchImage.AR2_TEMP_SCALE >= s.h) { break; } for (int i = ml.items[l].x - SKIP_INTERVAL; i <= ml.items[l].x + SKIP_INTERVAL; i++) { if (i - xts * NyARTemplatePatchImage.AR2_TEMP_SCALE < 0) { continue; } // if( i+mtemp.xts2*AR2_TEMP_SCALE >= xsize ){ if (i + xts * NyARTemplatePatchImage.AR2_TEMP_SCALE >= s.w) { break; } int wval = is_full_template ? ar2GetBestMatchingSubFineFull(sbuf, s.w, i_template, i, j) : ar2GetBestMatchingSubFine(sbuf, s.w, i_template, i, j); if (wval <= 0) { continue; } if (wval > wval2) { o_obs_point.x = i; o_obs_point.y = j; wval2 = wval; ret_sim = (double)wval / 10000; ret = 0; } } } } return(ret_sim); }
/** * コンストラクタです。 * 内部参照のバッファ({@link NyARBufferType#INT1D_GRAY_8}形式)を持つインスタンスを生成します。 * @param i_width * ラスタのサイズ * @param i_height * ラスタのサイズ * @ */ public NyARGrayscaleRaster(int i_width, int i_height) { this._size = new NyARIntSize(i_width, i_height); this._buffer_type = NyARBufferType.INT1D_GRAY_8; initInstance(this._size, NyARBufferType.INT1D_GRAY_8, true); }
public NyARRgbPixelReader_BYTE1D_B8G8R8X8_32(byte[] i_ref_buf, NyARIntSize i_size) { this._ref_buf = i_ref_buf; this._ref_size = i_size; }
/** * この関数は、ラスタを敷居値i_thで2値化して、ラベリングします。 * 検出したラベルは、自己コールバック関数{@link #onLabelFound}で通知します。 * @param i_bin_raster * 入力画像。対応する形式は、クラスの説明を参照してください。 * @param i_th * 敷居値を指定します。2値画像の場合は、0を指定してください。 * @ */ public virtual bool labeling(INyARGrayscaleRaster i_raster, int i_th) { NyARIntSize size = i_raster.getSize(); return(this.imple_labeling(i_raster, i_th, 0, 0, size.w, size.h)); }
public KpmImage(int i_width, int i_height) { this._size = new NyARIntSize(i_width, i_height); this._buf = new double[i_width * i_height]; }
public void convertRect(int l, int t, int w, int h, INyARGrayscaleRaster o_raster) { NyARIntSize size = this._ref_raster.getSize(); int bp = (l + t * size.w) * 3; int b = t + h; int row_padding_dst = (size.w - w); int row_padding_src = row_padding_dst * 3; int pix_count = w; int pix_mod_part = pix_count - (pix_count % 8); int dst_ptr = t * size.w + l; byte[] in_buf = (byte[])this._ref_raster.getBuffer(); switch (o_raster.getBufferType()) { case NyARBufferType.INT1D_GRAY_8: int[] out_buf = (int[])o_raster.getBuffer(); for (int y = t; y < b; y++) { int x = 0; for (x = pix_count - 1; x >= pix_mod_part; x--) { out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; } for (; x >= 0; x -= 8) { out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; out_buf[dst_ptr++] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3; bp += 3; } bp += row_padding_src; dst_ptr += row_padding_dst; } return; default: INyARGsPixelDriver out_drv = o_raster.getGsPixelDriver(); for (int y = t; y < b; y++) { for (int x = 0; x < pix_count; x++) { out_drv.setPixel(x, y, ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3); bp += 3; } bp += row_padding_src; } return; } }
/** * ストリームから読み出したデータでインスタンスを初期化します。 * @param i_stream * @throws NyARException */ public ParamLoader(StreamReader i_stream) { try { //読み出し ByteBufferedInputStream bis = new ByteBufferedInputStream(i_stream, 512); int s = bis.readToBuffer(512); bis.order(ByteBufferedInputStream.ENDIAN_BIG); //読み出したサイズでバージョンを決定 int[] version_table = { 136, 144, 152, 176 }; int version = -1; for (int i = 0; i < version_table.Length; i++) { if (s % version_table[i] == 0) { version = i + 1; break; } } //一致しなければ無し if (version == -1) { throw new NyARException(); } //size this.size = new NyARIntSize(); this.size.setValue(bis.getInt(), bis.getInt()); //projection matrix this.pmat = new NyARPerspectiveProjectionMatrix(); double[] pjv = new double[16]; for (int i = 0; i < 12; i++) { pjv[i] = bis.getDouble(); } pjv[12] = pjv[13] = pjv[14] = 0; pjv[15] = 1; this.pmat.setValue(pjv); //dist factor double[] df; switch (version) { case 1: //Version1 df = new double[NyARCameraDistortionFactorV2.NUM_OF_FACTOR]; this.dist_factor = new NyARCameraDistortionFactorV2(); break; case 4: //Version4 df = new double[NyARCameraDistortionFactorV4.NUM_OF_FACTOR]; this.dist_factor = new NyARCameraDistortionFactorV4(); break; default: throw new NyARException(); } for (int i = 0; i < df.Length; i++) { df[i] = bis.getDouble(); } this.dist_factor.setValue(df); } catch (Exception e) { throw new NyARException(e); } }
public NyARParam(NyARIntSize i_screen_size, NyARPerspectiveProjectionMatrix i_projection_mat, INyARCameraDistortionFactor i_dist_factor) { this._screen_size = new NyARIntSize(i_screen_size); this._dist = i_dist_factor; this._projection_matrix = i_projection_mat; }
public NyARRgbPixelReader_WORD1D_R5G6B5_16LE(short[] i_buf, NyARIntSize i_size) { this._ref_buf = i_buf; this._size = i_size; }
public void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) { Debug.Assert(i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr = (int[])i_input.getBuffer(); int[] out_ptr = (int[])i_output.getBuffer(); int width = i_size.w; int height = i_size.h; int col0, col1, col2; int bptr = 0; //1行目 col1 = in_ptr[bptr] * 2 + in_ptr[bptr + width]; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col1 * 2 + col2) / 9; bptr++; for (int x = 0; x < width - 2; x++) { col0 = col1; col1 = col2; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col0 + col1 * 2 + col2) / 12; bptr++; } out_ptr[bptr] = (col1 + col2) / 9; bptr++; //2行目-末行-1 for (int y = 0; y < height - 2; y++) { //左端 col1 = in_ptr[bptr] * 2 + in_ptr[bptr - width] + in_ptr[bptr + width]; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1] + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col1 + col2) / 12; bptr++; for (int x = 0; x < width - 2; x++) { col0 = col1; col1 = col2; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1] + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col0 + col1 * 2 + col2) / 16; bptr++; } //右端 out_ptr[bptr] = (col1 * 2 + col2) / 12; bptr++; } //末行目 col1 = in_ptr[bptr] * 2 + in_ptr[bptr - width]; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1]; out_ptr[bptr] = (col1 + col2) / 9; bptr++; for (int x = 0; x < width - 2; x++) { col0 = col1; col1 = col2; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1]; out_ptr[bptr] = (col0 + col1 * 2 + col2) / 12; bptr++; } out_ptr[bptr] = (col1 * 2 + col2) / 9; bptr++; return; }
/** * この関数は、遠近法のパラメータを計算して、返却します。 * @param i_size * 変換先の矩形のサイズを指定します。 * @param i_vertex * 変換元の頂点を指定します。要素数は4でなければなりません。 * @param o_param * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。 * @return * 成功するとtrueを返します。 * @ */ public bool getParam(NyARIntSize i_size, NyARDoublePoint2d[] i_vertex, double[] o_param) { return this.getParam(i_size.w, i_size.h, i_vertex[0].x, i_vertex[0].y, i_vertex[1].x, i_vertex[1].y, i_vertex[2].x, i_vertex[2].y, i_vertex[3].x, i_vertex[3].y, o_param); }
public void doThFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) { Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_BIN_8)); int[] out_buf = (int[])i_output.getBuffer(); byte[] in_buf = (byte[])i_input.getBuffer(); byte[] grey = new byte[i_size.w * i_size.h]; ulong[] integralImg = new ulong[i_size.w * i_size.h]; ulong sum = 0; float T = 0.15f; double s = i_size.w / 8; int x1, x2, y1, y2; int index, s2 = (int)(s / 2); int count = 0; // greyscale for (int i = 0, j = 0; i < in_buf.Length;) { grey[j++] = (byte) ((in_buf[i + 1] & 0xff) * 0.11 + // b (in_buf[i + 2] & 0xff) * 0.59 + // g (in_buf[i + 3] & 0xff) * 0.3); // r i += 4; // skip alpha } // integral image for (int i = 0; i < i_size.w; i++) { sum = 0; // cumulative row sum for (int j = 0; j < i_size.h; j++) { index = j * i_size.w + i; sum += grey[index]; if (i == 0) { integralImg[index] = (ulong)sum; } else { integralImg[index] = integralImg[index - 1] + (ulong)sum; } } } for (int i = 0; i < i_size.w; i++) { for (int j = 0; j < i_size.h; j++) { index = j * i_size.w + i; // set the SxS region x1 = i - s2; x2 = i + s2; y1 = j - s2; y2 = j + s2; // check the border if (x1 < 0) { x1 = 0; } if (x2 >= i_size.w) { x2 = i_size.w - 1; } if (y1 < 0) { y1 = 0; } if (y2 >= i_size.h) { y2 = i_size.h - 1; } count = (x2 - x1) * (y2 - y1); sum = integralImg[y2 * i_size.w + x2] - integralImg[y1 * i_size.w + x2] - integralImg[y2 * i_size.w + x1] + integralImg[y1 * i_size.w + x1]; if ((long)(grey[index] * count) < (long)(sum * (1.0 - T))) { out_buf[index] = 0; } else { out_buf[index] = 1; } } } return; }
public void switchRaster(INyARRgbRaster i_raster) { this._ref_raster = (NyARBitmapRaster)i_raster; this._ref_size = i_raster.getSize(); }
/** * コンストラクタです。 * 画像のサイズパラメータとバッファ形式を指定して、インスタンスを生成します。 * @param i_width * ラスタのサイズ * @param i_height * ラスタのサイズ * @param i_raster_type * ラスタのバッファ形式。 * {@link NyARBufferType}に定義された定数値を指定してください。指定できる値は、以下の通りです。 * <ul> * <li>{@link NyARBufferType#INT1D_GRAY_8} * <ul> * @param i_is_alloc * バッファを外部参照にするかのフラグ値。 * trueなら内部バッファ、falseなら外部バッファを使用します。 * falseの場合、初期のバッファはnullになります。インスタンスを生成したのちに、{@link #wrapBuffer}を使って割り当ててください。 * @ */ public NyARGrayscaleRaster(int i_width, int i_height, int i_raster_type, bool i_is_alloc) { this._size = new NyARIntSize(i_width, i_height); this._buffer_type = i_raster_type; initInstance(this._size, i_raster_type, i_is_alloc); }
/** * コンストラクタです。 * 差分画像のサイズを指定して、インスタンスを生成します。 * @param i_width * 差分画像のサイズ * @param i_height * 差分画像のサイズ */ public NyARMatchPattDeviationColorData(int i_width, int i_height) { this._size = new NyARIntSize(i_width, i_height); this._data = new int[this._size.w * this._size.h * 3]; return; }
public void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) { throw new NyARException(); }
public NyARRgbPixelReader_INT1D_GRAY_8(int[] i_buf, NyARIntSize i_size) { this._ref_buf = i_buf; this._size = i_size; }
public void doFilter(INyARGrayscaleRaster i_output) { Debug.Assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); NyARIntSize size = this._raster.getSize(); int[] in_ptr = (int[])this._raster.getBuffer(); switch (this._raster.getBufferType()) { case NyARBufferType.INT1D_GRAY_8: int[] out_ptr = (int[])i_output.getBuffer(); int width = size.w; int idx = 0; int idx2 = width; int fx, fy; int mod_p = (width - 2) - (width - 2) % 8; for (int y = size.h - 2; y >= 0; y--) { int p00 = in_ptr[idx++]; int p10 = in_ptr[idx2++]; int p01, p11; int x = width - 2; for (; x >= mod_p; x--) { p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; out_ptr[idx - 2] = ((fx < 0 ? -fx : fx) + (fy < 0 ? -fy : fy)) >> 1; p00 = p01; p10 = p11; } for (; x >= 0; x -= 4) { p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; out_ptr[idx - 2] = ((fx < 0 ? -fx : fx) + (fy < 0 ? -fy : fy)) >> 1; p00 = p01; p10 = p11; p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; out_ptr[idx - 2] = ((fx < 0 ? -fx : fx) + (fy < 0 ? -fy : fy)) >> 1; p00 = p01; p10 = p11; p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; out_ptr[idx - 2] = ((fx < 0 ? -fx : fx) + (fy < 0 ? -fy : fy)) >> 1; p00 = p01; p10 = p11; p01 = in_ptr[idx++]; p11 = in_ptr[idx2++]; fx = p11 - p00; fy = p10 - p01; out_ptr[idx - 2] = ((fx < 0 ? -fx : fx) + (fy < 0 ? -fy : fy)) >> 1; p00 = p01; p10 = p11; } out_ptr[idx - 1] = 0; } for (int x = width - 1; x >= 0; x--) { out_ptr[idx++] = 0; } return; default: //ANY未対応 throw new NyARException(); } }
public abstract void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size);
public void convert(INyARGrayscaleRaster i_raster) { NyARIntSize s = this._ref_raster.getSize(); this.convertRect(0, 0, s.w, s.h, i_raster); }
public void doFilter(int i_h, INyARGrayscaleRaster i_gsraster) { NyARIntSize s = this._raster.getSize(); this.doFilter(0, 0, s.w, s.h, i_h, i_gsraster); }
/** * i_rasiterの画像から、i_surfaceにマッチするパターンを検出して、その理想座標と3次元座標セットを返す。 * 検出した頂点セットは、o_pos2dとo_pos3dへ最大i_num個出力する。 * @param i_raster * 現在の画像 * @param i_surface * 検出すべきサーフェイスセット * @param i_trans * 現在の姿勢変換行列 * @param o_pos2d * 出力パラメータ。画面上の理想点。 * オブジェクトの配列を指定すること。 * @param o_pos3d * 出力パラメータ。三次元サーフェイス座標。 * オブジェクトの配列を指定すること。 * @param i_num * 返却数。この数値は、コンストラクタに与えた最大数以下である必要がある。o_pos2dとo_pos3dは、この数値より大きい配列でなければならない。 * @return * 検出した頂点セットの数。 * @throws NyARException */ public int tracking(INyARGrayscaleRaster i_raster, NyARSurfaceDataSet i_surface, NyARDoubleMatrix44 i_trans, NyARDoublePoint2d[] o_pos2d, NyARDoublePoint3d[] o_pos3d, int i_num) { //テンプレートドライバの更新 INyARTemplateMatchingDriver tmd; if (this._last_raster != i_raster) { tmd = this._last_driver = new NyARTemplateMatchingDriver_INT1D(i_raster, 12, 12); this._last_raster = i_raster; } else { tmd = this._last_driver; } //射影変換行列の計算とログへの追加 NyARSurfaceTransMatrixSet tlog = this._ctrans_log.preAdd(); tlog.setValue(this._ref_cparam.getPerspectiveProjectionMatrix(), i_trans); //可視な候補を選択する。(一時リスト) this._feature_selector.extractVisibleFeatures(i_surface.fset, tlog, this._candidate, this._candidate2); PatchImagePositions pcpoints = this.__pcpoints; //load screen size. NyARIntSize s = this._ref_cparam.getScreenSize(); //頂点選択クラス類の初期化 NyARSurfaceFeatureIndexSelector index_selecter = this.__index_selecter; NyARSurfaceFeaturesPtr selected_features = this.__selected_features; selected_features.clear(); //最大返却数の決定 int max_feature = i_num > this.__selected_features.getArraySize() ? this.__selected_features.getArraySize() : i_num; int num = 0; NyARSurfaceFeatures current_candidate = this._candidate; for (int i = max_feature - 1; i >= 0; i--) { //高精度を優先して探索。なければ低精度に切り替える。切替は1度だけ。出力は座標集合。 int k = index_selecter.ar2SelectTemplate(current_candidate, this._prev_selected_features, selected_features, s); if (k < 0) { if (current_candidate == this._candidate2) { break; } current_candidate = this._candidate2; //未選択なら終了 k = index_selecter.ar2SelectTemplate(current_candidate, this._prev_selected_features, selected_features, s); if (k < 0) { break; } } //候補kを確保 NyARSurfaceFeatureItem cai = current_candidate.getItem(k); //可視な点について、トラッキングするためのパッチ画像を生成 NyARTemplatePatchImage template_ = this.__template_patch; template_.makeFromReferenceImage((int)(cai.x + 0.5), (int)(cai.y + 0.5), tlog.ctrans, this._ref_cparam.getDistortionFactor(), i_surface.iset.items[cai.scale]); //パッチ画像の内容をチェック? if (template_.vlen * template_.vlen >= (template_.xsize) * (template_.ysize) * AR2_DEFALUT_TRACKING_SD_THRESH * AR2_DEFALUT_TRACKING_SD_THRESH) { //射影変換行列ログから候補点を作る。 int number_of_point = pcpoints.makeCandidatePos(cai, this._ctrans_log); //画像からテンプレートを検索 double sim = tmd.ar2GetBestMatching(template_, pcpoints.pos, number_of_point, o_pos2d[num]); //類似値が一定以上なら、保存 if (sim > this.simThresh) { if (selected_features.push(cai) == null) { break;//最大値に達したら終わり } this._ref_cparam.getDistortionFactor().observ2Ideal(o_pos2d[num], o_pos2d[num]); o_pos3d[num].x = cai.ref_feature.mx; o_pos3d[num].y = cai.ref_feature.my; o_pos3d[num].z = 0; //選択した得量を記録 num++; } } //選択された候補を取り外す。 current_candidate.remove(k); } // 過去ログへ記録 this._prev_selected_features.clear(); for (int i = 0; i < selected_features.getLength(); i++) { this._prev_selected_features.push(selected_features.getItem(i).ref_feature); } return(num); }
/** * インスタンスの状態をリセットする。 */ /** * o_posの状況に対応して、candidateから候補IDを選択します。 * @param candidate * @param prelog * @param o_pos * @param xsize * @param ysize * @return */ public int ar2SelectTemplate(NyARSurfaceFeatures candidate, NyARFeatureCoordPtrList prelog, NyARSurfaceFeaturesPtr o_pos, NyARIntSize i_screen_size) { switch (o_pos.getLength()) { case 0: return(select0(candidate, i_screen_size.w, i_screen_size.h)); case 1: return(select1(candidate, i_screen_size.w, i_screen_size.h, o_pos.getItem(0))); case 2: return(select2(candidate, i_screen_size.w, i_screen_size.h, o_pos.getItem(0), o_pos.getItem(1))); case 3: return(select3(candidate, i_screen_size.w, i_screen_size.h, o_pos.getItem(0), o_pos.getItem(1), o_pos.getItem(2))); default: return(selectHistory(candidate, prelog)); } }
public void changeScreenSize(NyARIntSize i_size) { this.changeScreenSize(i_size.w, i_size.w); return; }
/** * この関数は、遠近法のパラメータを計算して、返却します。 * @param i_size * 変換先の矩形のサイズを指定します。 * @param i_vertex * 変換元の頂点を指定します。要素数は4でなければなりません。 * @param o_param * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。 * @return * 成功するとtrueを返します。 * @ */ public bool getParam(NyARIntSize i_size, NyARIntPoint2d[] i_vertex, double[] o_param) { Debug.Assert(i_vertex.Length == 4); return(this.getParam(i_size.w, i_size.h, i_vertex[0].x, i_vertex[0].y, i_vertex[1].x, i_vertex[1].y, i_vertex[2].x, i_vertex[2].y, i_vertex[3].x, i_vertex[3].y, o_param)); }
/** * この関数は、遠近法のパラメータを計算して、返却します。 * @param i_size * 変換先の矩形のサイズを指定します。 * @param i_vertex * 変換元の頂点を指定します。要素数は4でなければなりません。 * @param o_param * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。 * @return * 成功するとtrueを返します。 * @ */ public bool getParam(NyARIntSize i_size, NyARIntPoint2d[] i_vertex, double[] o_param) { Debug.Assert(i_vertex.Length == 4); return this.getParam(i_size.w, i_size.h, i_vertex[0].x, i_vertex[0].y, i_vertex[1].x, i_vertex[1].y, i_vertex[2].x, i_vertex[2].y, i_vertex[3].x, i_vertex[3].y, o_param); }
/** * この関数は、遠近法のパラメータを計算して、返却します。 * @param i_size * 変換先の矩形のサイズを指定します。 * @param i_vertex * 変換元の頂点を指定します。要素数は4でなければなりません。 * @param o_param * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。 * @return * 成功するとtrueを返します。 * @ */ public bool getParam(NyARIntSize i_size, NyARDoublePoint2d[] i_vertex, double[] o_param) { return(this.getParam(i_size.w, i_size.h, i_vertex[0].x, i_vertex[0].y, i_vertex[1].x, i_vertex[1].y, i_vertex[2].x, i_vertex[2].y, i_vertex[3].x, i_vertex[3].y, o_param)); }
public NyARRgbPixelReader_INT1D_X8R8G8B8_32(int[] i_buf, NyARIntSize i_size) { this._ref_buf = i_buf; this._size = i_size; }
public double makeColorData(int[] o_out) { //i_buffer[XRGB]→差分[R,G,B]変換 int i; int rgb; //<PV/> //<平均値計算(FORの1/8展開)> int ave; //<PV/> int[] buf = (int[])(this._ref_raster.getBuffer()); NyARIntSize size = this._ref_raster.getSize(); int number_of_pix = size.w * size.h; int optimize_mod = number_of_pix - (number_of_pix % 8); ave = 0; for (i = number_of_pix - 1; i >= optimize_mod; i--) { rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); } for (; i >= 0;) { rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; rgb = buf[i]; ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff); i--; } //<平均値計算(FORの1/8展開)/> ave = number_of_pix * 255 * 3 - ave; ave = 255 - (ave / (number_of_pix * 3));//(255-R)-ave を分解するための事前計算 int sum = 0, w_sum; int input_ptr = number_of_pix * 3 - 1; //<差分値計算(FORの1/8展開)> for (i = number_of_pix - 1; i >= optimize_mod; i--) { rgb = buf[i]; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R } for (; i >= 0;) { rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //R rgb = buf[i]; i--; w_sum = (ave - (rgb & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //B w_sum = (ave - ((rgb >> 8) & 0xff)); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum; //G w_sum = (ave - ((rgb >> 16) & 0xff)); 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); }