Exemple #1
0
        /**
         * i_raster上にあるi_vertexの頂点で定義される四角形のパターンから、一致するID値を特定します。
         * @param i_vertex
         * 4頂点の座標
         * @param i_raster
         * @param o_result
         * @return
         * @throws NyARException
         */
        public bool identifyId(NyARDoublePoint2d[] i_vertex, INyARRgbRaster i_raster, IdentifyIdResult o_result)
        {
            if (this._last_laster != i_raster)
            {
                this._gs_pix_reader = NyARGsPixelDriverFactory.createDriver(i_raster);
                this._last_laster   = i_raster;
            }
            if (!this._id_pickup.pickFromRaster(this._gs_pix_reader, i_vertex, this._temp_nyid_info, this._temp_nyid_param))
            {
                return(false);
            }
            if (!this._rb.Encode(this._temp_nyid_info, this._rb_dest))
            {
                return(false);
            }

            //SerialID引きする。
            SerialTable.SerialTableRow d = this._table.getItembySerialId(this._rb_dest.marker_id);
            if (d == null)
            {
                return(false);
            }

            //戻り値を設定
            o_result.marker_width   = d.marker_width;
            o_result.id             = this._rb_dest.marker_id;
            o_result.artk_direction = this._temp_nyid_param.direction;
            o_result.name           = d.name;
            return(true);
        }
 /**
  * この関数は、ラスタドライバから画像を読み出します。
  * @param i_pix_drv
  * @param i_size
  * @param i_vertex
  * @param o_data
  * @param o_param
  * @return
  * @throws NyARException
  */
 public bool getARPlayCardId(INyARGsPixelDriver i_pix_drv, NyARIntPoint2d[] i_vertex, PsArIdParam i_result)
 {
     if (!this._perspective_reader.setSourceSquare(i_vertex)) {
     return false;
       }
       return this._pickFromRaster(i_pix_drv, i_result);
 }
Exemple #3
0
 /**
  * この関数は、ラスタドライバから画像を読み出します。
  * @param i_pix_drv
  * @param i_size
  * @param i_vertex
  * @param o_data
  * @param o_param
  * @return
  * @throws NyARException
  */
 public bool getARPlayCardId(INyARGsPixelDriver i_pix_drv, NyARDoublePoint2d[] i_vertex, PsArIdParam i_result)
 {
     if (!this._perspective_reader.setSourceSquare(i_vertex))
     {
         return(false);
     }
     return(this._pickFromRaster(i_pix_drv, i_result));
 }
 /**
  * この関数は、ラスタドライバから画像を読み出します。
  * @param i_pix_drv
  * @param i_size
  * @param i_vertex
  * @param o_data
  * @param o_param
  * @return
  * @
  */
 public bool pickFromRaster(INyARGsPixelDriver i_pix_drv, NyARIntPoint2d[] i_vertex, NyIdMarkerPattern o_data, NyIdMarkerParam o_param)
 {
     if (!this._perspective_reader.setSourceSquare(i_vertex))
     {
         return false;
     }
     return this._pickFromRaster(i_pix_drv, o_data, o_param);
 }
 /**
  * この関数は、ラスタドライバから画像を読み出します。
  * @param i_pix_drv
  * @param i_size
  * @param i_vertex
  * @param o_data
  * @param o_param
  * @return
  * @
  */
 public bool pickFromRaster(INyARGsPixelDriver i_pix_drv, NyARDoublePoint2d[] i_vertex, NyIdMarkerPattern o_data, NyIdMarkerParam o_param)
 {
     if (!this._perspective_reader.setSourceSquare(i_vertex))
     {
         return(false);
     }
     return(this._pickFromRaster(i_pix_drv, o_data, o_param));
 }
Exemple #6
0
 /**
  * i_imageから、idマーカを読みだします。
  * o_dataにはマーカデータ、o_paramにはマーカのパラメータを返却します。
  * @param image
  * @param i_vertex
  * @param o_data
  * @param o_param
  * @return
  * @throws NyARException
  */
 private bool _pickFromRaster(INyARGsPixelDriver i_pix_drv, PsArIdParam i_result)
 {
     if (!this._perspective_reader.readDataBits(i_pix_drv, i_pix_drv.getSize(), this._decoder))
     {
         return(false);
     }
     //敷居値検索
     return(this._decoder.decodePatt(i_result));
 }
        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);
            int         b               = t + h;
            int         row_padding_dst = (size.w - w);
            int         row_padding_src = row_padding_dst;
            int         pix_count       = w;
            int         pix_mod_part    = pix_count - (pix_count % 8);
            int         src_ptr         = t * size.w + l;

            int[] in_buf = (int[])this._ref_raster.getBuffer();
            switch (o_raster.getBufferType())
            {
            case NyARBufferType.INT1D_GRAY_8:
                int   v;
                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--)
                    {
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) >> 2;
                    }
                    for (; x >= 0; x -= 8)
                    {
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                        v = in_buf[src_ptr++]; out_buf[bp++] = (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3;
                    }
                    bp      += row_padding_dst;
                    src_ptr += row_padding_src;
                }
                return;

            default:
                INyARGsPixelDriver out_drv = o_raster.getGsPixelDriver();
                for (int y = t; y < b; y++)
                {
                    for (int x = 0; x < pix_count; x++)
                    {
                        v = in_buf[src_ptr++];
                        out_drv.setPixel(x, y, (((v >> 16) & 0xff) + ((v >> 8) & 0xff) + (v & 0xff)) / 3);
                    }
                }
                return;
            }
        }
Exemple #8
0
        public void doFilter(INyARGrayscaleRaster i_output)
        {
            INyARGsPixelDriver ind  = this._raster.getGsPixelDriver();
            INyARGsPixelDriver outd = i_output.getGsPixelDriver();
            NyARIntSize        s    = this._raster.getSize();

            for (int y = s.h - 1; y >= 0; y--)
            {
                for (int x = s.w - 1; x >= 0; x--)
                {
                    outd.setPixel(x, y, 255 - ind.getPixel(x, y));
                }
            }
        }
        /**
         * このクラスの初期化シーケンスです。コンストラクタから呼び出します。初期化に失敗すると、例外を発生します。
         * @param i_size
         * ラスタサイズ
         * @param i_raster_type
         * バッファ形式
         * @param i_is_alloc
         * バッファ参照方法値
         * @
         */
        protected virtual void initInstance(NyARIntSize i_size, int i_raster_type, bool i_is_alloc)
        {
            switch (i_raster_type)
            {
            case NyARBufferType.INT1D_GRAY_8:
                this._buf = i_is_alloc ? new int[i_size.w * i_size.h] : null;
                break;

            default:
                throw new NyARException();
            }
            this._is_attached_buffer = i_is_alloc;
            //ピクセルドライバの生成
            this._pixdrv = NyARGsPixelDriverFactory.createDriver(this);
        }
        public void createHistogram(int i_l, int i_t, int i_w, int i_h, int i_skip, NyARHistogram o_histogram)
        {
            o_histogram.reset();
            int[] data_ptr         = o_histogram.data;
            INyARGsPixelDriver drv = this._gsr.getGsPixelDriver();
            int pix_count          = i_w;
            int pix_mod_part       = pix_count - (pix_count % 8);

            //左上から1行づつ走査していく
            for (int y = i_h - 1; y >= 0; y -= i_skip)
            {
                for (int x = pix_count - 1; x >= pix_mod_part; x--)
                {
                    data_ptr[drv.getPixel(x, y)]++;
                }
            }
            o_histogram.total_of_data = i_w * i_h / i_skip;
            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
         * グレースケールのピクセルを格納するバッファ
         * @
         */
        private bool rectPixels(INyARGsPixelDriver 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      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++;
                }
                //GS値を配列に取得
                i_reader.getPixelSet(ref_x, ref_y, i_width, o_pixel, out_index);
                out_index += i_width;
            }
            return(true);
        }
        public void convertRect(int l, int t, int w, int h, INyARGrayscaleRaster o_raster)
        {
            int[] wk        = this._wk;
            int   b         = t + h;
            int   pix_count = w;

            switch (o_raster.getBufferType())
            {
            default:
                INyARGsPixelDriver  out_drv = o_raster.getGsPixelDriver();
                INyARRgbPixelDriver in_drv  = this._ref_raster.getRgbPixelDriver();
                for (int y = t; y < b; y++)
                {
                    for (int x = pix_count - 1; x >= 0; x--)
                    {
                        in_drv.getPixel(x, y, wk);
                        out_drv.setPixel(x, y, (306 * (wk[2] & 0xff) + 601 * (wk[1] & 0xff) + 117 * (wk[0] & 0xff)) >> 10);
                    }
                }
                return;
            }
        }
        /**
         * i_imageから、idマーカを読みだします。
         * o_dataにはマーカデータ、o_paramにはマーカのパラメータを返却します。
         * @param image
         * @param i_vertex
         * @param o_data
         * @param o_param
         * @return
         * @
         */
        private bool _pickFromRaster(INyARGsPixelDriver i_pix_drv, NyIdMarkerPattern o_data, NyIdMarkerParam o_param)
        {
            PerspectivePixelReader.TThreshold th = this.__pickFromRaster_th;
            MarkerPattEncoder encoder            = this.__pickFromRaster_encoder;

            //マーカパラメータを取得
            this._perspective_reader.detectThresholdValue(i_pix_drv, th);

            if (!this._perspective_reader.readDataBits(i_pix_drv, i_pix_drv.getSize(), 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);
        }
        /**
         * この関数は、マーカ画像のi_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。
         * L=暗点、H=明点、LHL=1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
         * 検出した場合、関数は失敗します。
         * @param i_y1
         * ライン1のインデクス
         * @param i_th_h
         * 明点の敷居値
         * @param i_th_l
         * 暗点の敷居値
         * @param o_edge_index
         * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列。
         * [FRQ_POINTS]以上の配列を指定すること。
         * @return
         * 周波数の値。失敗すると-1
         * @
         */
        public int getRowFrequency(INyARGsPixelDriver 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, 0);

                //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);
        }
        /**
         * この関数はマーカパターンから、敷居値を決定します。
         * @param i_reader
         * ラスタリーダオブジェクト
         * @param i_raster_size
         * ラスのタのサイズ
         * @param o_threshold
         * 敷居値を受け取るオブジェクト
         * @
         */
        public void detectThresholdValue(INyARGsPixelDriver i_reader, TThreshold o_threshold)
        {
            int[] th_pixels = this._th_pixels;
            NyARIntSize size = i_reader.getSize();
            //左上のピックアップ領域からピクセルを得る(00-24)
            rectPixels(i_reader, size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, 0, th_pixels);

            //左下のピックアップ領域からピクセルを得る(25-49)
            rectPixels(i_reader, size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE, th_pixels);

            //右上のピックアップ領域からピクセルを得る(50-74)
            rectPixels(i_reader, 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, 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_imageから、idマーカを読みだします。
         * o_dataにはマーカデータ、o_paramにはマーカのパラメータを返却します。
         * @param image
         * @param i_vertex
         * @param o_data
         * @param o_param
         * @return
         * @
         */
        private bool _pickFromRaster(INyARGsPixelDriver i_pix_drv, NyIdMarkerPattern o_data, NyIdMarkerParam o_param)
        {
            PerspectivePixelReader.TThreshold th = this.__pickFromRaster_th;
            MarkerPattEncoder encoder = this.__pickFromRaster_encoder;
            //マーカパラメータを取得
            this._perspective_reader.detectThresholdValue(i_pix_drv, th);

            if (!this._perspective_reader.readDataBits(i_pix_drv, i_pix_drv.getSize(), 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;
        }
        /**
         * この関数は、マーカ画像のi_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。
         * L=暗点、H=明点、LHL=1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
         * 検出した場合、関数は失敗します。
         * @param i_y1
         * ライン1のインデクス
         * @param i_th_h
         * 明点の敷居値
         * @param i_th_l
         * 暗点の敷居値
         * @param o_edge_index
         * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列。
         * [FRQ_POINTS]以上の配列を指定すること。
         * @return
         * 周波数の値。失敗すると-1
         * @
         */
        public int getRowFrequency(INyARGsPixelDriver 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, 0);

                //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));
        }
        /**
         * この関数は、マーカパターンからデータを読み取ります。
         * @param i_reader
         * ラスタリーダ
         * @param i_raster_size
         * ラスタのサイズ
         * @param o_bitbuffer
         * データビットの出力先
         * @return
         * 成功するとtrue
         * @throws NyARException
         */
        public bool readDataBits(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, MarkerPattDecoder o_bitbuffer)
        {
            int raster_width = i_raster_size.w;
            int raster_height = i_raster_size.h;

            double[] index_x = this.__readDataBits_index_bit_x;
            double[] index_y = this.__readDataBits_index_bit_y;

            //読み出し位置を取得
            detectDataBitsIndex(index_x, index_y);
            int resolution = 3;

            double[] cpara = this._cparam;
            int[] ref_x = this._ref_x;
            int[] ref_y = this._ref_y;
            int[] pixcel_temp = this._pixcel_temp;

            double cpara_0 = cpara[0];
            double cpara_1 = cpara[1];
            double cpara_3 = cpara[3];
            double cpara_6 = cpara[6];

            int p = 0;
            for (int i = 0; i < resolution; i++)
            {
                //1列分のピクセルのインデックス値を計算する。
                double cy0 = 1 + index_y[i * 2 + 0];
                double cy1 = 1 + index_y[i * 2 + 1];
                double cpy0_12 = cpara_1 * cy0 + cpara[2];
                double cpy0_45 = cpara[4] * cy0 + cpara[5];
                double cpy0_7 = cpara[7] * cy0 + 1.0;
                double cpy1_12 = cpara_1 * cy1 + cpara[2];
                double cpy1_45 = cpara[4] * cy1 + cpara[5];
                double cpy1_7 = cpara[7] * cy1 + 1.0;

                int pt = 0;
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int xx, yy;
                    double d;
                    double cx0 = 1 + index_x[i2 * 2 + 0];
                    double cx1 = 1 + index_x[i2 * 2 + 1];

                    double cp6_0 = cpara_6 * cx0;
                    double cpx0_0 = cpara_0 * cx0;
                    double cpx3_0 = cpara_3 * cx0;

                    double cp6_1 = cpara_6 * cx1;
                    double cpx0_1 = cpara_0 * cx1;
                    double cpx3_1 = cpara_3 * cx1;

                    d = cp6_0 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d = cp6_0 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d = cp6_1 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d = cp6_1 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp, 0);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int index = i2 * 4;
                    o_bitbuffer.setBit(p, (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3]) / 4);
                    p++;
                }
            }
            return true;
        }
 /**
  * i_imageから、idマーカを読みだします。
  * o_dataにはマーカデータ、o_paramにはマーカのパラメータを返却します。
  * @param image
  * @param i_vertex
  * @param o_data
  * @param o_param
  * @return
  * @throws NyARException
  */
 private bool _pickFromRaster(INyARGsPixelDriver i_pix_drv, PsArIdParam i_result)
 {
     if (!this._perspective_reader.readDataBits(i_pix_drv, i_pix_drv.getSize(), this._decoder))
     {
         return false;
     }
     //敷居値検索
     return this._decoder.decodePatt(i_result);
 }
Exemple #20
0
        public void convertRect(int l, int t, int w, int h, INyARGrayscaleRaster o_raster)
        {
            Color32[]   c               = (Color32[])(this._ref_raster.getBuffer());
            NyARIntSize size            = this._ref_raster.getSize();
            int         src             = (l + t * size.w) * 4;
            int         b               = t + h;
            int         row_padding_dst = (size.w - w);
            int         row_padding_src = row_padding_dst * 4;
            int         pix_count       = w;
            int         pix_mod_part    = pix_count - (pix_count % 8);

            // in_buf = (byte[])this._ref_raster.getBuffer();
            switch (o_raster.getBufferType())
            {
            case NyARBufferType.INT1D_GRAY_8:
                int[] out_buf = (int[])o_raster.getBuffer();
                int   dst_ptr;
                if (this._is_inverse)
                {
                    dst_ptr          = (h - 1 - t) * size.w + l;
                    row_padding_dst -= size.w * 2;
                }
                else
                {
                    dst_ptr = t * size.w + l;
                }
                for (int y = t; y < b; y++)
                {
                    int     x = 0;
                    Color32 p;
                    for (x = pix_count - 1; x >= pix_mod_part; x--)
                    {
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                    }
                    for (; x >= 0; x -= 8)
                    {
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                        p = c[src++];
                        out_buf[dst_ptr++] = (p.r + p.g + p.b) / 3;
                    }
                    dst_ptr += row_padding_dst;
                    src     += row_padding_src;
                }
                return;

            default:
                INyARGsPixelDriver out_drv = o_raster.getGsPixelDriver();
                for (int y = t; y < b; y++)
                {
                    for (int x = 0; x < pix_count; x++)
                    {
                        Color32 p = c[src++];
                        out_drv.setPixel(x, y, (p.r + p.g + p.b) / 3);
                    }
                    src += row_padding_src;
                }
                return;
            }
        }
Exemple #21
0
 public NyARRlePixelDriver_GSReader(INyARGrayscaleRaster i_raster)
 {
     this._ref_driver = i_raster.getGsPixelDriver();
 }
        private int detectDataBitsIndex(INyARGsPixelDriver 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;
        }
        /**
         * この関数は、マーカ画像のi_x1列目とi_x2列目を平均して、タイミングパターンの周波数を得ます。
         * L=暗点、H=明点、LHL=1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
         * 検出した場合、関数は失敗します。
         * @param i_x1
         * ライン1のインデクス
         * @param i_th_h
         * 明点の敷居値
         * @param i_th_l
         * 暗点の敷居値
         * @param o_edge_index
         * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列。
         * [FRQ_POINTS]以上の配列を指定すること。
         * @return
         * 周波数の値。失敗すると-1
         * @
         */
        public int getColFrequency(INyARGsPixelDriver 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, 0);

                int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index);
                //周期は3-10であること
                if (freq_t < MIN_FREQ || freq_t > MAX_FREQ)
                {
                    continue;
                }
                //周期は等間隔であること
                if (!checkFreqWidth(o_edge_index, freq_t))
                {
                    continue;
                }
                //検出カウンタを追加
                freq_count_table[freq_t]++;
                int table_st = (freq_t - 1) * freq_t;
                for (int i2 = 0; i2 < freq_t * 2; i2++)
                {
                    freq_table[table_st + i2] += o_edge_index[i2];
                }
            }
            return(getMaxFreq(freq_count_table, freq_table, o_edge_index));
        }
        /**
         * ラスタから射影変換したピクセルを得ます。
         * @param i_lt_x
         * @param i_lt_y
         * @param i_step_x
         * @param i_step_y
         * @param i_width
         * @param i_height
         * @param i_out_st
         * 格納バッファo_pixelの先頭のインデクス。
         * @param o_pixel
         * グレースケールのピクセルを格納するバッファ
         * @
         */
        private bool rectPixels(INyARGsPixelDriver 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 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++;
                }
                //GS値を配列に取得
                i_reader.getPixelSet(ref_x, ref_y, i_width, o_pixel, out_index);
                out_index += i_width;
            }
            return true;
        }
        /**
         * この関数はマーカパターンから、敷居値を決定します。
         * @param i_reader
         * ラスタリーダオブジェクト
         * @param i_raster_size
         * ラスのタのサイズ
         * @param o_threshold
         * 敷居値を受け取るオブジェクト
         * @
         */
        public void detectThresholdValue(INyARGsPixelDriver i_reader, TThreshold o_threshold)
        {
            int[]       th_pixels = this._th_pixels;
            NyARIntSize size      = i_reader.getSize();

            //左上のピックアップ領域からピクセルを得る(00-24)
            rectPixels(i_reader, size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, 0, th_pixels);

            //左下のピックアップ領域からピクセルを得る(25-49)
            rectPixels(i_reader, size, THRESHOLD_SAMPLE_LT, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE, th_pixels);

            //右上のピックアップ領域からピクセルを得る(50-74)
            rectPixels(i_reader, 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, 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_x1列目とi_x2列目を平均して、タイミングパターンの周波数を得ます。
         * L=暗点、H=明点、LHL=1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
         * 検出した場合、関数は失敗します。
         * @param i_x1
         * ライン1のインデクス
         * @param i_th_h
         * 明点の敷居値
         * @param i_th_l
         * 暗点の敷居値
         * @param o_edge_index
         * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列。
         * [FRQ_POINTS]以上の配列を指定すること。
         * @return
         * 周波数の値。失敗すると-1
         * @
         */
        public int getColFrequency(INyARGsPixelDriver 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, 0);

                int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index);
                //周期は3-10であること
                if (freq_t < MIN_FREQ || freq_t > MAX_FREQ)
                {
                    continue;
                }
                //周期は等間隔であること
                if (!checkFreqWidth(o_edge_index, freq_t))
                {
                    continue;
                }
                //検出カウンタを追加
                freq_count_table[freq_t]++;
                int table_st = (freq_t - 1) * freq_t;
                for (int i2 = 0; i2 < freq_t * 2; i2++)
                {
                    freq_table[table_st + i2] += o_edge_index[i2];
                }
            }
            return getMaxFreq(freq_count_table, freq_table, o_edge_index);
        }
Exemple #27
0
        public void convertRect(int l, int t, int w, int h, INyARGrayscaleRaster o_raster)
        {
            byte[]      work            = this._work;
            BitmapData  bm              = this._ref_raster.lockBitmap();
            NyARIntSize size            = this._ref_raster.getSize();
            int         bp              = (l + t * size.w) * 4 + (int)bm.Scan0;
            int         b               = t + h;
            int         row_padding_dst = (size.w - w);
            int         row_padding_src = row_padding_dst * 4;
            int         pix_count       = w;
            int         pix_mod_part    = pix_count - (pix_count % 8);
            int         dst_ptr         = t * size.w + l;

            // 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--)
                    {
                        int p = Marshal.ReadInt32((IntPtr)bp);
                        out_buf[dst_ptr++] = (((p >> 16) & 0xff) + ((p >> 8) & 0xff) + (p & 0xff)) / 3;
                        bp += 4;
                    }
                    for (; x >= 0; x -= 8)
                    {
                        Marshal.Copy((IntPtr)bp, work, 0, 32);
                        out_buf[dst_ptr++] = (work[0] + work[1] + work[2]) / 3;
                        out_buf[dst_ptr++] = (work[4] + work[5] + work[6]) / 3;
                        out_buf[dst_ptr++] = (work[8] + work[9] + work[10]) / 3;
                        out_buf[dst_ptr++] = (work[12] + work[13] + work[14]) / 3;
                        out_buf[dst_ptr++] = (work[16] + work[17] + work[18]) / 3;
                        out_buf[dst_ptr++] = (work[20] + work[21] + work[22]) / 3;
                        out_buf[dst_ptr++] = (work[24] + work[25] + work[26]) / 3;
                        out_buf[dst_ptr++] = (work[28] + work[29] + work[30]) / 3;
                        bp += 32;
                    }
                    bp      += row_padding_src;
                    dst_ptr += row_padding_dst;
                }
                this._ref_raster.unlockBitmap();
                return;

            default:
                INyARGsPixelDriver out_drv = o_raster.getGsPixelDriver();
                for (int y = t; y < b; y++)
                {
                    for (int x = 0; x < pix_count; x++)
                    {
                        int p = Marshal.ReadInt32((IntPtr)bp);
                        out_drv.setPixel(x, y, (((p >> 16) & 0xff) + ((p >> 8) & 0xff) + (p & 0xff)) / 3);
                        bp += 4;
                    }
                    bp += row_padding_src;
                }
                this._ref_raster.unlockBitmap();
                return;
            }
        }
        /**
         * この関数は、マーカパターンからデータを読み取ります。
         * @param i_reader
         * ラスタリーダ
         * @param i_raster_size
         * ラスタのサイズ
         * @param i_th
         * 敷居値情報
         * @param o_bitbuffer
         * データビットの出力先
         * @return
         * 成功するとtrue
         * @
         */
        public bool readDataBits(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer)
        {
            int raster_width = i_raster_size.w;
            int raster_height = i_raster_size.h;

            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++)
                {
                    int xx, yy;
                    double d;
                    double cx0 = 1 + index_x[i2 * 2 + 0];
                    double cx1 = 1 + index_x[i2 * 2 + 1];

                    double cp6_0 = cpara_6 * cx0;
                    double cpx0_0 = cpara_0 * cx0;
                    double cpx3_0 = cpara_3 * cx0;

                    double cp6_1 = cpara_6 * cx1;
                    double cpx0_1 = cpara_0 * cx1;
                    double cpx3_1 = cpara_3 * cx1;

                    d = cp6_0 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d = cp6_0 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d = cp6_1 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d = cp6_1 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp, 0);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int index = i2 * 4;
                    int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3]) / 4;
                    //				+pixcel_temp[index+4]+pixcel_temp[index+5]+
                    //							pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+
                    //							pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);
                    //暗点を1、明点を0で表現します。
                    o_bitbuffer.setBitByBitIndex(p, pixel > th ? 0 : 1);
                    p++;
                }
            }
            return true;
        }
Exemple #29
0
        /**
         * この関数は、マーカパターンからデータを読み取ります。
         * @param i_reader
         * ラスタリーダ
         * @param i_raster_size
         * ラスタのサイズ
         * @param o_bitbuffer
         * データビットの出力先
         * @return
         * 成功するとtrue
         * @throws NyARException
         */
        public bool readDataBits(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, MarkerPattDecoder o_bitbuffer)
        {
            int raster_width  = i_raster_size.w;
            int raster_height = i_raster_size.h;

            double[] index_x = this.__readDataBits_index_bit_x;
            double[] index_y = this.__readDataBits_index_bit_y;


            //読み出し位置を取得
            detectDataBitsIndex(index_x, index_y);
            int resolution = 3;

            double[] cpara       = this._cparam;
            int[]    ref_x       = this._ref_x;
            int[]    ref_y       = this._ref_y;
            int[]    pixcel_temp = this._pixcel_temp;

            double cpara_0 = cpara[0];
            double cpara_1 = cpara[1];
            double cpara_3 = cpara[3];
            double cpara_6 = cpara[6];


            int p = 0;

            for (int i = 0; i < resolution; i++)
            {
                //1列分のピクセルのインデックス値を計算する。
                double cy0     = 1 + index_y[i * 2 + 0];
                double cy1     = 1 + index_y[i * 2 + 1];
                double cpy0_12 = cpara_1 * cy0 + cpara[2];
                double cpy0_45 = cpara[4] * cy0 + cpara[5];
                double cpy0_7  = cpara[7] * cy0 + 1.0;
                double cpy1_12 = cpara_1 * cy1 + cpara[2];
                double cpy1_45 = cpara[4] * cy1 + cpara[5];
                double cpy1_7  = cpara[7] * cy1 + 1.0;

                int pt = 0;
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int    xx, yy;
                    double d;
                    double cx0 = 1 + index_x[i2 * 2 + 0];
                    double cx1 = 1 + index_x[i2 * 2 + 1];

                    double cp6_0  = cpara_6 * cx0;
                    double cpx0_0 = cpara_0 * cx0;
                    double cpx3_0 = cpara_3 * cx0;

                    double cp6_1  = cpara_6 * cx1;
                    double cpx0_1 = cpara_0 * cx1;
                    double cpx3_1 = cpara_3 * cx1;

                    d         = cp6_0 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d         = cp6_0 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d         = cp6_1 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d         = cp6_1 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp, 0);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int index = i2 * 4;
                    o_bitbuffer.setBit(p, (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3]) / 4);
                    p++;
                }
            }
            return(true);
        }
        private int detectDataBitsIndex(INyARGsPixelDriver 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_size
  * ラスタサイズ
  * @param i_raster_type
  * バッファ形式
  * @param i_is_alloc
  * バッファ参照方法値
  * @
  */
 protected virtual void initInstance(NyARIntSize i_size, int i_raster_type, bool i_is_alloc)
 {
     switch (i_raster_type)
     {
         case NyARBufferType.INT1D_GRAY_8:
             this._buf = i_is_alloc ? new int[i_size.w * i_size.h] : null;
             break;
         default:
             throw new NyARException();
     }
     this._is_attached_buffer = i_is_alloc;
     //ピクセルドライバの生成
     this._pixdrv = NyARGsPixelDriverFactory.createDriver(this);
 }
        /**
         * この関数は、マーカパターンからデータを読み取ります。
         * @param i_reader
         * ラスタリーダ
         * @param i_raster_size
         * ラスタのサイズ
         * @param i_th
         * 敷居値情報
         * @param o_bitbuffer
         * データビットの出力先
         * @return
         * 成功するとtrue
         * @
         */
        public bool readDataBits(INyARGsPixelDriver i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer)
        {
            int raster_width  = i_raster_size.w;
            int raster_height = i_raster_size.h;

            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++)
                {
                    int    xx, yy;
                    double d;
                    double cx0 = 1 + index_x[i2 * 2 + 0];
                    double cx1 = 1 + index_x[i2 * 2 + 1];

                    double cp6_0  = cpara_6 * cx0;
                    double cpx0_0 = cpara_0 * cx0;
                    double cpx3_0 = cpara_3 * cx0;

                    double cp6_1  = cpara_6 * cx1;
                    double cpx0_1 = cpara_0 * cx1;
                    double cpx3_1 = cpara_3 * cx1;

                    d         = cp6_0 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d         = cp6_0 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_0 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_0 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d         = cp6_1 + cpy0_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy0_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy0_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;

                    d         = cp6_1 + cpy1_7;
                    ref_x[pt] = xx = (int)((cpx0_1 + cpy1_12) / d);
                    ref_y[pt] = yy = (int)((cpx3_1 + cpy1_45) / d);
                    if (xx < 0 || xx >= raster_width || yy < 0 || yy >= raster_height)
                    {
                        ref_x[pt] = xx < 0 ? 0 : (xx >= raster_width ? raster_width - 1 : xx);
                        ref_y[pt] = yy < 0 ? 0 : (yy >= raster_height ? raster_height - 1 : yy);
                    }
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp, 0);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int index = i2 * 4;
                    int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] + pixcel_temp[index + 3]) / 4;
                    //				+pixcel_temp[index+4]+pixcel_temp[index+5]+
                    //							pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+
                    //							pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);
                    //暗点を1、明点を0で表現します。
                    o_bitbuffer.setBitByBitIndex(p, pixel > th ? 0 : 1);
                    p++;
                }
            }
            return(true);
        }
Exemple #33
0
        public override bool getContour(int i_l, int i_t, int i_r, int i_b, int i_entry_x, int i_entry_y, int i_th, NyARIntCoordinates o_coord)
        {
            Debug.Assert(i_t <= i_entry_x);
            INyARGsPixelDriver reader = this._ref_raster.getGsPixelDriver();

            int[] xdir = _getContour_xdir; // static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
            int[] ydir = _getContour_ydir; // static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
            //クリップ領域の上端に接しているポイントを得る。
            NyARIntPoint2d[] coord = o_coord.items;
            int max_coord          = o_coord.items.Length;

            coord[0].x = i_entry_x;
            coord[0].y = i_entry_y;
            int coord_num = 1;
            int dir       = 5;

            int c = i_entry_x;
            int r = i_entry_y;

            for (; ;)
            {
                dir = (dir + 5) % 8;//dirの正規化
                //境界に接しているとき
                int i;
                for (i = 0; i < 8; i++)
                {
                    int x = c + xdir[dir];
                    int y = r + ydir[dir];
                    //境界チェック
                    if (x >= i_l && x <= i_r && y >= i_t && y <= i_b)
                    {
                        if (reader.getPixel(x, y) <= i_th)
                        {
                            break;
                        }
                    }
                    dir++;//倍長テーブルを参照するので問題なし
                }
                if (i == 8)
                {
                    //8方向全て調べたけどラベルが無いよ?
                    throw new NyARException();// return(-1);
                }
                // xcoordとycoordをc,rにも保存
                c = c + xdir[dir];
                r = r + ydir[dir];
                coord[coord_num].x = c;
                coord[coord_num].y = r;
                //終了条件判定
                if (c == i_entry_x && r == i_entry_y)
                {
                    //開始点と同じピクセルに到達したら、終点の可能性がある。
                    coord_num++;
                    //末端のチェック
                    if (coord_num == max_coord)
                    {
                        //輪郭bufが末端に達した
                        return(false);
                    }
                    //末端候補の次のピクセルを調べる
                    dir = (dir + 5) % 8;//dirの正規化
                    for (i = 0; i < 8; i++)
                    {
                        int x = c + xdir[dir];
                        int y = r + ydir[dir];
                        //境界チェック
                        if (x >= i_l && x <= i_r && y >= i_t && y <= i_b)
                        {
                            if (reader.getPixel(x, y) <= i_th)
                            {
                                break;
                            }
                        }
                        dir++;//倍長テーブルを参照するので問題なし
                    }
                    if (i == 8)
                    {
                        //8方向全て調べたけどラベルが無いよ?
                        throw new NyARException();
                    }
                    //得たピクセルが、[1]と同じならば、末端である。
                    c = c + xdir[dir];
                    r = r + ydir[dir];
                    if (coord[1].x == c && coord[1].y == r)
                    {
                        //終点に達している。
                        o_coord.length = coord_num;
                        break;
                    }
                    else
                    {
                        //終点ではない。
                        coord[coord_num].x = c;
                        coord[coord_num].y = r;
                    }
                }
                coord_num++;
                //末端のチェック
                if (coord_num == max_coord)
                {
                    //輪郭が末端に達した
                    return(false);
                }
            }
            return(true);
        }