Exemple #1
0
        protected bool initInstance(NyARIntSize i_size, int i_raster_type, bool i_is_alloc)
        {
            switch (i_raster_type)
            {
            case NyARBufferType.INT1D_X8R8G8B8_32:
                this._buf    = i_is_alloc?new int[i_size.w * i_size.h]:null;
                this._reader = new NyARRgbPixelReader_INT1D_X8R8G8B8_32((int[])this._buf, i_size);
                break;

            case NyARBufferType.BYTE1D_B8G8R8X8_32:
                this._buf    = i_is_alloc?new byte[i_size.w * i_size.h * 4]:null;
                this._reader = new NyARRgbPixelReader_BYTE1D_B8G8R8X8_32((byte[])this._buf, i_size);
                break;

            case NyARBufferType.BYTE1D_R8G8B8_24:
                this._buf    = i_is_alloc?new byte[i_size.w * i_size.h * 3]:null;
                this._reader = new NyARRgbPixelReader_BYTE1D_R8G8B8_24((byte[])this._buf, i_size);
                break;

            default:
                return(false);
            }
            this._is_attached_buffer = i_is_alloc;
            return(true);
        }
        /**
         * i_imageから、idマーカを読みだします。
         * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。
         * @param image
         * @param i_square
         * @param o_data
         * @param o_param
         * @return
         * @throws NyARException
         */
        public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertex, NyIdMarkerPattern o_data, NyIdMarkerParam o_param)
        {
            //遠近法のパラメータを計算
            if (!this._perspective_reader.setSourceSquare(i_vertex))
            {
                return(false);
            }
            ;

            INyARRgbPixelReader reader      = image.getRgbPixelReader();
            NyARIntSize         raster_size = image.getSize();


            PerspectivePixelReader.TThreshold th = this.__pickFromRaster_th;
            MarkerPattEncoder encoder            = this.__pickFromRaster_encoder;

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

            if (!this._perspective_reader.readDataBits(reader, raster_size, th, encoder))
            {
                return(false);
            }
            int d = encoder.encode(o_data);

            if (d < 0)
            {
                return(false);
            }
            o_param.direction = d;
            o_param.threshold = th.th;

            return(true);
        }
Exemple #3
0
        /**
         * @see INyARColorPatt#pickFromRaster
         */
        public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs)
        {
            double[] conv_param = this._convparam;
            int      rx2, ry2;

            rx2 = this._size.w;
            ry2 = this._size.h;
            int[] rgb_tmp = new int[3];

            INyARRgbPixelReader reader = image.getRgbPixelReader();

            // 変形先領域の頂点を取得

            //変換行列から現在の座標系への変換パラメタを作成
            calcPara(i_vertexs, conv_param);       // 変換パラメータを求める
            for (int y = 0; y < ry2; y++)
            {
                for (int x = 0; x < rx2; x++)
                {
                    int ttx = (int)((conv_param[0] * x * y + conv_param[1] * x + conv_param[2] * y + conv_param[3]) + 0.5);
                    int tty = (int)((conv_param[4] * x * y + conv_param[5] * x + conv_param[6] * y + conv_param[7]) + 0.5);
                    reader.getPixel((int)ttx, (int)tty, rgb_tmp);
                    this._patdata[x + y * rx2] = (rgb_tmp[0] << 16) | (rgb_tmp[1] << 8) | rgb_tmp[2];
                }
            }
            return(true);
        }
Exemple #4
0
 public DsRGB565Raster(int i_width, int i_height)
     : base(i_width, i_height, NyARBufferType.WORD1D_R5G6B5_16LE)
 {
     if (i_width % 4 != 0)
     {
         throw new NyARException();
     }
     this._buf        = new short[i_height * i_width];
     this._rgb_reader = new NyARRgbPixelReader_WORD1D_R5G6B5_16LE(this._buf, this._size);
     return;
 }
        /**
         * 矩形からピクセルを切り出します
         * @param i_lt_x
         * @param i_lt_y
         * @param i_step_x
         * @param i_step_y
         * @param i_width
         * @param i_height
         * @param i_out_st
         * o_pixelへの格納場所の先頭インデクス
         * @param o_pixel
         * @throws NyARException
         */
        private bool rectPixels(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_lt_x, int i_lt_y, int i_step_x, int i_step_y, int i_width, int i_height, int i_out_st, int[] o_pixel)
        {
            double[] cpara = this._cparam;
            int[] ref_x = this._ref_x;
            int[] ref_y = this._ref_y;
            int[] pixcel_temp = this._pixcel_temp;
            int raster_width = i_raster_size.w;
            int raster_height = i_raster_size.h;

            int out_index = i_out_st;
            double cpara_6 = cpara[6];
            double cpara_0 = cpara[0];
            double cpara_3 = cpara[3];

            for (int i = 0; i < i_height; i++)
            {
                //1列分のピクセルのインデックス値を計算する。
                int cy0 = 1 + i * i_step_y + i_lt_y;
                double cpy0_12 = cpara[1] * cy0 + cpara[2];
                double cpy0_45 = cpara[4] * cy0 + cpara[5];
                double cpy0_7 = cpara[7] * cy0 + 1.0;
                int pt = 0;
                for (int i2 = 0; i2 < i_width; i2++)
                {
                    int cx0 = 1 + i2 * i_step_x + i_lt_x;
                    double d = cpara_6 * cx0 + cpy0_7;
                    int x = (int)((cpara_0 * cx0 + cpy0_12) / d);
                    int y = (int)((cpara_3 * cx0 + cpy0_45) / d);
                    if (x < 0 || y < 0 || x >= raster_width || y >= raster_height)
                    {
                        return false;
                    }
                    ref_x[pt] = x;
                    ref_y[pt] = y;
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, i_width, pixcel_temp);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < i_width; i2++)
                {
                    int index = i2 * 3;
                    o_pixel[out_index] = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2]) / 3;
                    out_index++;
                }
            }
            return true;
        }
        /**
         * 矩形からピクセルを切り出します
         * @param i_lt_x
         * @param i_lt_y
         * @param i_step_x
         * @param i_step_y
         * @param i_width
         * @param i_height
         * @param i_out_st
         * o_pixelへの格納場所の先頭インデクス
         * @param o_pixel
         * @throws NyARException
         */
        private bool rectPixels(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_lt_x, int i_lt_y, int i_step_x, int i_step_y, int i_width, int i_height, int i_out_st, int[] o_pixel)
        {
            double[] cpara         = this._cparam;
            int[]    ref_x         = this._ref_x;
            int[]    ref_y         = this._ref_y;
            int[]    pixcel_temp   = this._pixcel_temp;
            int      raster_width  = i_raster_size.w;
            int      raster_height = i_raster_size.h;

            int    out_index = i_out_st;
            double cpara_6   = cpara[6];
            double cpara_0   = cpara[0];
            double cpara_3   = cpara[3];

            for (int i = 0; i < i_height; i++)
            {
                //1列分のピクセルのインデックス値を計算する。
                int    cy0     = 1 + i * i_step_y + i_lt_y;
                double cpy0_12 = cpara[1] * cy0 + cpara[2];
                double cpy0_45 = cpara[4] * cy0 + cpara[5];
                double cpy0_7  = cpara[7] * cy0 + 1.0;
                int    pt      = 0;
                for (int i2 = 0; i2 < i_width; i2++)
                {
                    int    cx0 = 1 + i2 * i_step_x + i_lt_x;
                    double d   = cpara_6 * cx0 + cpy0_7;
                    int    x   = (int)((cpara_0 * cx0 + cpy0_12) / d);
                    int    y   = (int)((cpara_3 * cx0 + cpy0_45) / d);
                    if (x < 0 || y < 0 || x >= raster_width || y >= raster_height)
                    {
                        return(false);
                    }
                    ref_x[pt] = x;
                    ref_y[pt] = y;
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, i_width, pixcel_temp);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < i_width; i2++)
                {
                    int index = i2 * 3;
                    o_pixel[out_index] = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2]) / 3;
                    out_index++;
                }
            }
            return(true);
        }
        /**
         * ラスタのコピーを実行します。
         * この関数は暫定です。低速なので注意してください。
         * @param i_input
         * @param o_output
         * @throws NyARException
         */
        public static void copy(INyARRgbRaster i_input, INyARRgbRaster o_output)
        {
            Debug.Assert(i_input.getSize().isEqualSize(o_output.getSize()));
            int width  = i_input.getWidth();
            int height = i_input.getHeight();

            int[] rgb = new int[3];
            INyARRgbPixelReader inr  = i_input.getRgbPixelReader();
            INyARRgbPixelReader outr = o_output.getRgbPixelReader();

            for (int i = height - 1; i >= 0; i--)
            {
                for (int i2 = width - 1; i2 >= 0; i2--)
                {
                    inr.getPixel(i2, i, rgb);
                    outr.setPixel(i2, i, rgb);
                }
            }
        }
        /**
         * ANY形式の入力ドライバ。
         * @param i_buf
         * @param i_number_of_pix
         * @param i_for_mod
         * @param o_out
         * pow値
         * @return
         * @throws NyARException
         */
        private static double setRaster_ANY(INyARRgbPixelReader i_reader, NyARIntSize i_size, int i_number_of_pix, int[] o_out)
        {
            int width = i_size.w;

            int[] rgb = new int[3];
            int   ave;      //<PV/>

            //<平均値計算>
            ave = 0;
            for (int y = i_size.h - 1; y >= 0; y--)
            {
                for (int x = width - 1; x >= 0; x--)
                {
                    i_reader.getPixel(x, y, rgb);
                    ave += rgb[0] + rgb[1] + rgb[2];
                }
            }
            //<平均値計算>
            ave = i_number_of_pix * 255 * 3 - ave;
            ave = 255 - (ave / (i_number_of_pix * 3));    //(255-R)-ave を分解するための事前計算

            int sum = 0, w_sum;
            int input_ptr = i_number_of_pix * 3 - 1;

            //<差分値計算>
            for (int y = i_size.h - 1; y >= 0; y--)
            {
                for (int x = width - 1; x >= 0; x--)
                {
                    i_reader.getPixel(x, y, rgb);
                    w_sum = (ave - rgb[2]); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum;               //B
                    w_sum = (ave - rgb[1]); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum;               //G
                    w_sum = (ave - rgb[0]); o_out[input_ptr--] = w_sum; sum += w_sum * w_sum;               //R
                }
            }
            //<差分値計算(FORの1/8展開)/>
            double p = Math.Sqrt((double)sum);

            return(p != 0.0?p:0.0000001);
        }
	    protected bool initInstance(NyARIntSize i_size,int i_raster_type,bool i_is_alloc)
	    {
		    switch(i_raster_type)
		    {
			    case NyARBufferType.INT1D_X8R8G8B8_32:
				    this._buf=i_is_alloc?new int[i_size.w*i_size.h]:null;
				    this._reader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32((int[])this._buf,i_size);
				    break;
			    case NyARBufferType.BYTE1D_B8G8R8X8_32:
				    this._buf=i_is_alloc?new byte[i_size.w*i_size.h*4]:null;
				    this._reader=new NyARRgbPixelReader_BYTE1D_B8G8R8X8_32((byte[])this._buf,i_size);
				    break;
			    case NyARBufferType.BYTE1D_R8G8B8_24:
				    this._buf=i_is_alloc?new byte[i_size.w*i_size.h*3]:null;
				    this._reader=new NyARRgbPixelReader_BYTE1D_R8G8B8_24((byte[])this._buf,i_size);
				    break;
			    default:
				    return false;
		    }
		    this._is_attached_buffer=i_is_alloc;
		    return true;
	    }
        public bool readDataBits(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer)
        {
            double[] index_x = this.__readDataBits_index_bit_x;
            double[] index_y = this.__readDataBits_index_bit_y;
            //読み出し位置を取得
            int size = detectDataBitsIndex(i_reader, i_raster_size,i_th, index_x, index_y);
            int resolution = size + size - 1;
            if (size < 0)
            {
                return false;
            }
            if (!o_bitbuffer.initEncoder(size - 1))
            {
                return false;
            }

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

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


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

                int pt = 0;
                for (int i2 = 0; i2 < resolution; i2++)
                {

                    double d;
                    double cx0 = 1 + index_x[i2 * 2 + 0];
                    double cx1 = 1 + index_x[i2 * 2 + 1];

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

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

                    d = cp6_0 + cpy0_7;
                    ref_x[pt] = (int)((cpx0_0 + cpy0_12) / d);
                    ref_y[pt] = (int)((cpx3_0 + cpy0_45) / d);
                    pt++;

                    d = cp6_0 + cpy1_7;
                    ref_x[pt] = (int)((cpx0_0 + cpy1_12) / d);
                    ref_y[pt] = (int)((cpx3_0 + cpy1_45) / d);
                    pt++;

                    d = cp6_1 + cpy0_7;
                    ref_x[pt] = (int)((cpx0_1 + cpy0_12) / d);
                    ref_y[pt] = (int)((cpx3_1 + cpy0_45) / d);
                    pt++;

                    d = cp6_1 + cpy1_7;
                    ref_x[pt] = (int)((cpx0_1 + cpy1_12) / d);
                    ref_y[pt] = (int)((cpx3_1 + cpy1_45) / d);
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int index = i2 * 3 * 4;
                    int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] +
                                pixcel_temp[index + 3] + pixcel_temp[index + 4] + pixcel_temp[index + 5] +
                                pixcel_temp[index + 6] + pixcel_temp[index + 7] + pixcel_temp[index + 8] +
                                pixcel_temp[index + 9] + pixcel_temp[index + 10] + pixcel_temp[index + 11]) / (4 * 3);
                    //暗点を1、明点を0で表現します。
                    o_bitbuffer.setBitByBitIndex(p, pixel > th ? 0 : 1);
                    p++;
                }
            }
            /*		
                    for(int i=0;i<225*4;i++){
                        this.vertex_x[i]=0;
                        this.vertex_y[i]=0;
                    }
                    for(int i=0;i<(resolution)*2;i++){
                        for(int i2=0;i2<(resolution)*2;i2++){
                            this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2];
                            this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i];
				
                        }
                    }
            */
            return true;
        }
        private int detectDataBitsIndex(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th, double[] o_index_row, double[] o_index_col)
        {
            //周波数を測定
            int[] freq_index1 = this.__detectDataBitsIndex_freq_index1;
            int[] freq_index2 = this.__detectDataBitsIndex_freq_index2;


            int frq_t = getRowFrequency(i_reader, i_raster_size, i_th.lt_y, i_th.th_h, i_th.th_l, freq_index1);
            int frq_b = getRowFrequency(i_reader, i_raster_size, i_th.rb_y, i_th.th_h, i_th.th_l, freq_index2);
            //周波数はまとも?
            if ((frq_t < 0 && frq_b < 0) || frq_t == frq_b)
            {
                return -1;
            }
            //タイミングパターンからインデクスを作成
            int freq_h, freq_v;
            int[] index;
            if (frq_t > frq_b)
            {
                freq_h = frq_t;
                index = freq_index1;
            }
            else
            {
                freq_h = frq_b;
                index = freq_index2;
            }
            for (int i = 0; i < freq_h + freq_h - 1; i++)
            {
                o_index_row[i * 2] = ((index[i + 1] - index[i]) * 2 / 5 + index[i]) + FRQ_EDGE;
                o_index_row[i * 2 + 1] = ((index[i + 1] - index[i]) * 3 / 5 + index[i]) + FRQ_EDGE;
            }


            int frq_l = getColFrequency(i_reader, i_raster_size, i_th.lt_x, i_th.th_h, i_th.th_l, freq_index1);
            int frq_r = getColFrequency(i_reader, i_raster_size, i_th.rb_x, i_th.th_h, i_th.th_l, freq_index2);
            //周波数はまとも?
            if ((frq_l < 0 && frq_r < 0) || frq_l == frq_r)
            {
                return -1;
            }
            //タイミングパターンからインデクスを作成
            if (frq_l > frq_r)
            {
                freq_v = frq_l;
                index = freq_index1;
            }
            else
            {
                freq_v = frq_r;
                index = freq_index2;
            }
            //同じ周期?
            if (freq_v != freq_h)
            {
                return -1;
            }

            for (int i = 0; i < freq_v + freq_v - 1; i++)
            {
                int w = index[i];
                int w2 = index[i + 1] - w;
                o_index_col[i * 2] = ((w2) * 2 / 5 + w) + FRQ_EDGE;
                o_index_col[i * 2 + 1] = ((w2) * 3 / 5 + w) + FRQ_EDGE;
            }
            //Lv4以上は無理
            if (freq_v > MAX_FREQ)
            {
                return -1;
            }
            return freq_v;

        }
        /**
         * @see INyARColorPatt#pickFromRaster
         */
        public bool pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs)
        {
            //遠近法のパラメータを計算
            double[] cpara = this.__pickFromRaster_cpara;
            if (!this._perspective_gen.getParam(this._pickup_wh, i_vertexs, cpara))
            {
                return(false);
            }

            int resolution = this._resolution;
            int img_x      = image.getWidth();
            int img_y      = image.getHeight();
            int res_pix    = resolution * resolution;

            int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;

            //ピクセルリーダーを取得
            INyARRgbPixelReader reader = image.getRgbPixelReader();
            int p = 0;

            for (int iy = 0; iy < this._size.h * resolution; iy += resolution)
            {
                //解像度分の点を取る。
                for (int ix = 0; ix < this._size.w * resolution; ix += resolution)
                {
                    int r, g, b;
                    r = g = b = 0;
                    for (int i2y = iy; i2y < iy + resolution; i2y++)
                    {
                        int cy = this._pickup_lt.y + i2y;
                        for (int i2x = ix; i2x < ix + resolution; i2x++)
                        {
                            //1ピクセルを作成
                            int    cx = this._pickup_lt.x + i2x;
                            double d  = cpara[6] * cx + cpara[7] * cy + 1.0;
                            int    x  = (int)((cpara[0] * cx + cpara[1] * cy + cpara[2]) / d);
                            int    y  = (int)((cpara[3] * cx + cpara[4] * cy + cpara[5]) / d);
                            if (x < 0)
                            {
                                x = 0;
                            }
                            if (x >= img_x)
                            {
                                x = img_x - 1;
                            }
                            if (y < 0)
                            {
                                y = 0;
                            }
                            if (y >= img_y)
                            {
                                y = img_y - 1;
                            }

                            reader.getPixel(x, y, rgb_tmp);
                            r += rgb_tmp[0];
                            g += rgb_tmp[1];
                            b += rgb_tmp[2];
                        }
                    }
                    r /= res_pix;
                    g /= res_pix;
                    b /= res_pix;
                    this._patdata[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff));
                    p++;
                }
            }
            //ピクセル問い合わせ
            //ピクセルセット
            return(true);
        }
        private int detectDataBitsIndex(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, double[] o_index_row, double[] o_index_col)
        {
            //周波数を測定
            int[] freq_index1 = this.__detectDataBitsIndex_freq_index1;
            int[] freq_index2 = this.__detectDataBitsIndex_freq_index2;


            int frq_t = getRowFrequency(i_reader, i_raster_size, i_th.lt_y, i_th.th_h, i_th.th_l, freq_index1);
            int frq_b = getRowFrequency(i_reader, i_raster_size, i_th.rb_y, i_th.th_h, i_th.th_l, freq_index2);

            //周波数はまとも?
            if ((frq_t < 0 && frq_b < 0) || frq_t == frq_b)
            {
                return(-1);
            }
            //タイミングパターンからインデクスを作成
            int freq_h, freq_v;

            int[] index;
            if (frq_t > frq_b)
            {
                freq_h = frq_t;
                index  = freq_index1;
            }
            else
            {
                freq_h = frq_b;
                index  = freq_index2;
            }
            for (int i = 0; i < freq_h + freq_h - 1; i++)
            {
                o_index_row[i * 2]     = ((index[i + 1] - index[i]) * 2 / 5 + index[i]) + FRQ_EDGE;
                o_index_row[i * 2 + 1] = ((index[i + 1] - index[i]) * 3 / 5 + index[i]) + FRQ_EDGE;
            }


            int frq_l = getColFrequency(i_reader, i_raster_size, i_th.lt_x, i_th.th_h, i_th.th_l, freq_index1);
            int frq_r = getColFrequency(i_reader, i_raster_size, i_th.rb_x, i_th.th_h, i_th.th_l, freq_index2);

            //周波数はまとも?
            if ((frq_l < 0 && frq_r < 0) || frq_l == frq_r)
            {
                return(-1);
            }
            //タイミングパターンからインデクスを作成
            if (frq_l > frq_r)
            {
                freq_v = frq_l;
                index  = freq_index1;
            }
            else
            {
                freq_v = frq_r;
                index  = freq_index2;
            }
            //同じ周期?
            if (freq_v != freq_h)
            {
                return(-1);
            }

            for (int i = 0; i < freq_v + freq_v - 1; i++)
            {
                int w  = index[i];
                int w2 = index[i + 1] - w;
                o_index_col[i * 2]     = ((w2) * 2 / 5 + w) + FRQ_EDGE;
                o_index_col[i * 2 + 1] = ((w2) * 3 / 5 + w) + FRQ_EDGE;
            }
            //Lv4以上は無理
            if (freq_v > MAX_FREQ)
            {
                return(-1);
            }
            return(freq_v);
        }
        /**
         * 指定した場所のピクセル値を調査して、閾値を計算して返します。
         * @param i_reader
         * @param i_x
         * @param i_y
         * @return
         * @throws NyARException
         */
        public void detectThresholdValue(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, TThreshold o_threshold)
        {
            int[] th_pixels = this._th_pixels;

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

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

            //右上のピックアップ領域からピクセルを得る(50-74)
            rectPixels(i_reader, i_raster_size, THRESHOLD_SAMPLE_RB, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE * 2, th_pixels);

            //右下のピックアップ領域からピクセルを得る(75-99)
            rectPixels(i_reader, i_raster_size, THRESHOLD_SAMPLE_RB, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE * 3, th_pixels);

            THighAndLow hl = this.__detectThresholdValue_hl;

            //Ptailで求めたピクセル平均
            getPtailHighAndLow(th_pixels, hl);



            //閾値中心
            int th = (hl.h + hl.l) / 2;
            //ヒステリシス(差分の20%)
            int th_sub = (hl.h - hl.l) / 5;

            o_threshold.th   = th;
            o_threshold.th_h = th + th_sub; //ヒステリシス付き閾値
            o_threshold.th_l = th - th_sub; //ヒステリシス付き閾値

            //エッジを計算(明点重心)
            int            lt_x, lt_y, lb_x, lb_y, rt_x, rt_y, rb_x, rb_y;
            NyARIntPoint2d tpt = this.__detectThresholdValue_tpt;

            //LT
            if (getHighPixelCenter(0, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                lt_x = tpt.x * THRESHOLD_STEP;
                lt_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                lt_x = 11;
                lt_y = 11;
            }
            //LB
            if (getHighPixelCenter(THRESHOLD_SAMPLE * 1, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                lb_x = tpt.x * THRESHOLD_STEP;
                lb_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                lb_x = 11;
                lb_y = -1;
            }
            //RT
            if (getHighPixelCenter(THRESHOLD_SAMPLE * 2, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                rt_x = tpt.x * THRESHOLD_STEP;
                rt_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                rt_x = -1;
                rt_y = 11;
            }
            //RB
            if (getHighPixelCenter(THRESHOLD_SAMPLE * 3, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                rb_x = tpt.x * THRESHOLD_STEP;
                rb_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                rb_x = -1;
                rb_y = -1;
            }
            //トラッキング開始位置の決定
            o_threshold.lt_x = (lt_x + lb_x) / 2 + THRESHOLD_SAMPLE_LT - 1;
            o_threshold.rb_x = (rt_x + rb_x) / 2 + THRESHOLD_SAMPLE_RB + 1;
            o_threshold.lt_y = (lt_y + rt_y) / 2 + THRESHOLD_SAMPLE_LT - 1;
            o_threshold.rb_y = (lb_y + rb_y) / 2 + THRESHOLD_SAMPLE_RB + 1;
            return;
        }
        /**
         * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。
         * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
         * 検出した場合、関数は失敗します。
         *
         * @param i_y1
         * @param i_y2
         * @param i_th_h
         * @param i_th_l
         * @param o_edge_index
         * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。
         * [FRQ_POINTS]以上の配列を指定してください。
         * @return
         * @throws NyARException
         */
        public int getRowFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_y1, int i_th_h, int i_th_l, int[] o_edge_index)
        {
            //3,4,5,6,7,8,9,10
            int[] freq_count_table = this._freq_count_table;
            //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列
            int[] freq_table = this._freq_table;
            //初期化
            double[] cpara       = this._cparam;
            int[]    ref_x       = this._ref_x;
            int[]    ref_y       = this._ref_y;
            int[]    pixcel_temp = this._pixcel_temp;
            for (int i = 0; i < 10; i++)
            {
                freq_count_table[i] = 0;
            }
            for (int i = 0; i < 110; i++)
            {
                freq_table[i] = 0;
            }
            int raster_width  = i_raster_size.w;
            int raster_height = i_raster_size.h;

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

            //10-20ピクセル目からタイミングパターンを検出
            for (int i = 0; i < FREQ_SAMPLE_NUM; i++)
            {
                //2行分のピクセルインデックスを計算
                double cy0     = 1 + i_y1 + i;
                double cpy0_12 = cpara[1] * cy0 + cpara[2];
                double cpy0_45 = cpara[4] * cy0 + cpara[5];
                double cpy0_7  = cpara[7] * cy0 + 1.0;

                int pt = 0;
                for (int i2 = 0; i2 < FRQ_POINTS; i2++)
                {
                    double cx0 = 1 + i2 * FRQ_STEP + FRQ_EDGE;
                    double d   = (cpara_6 * cx0) + cpy0_7;
                    int    x   = (int)((cpara_0 * cx0 + cpy0_12) / d);
                    int    y   = (int)((cpara_3 * cx0 + cpy0_45) / d);
                    if (x < 0 || y < 0 || x >= raster_width || y >= raster_height)
                    {
                        return(-1);
                    }
                    ref_x[pt] = x;
                    ref_y[pt] = y;
                    pt++;
                }

                //ピクセルを取得(入力画像を多様化するならここから先を調整すること)
                i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp);

                //o_edge_indexを一時的に破壊して調査する
                int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index);

                //周期は3-10であること
                if (freq_t < MIN_FREQ || freq_t > MAX_FREQ)
                {
                    continue;
                }
                //周期は等間隔であること
                if (!checkFreqWidth(o_edge_index, freq_t))
                {
                    continue;
                }
                //検出カウンタを追加
                freq_count_table[freq_t]++;
                int table_st = (freq_t - 1) * freq_t;
                for (int i2 = 0; i2 < freq_t * 2; i2++)
                {
                    freq_table[table_st + i2] += o_edge_index[i2];
                }
            }
            return(getMaxFreq(freq_count_table, freq_table, o_edge_index));
        }
        //分割数16未満になると少し遅くなるかも。
        private void updateExtpat(INyARRgbRaster image, NyARMat i_cpara, int i_xdiv2, int i_ydiv2)
        {
            int i, j;
            int r, g, b;
            //ピクセルリーダーを取得
            int    pat_size_w  = this._size.w;
            int    xdiv        = i_xdiv2 / pat_size_w;   // xdiv = xdiv2/Config.AR_PATT_SIZE_X;
            int    ydiv        = i_ydiv2 / this._size.h; // ydiv = ydiv2/Config.AR_PATT_SIZE_Y;
            int    xdiv_x_ydiv = xdiv * ydiv;
            double reciprocal;

            double[][] para   = i_cpara.getArray();
            double     para00 = para[0 * 3 + 0][0];
            double     para01 = para[0 * 3 + 1][0];
            double     para02 = para[0 * 3 + 2][0];
            double     para10 = para[1 * 3 + 0][0];
            double     para11 = para[1 * 3 + 1][0];
            double     para12 = para[1 * 3 + 2][0];
            double     para20 = para[2 * 3 + 0][0];
            double     para21 = para[2 * 3 + 1][0];

            INyARRgbPixelReader reader = image.getRgbPixelReader();
            int img_width  = image.getWidth();
            int img_height = image.getHeight();

            //ワークバッファの準備
            reservWorkBuffers(xdiv, ydiv);
            double[] xw      = this.__updateExtpat_xw;
            double[] yw      = this.__updateExtpat_yw;
            int[]    xc      = this.__updateExtpat_xc;
            int[]    yc      = this.__updateExtpat_yc;
            int[]    rgb_set = this.__updateExtpat_rgbset;


            for (int iy = this._size.h - 1; iy >= 0; iy--)
            {
                for (int ix = pat_size_w - 1; ix >= 0; ix--)
                {
                    //xw,ywマップを作成
                    reciprocal = 1.0 / i_xdiv2;
                    for (i = xdiv - 1; i >= 0; i--)
                    {
                        xw[i] = LT_POS + SQ_SIZE * (ix * xdiv + i + 0.5) * reciprocal;
                    }
                    reciprocal = 1.0 / i_ydiv2;
                    for (i = ydiv - 1; i >= 0; i--)
                    {
                        yw[i] = LT_POS + SQ_SIZE * (iy * ydiv + i + 0.5) * reciprocal;
                    }
                    //1ピクセルを構成するピクセル座標の集合をxc,yc配列に取得
                    int number_of_pix = 0;
                    for (i = ydiv - 1; i >= 0; i--)
                    {
                        double para01_x_yw_para02 = para01 * yw[i] + para02;
                        double para11_x_yw_para12 = para11 * yw[i] + para12;
                        double para12_x_yw_para22 = para21 * yw[i] + 1.0;
                        for (j = xdiv - 1; j >= 0; j--)
                        {
                            double d = para20 * xw[j] + para12_x_yw_para22;
                            if (d == 0)
                            {
                                throw new NyARException();
                            }
                            int xcw = (int)((para00 * xw[j] + para01_x_yw_para02) / d);
                            int ycw = (int)((para10 * xw[j] + para11_x_yw_para12) / d);
                            if (xcw < 0 || xcw >= img_width || ycw < 0 || ycw >= img_height)
                            {
                                continue;
                            }
                            xc[number_of_pix] = xcw;
                            yc[number_of_pix] = ycw;
                            number_of_pix++;
                        }
                    }
                    //1ピクセル分の配列を取得
                    reader.getPixelSet(xc, yc, number_of_pix, rgb_set);
                    r = g = b = 0;
                    for (i = number_of_pix * 3 - 1; i >= 0; i -= 3)
                    {
                        r += rgb_set[i - 2]; // R
                        g += rgb_set[i - 1]; // G
                        b += rgb_set[i];     // B
                    }
                    //1ピクセル確定
                    this._patdata[iy * pat_size_w + ix] = (((r / xdiv_x_ydiv) & 0xff) << 16) | (((g / xdiv_x_ydiv) & 0xff) << 8) | (((b / xdiv_x_ydiv) & 0xff));
                }
            }
            return;
        }
        private void multiPixel_ANY(int pk_l, int pk_t, int in_w, int in_h, int i_resolution, double[] cpara, byte[] i_in_buf, INyARRgbRaster o_out)
        {
            int res_pix = i_resolution * i_resolution;

            INyARRgbPixelReader out_reader = o_out.getRgbPixelReader();

            //ピクセルリーダーを取得
            double cp0 = cpara[0];
            double cp3 = cpara[3];
            double cp6 = cpara[6];
            double cp1 = cpara[1];
            double cp4 = cpara[4];
            double cp7 = cpara[7];
            double cp2 = cpara[2];
            double cp5 = cpara[5];

            int out_w = o_out.getWidth();
            int out_h = o_out.getHeight();

            for (int iy = out_h - 1; iy >= 0; iy--)
            {
                //解像度分の点を取る。
                for (int ix = out_w - 1; ix >= 0; ix--)
                {
                    int r, g, b;
                    r = g = b = 0;
                    int    cy = pk_t + iy * i_resolution;
                    int    cx = pk_l + ix * i_resolution;
                    double cp7_cy_1_cp6_cx_b   = cp7 * cy + 1.0 + cp6 * cx;
                    double cp1_cy_cp2_cp0_cx_b = cp1 * cy + cp2 + cp0 * cx;
                    double cp4_cy_cp5_cp3_cx_b = cp4 * cy + cp5 + cp3 * cx;
                    for (int i2y = i_resolution - 1; i2y >= 0; i2y--)
                    {
                        double cp7_cy_1_cp6_cx   = cp7_cy_1_cp6_cx_b;
                        double cp1_cy_cp2_cp0_cx = cp1_cy_cp2_cp0_cx_b;
                        double cp4_cy_cp5_cp3_cx = cp4_cy_cp5_cp3_cx_b;
                        for (int i2x = i_resolution - 1; i2x >= 0; i2x--)
                        {
                            //1ピクセルを作成
                            double d = 1 / (cp7_cy_1_cp6_cx);
                            int    x = (int)((cp1_cy_cp2_cp0_cx) * d);
                            int    y = (int)((cp4_cy_cp5_cp3_cx) * d);
                            if (x < 0)
                            {
                                x = 0;
                            }
                            else if (x >= in_w)
                            {
                                x = in_w - 1;
                            }
                            if (y < 0)
                            {
                                y = 0;
                            }
                            else if (y >= in_h)
                            {
                                y = in_h - 1;
                            }

                            int bp = (x + y * in_w) * 4;
                            r += (i_in_buf[bp + 2] & 0xff);
                            g += (i_in_buf[bp + 1] & 0xff);
                            b += (i_in_buf[bp + 0] & 0xff);
                            cp7_cy_1_cp6_cx   += cp6;
                            cp1_cy_cp2_cp0_cx += cp0;
                            cp4_cy_cp5_cp3_cx += cp3;
                        }
                        cp7_cy_1_cp6_cx_b   += cp7;
                        cp1_cy_cp2_cp0_cx_b += cp1;
                        cp4_cy_cp5_cp3_cx_b += cp4;
                    }
                    out_reader.setPixel(ix, iy, r / res_pix, g / res_pix, b / res_pix);
                }
            }
            return;
        }
        private void onePixel_INT1D_X8R8G8B8_32(int pk_l, int pk_t, int in_w, int in_h, double[] cpara, INyARRgbPixelReader i_in_reader, INyARRgbRaster o_out)
        {
            Debug.Assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
            int[] rgb_tmp  = this.__pickFromRaster_rgb_tmp;
            int[] pat_data = (int[])o_out.getBuffer();

            //ピクセルリーダーを取得
            double cp0 = cpara[0];
            double cp3 = cpara[3];
            double cp6 = cpara[6];
            double cp1 = cpara[1];
            double cp4 = cpara[4];
            double cp7 = cpara[7];

            int    out_w      = o_out.getWidth();
            int    out_h      = o_out.getHeight();
            double cp7_cy_1   = cp7 * pk_t + 1.0 + cp6 * pk_l;
            double cp1_cy_cp2 = cp1 * pk_t + cpara[2] + cp0 * pk_l;
            double cp4_cy_cp5 = cp4 * pk_t + cpara[5] + cp3 * pk_l;
            int    p          = 0;

            for (int iy = out_h - 1; iy >= 0; iy--)
            {
                //解像度分の点を取る。
                double cp7_cy_1_cp6_cx   = cp7_cy_1;
                double cp1_cy_cp2_cp0_cx = cp1_cy_cp2;
                double cp4_cy_cp5_cp3_cx = cp4_cy_cp5;

                for (int ix = out_w - 1; ix >= 0; ix--)
                {
                    //1ピクセルを作成
                    double d = 1 / (cp7_cy_1_cp6_cx);
                    int    x = (int)((cp1_cy_cp2_cp0_cx) * d);
                    int    y = (int)((cp4_cy_cp5_cp3_cx) * d);
                    if (x < 0)
                    {
                        x = 0;
                    }
                    else if (x >= in_w)
                    {
                        x = in_w - 1;
                    }
                    if (y < 0)
                    {
                        y = 0;
                    }
                    else if (y >= in_h)
                    {
                        y = in_h - 1;
                    }

                    i_in_reader.getPixel(x, y, rgb_tmp);
                    cp7_cy_1_cp6_cx   += cp6;
                    cp1_cy_cp2_cp0_cx += cp0;
                    cp4_cy_cp5_cp3_cx += cp3;

                    pat_data[p] = (rgb_tmp[0] << 16) | (rgb_tmp[1] << 8) | ((rgb_tmp[2] & 0xff));
                    p++;
                }
                cp7_cy_1   += cp7;
                cp1_cy_cp2 += cp1;
                cp4_cy_cp5 += cp4;
            }
            return;
        }
        private void onePixel_ANY(int pk_l, int pk_t, int in_w, int in_h, double[] cpara, byte[] i_in_buf, INyARRgbRaster o_out)
        {
            INyARRgbPixelReader out_reader = o_out.getRgbPixelReader();

            //ピクセルリーダーを取得
            double cp0 = cpara[0];
            double cp3 = cpara[3];
            double cp6 = cpara[6];
            double cp1 = cpara[1];
            double cp4 = cpara[4];
            double cp7 = cpara[7];

            int    out_w = o_out.getWidth();
            int    out_h = o_out.getHeight();
            double cp7_cy_1 = cp7 * pk_t + 1.0 + cp6 * pk_l;
            double cp1_cy_cp2 = cp1 * pk_t + cpara[2] + cp0 * pk_l;
            double cp4_cy_cp5 = cp4 * pk_t + cpara[5] + cp3 * pk_l;
            int    r, g, b;

            for (int iy = 0; iy < out_h; iy++)
            {
                //解像度分の点を取る。
                double cp7_cy_1_cp6_cx   = cp7_cy_1;
                double cp1_cy_cp2_cp0_cx = cp1_cy_cp2;
                double cp4_cy_cp5_cp3_cx = cp4_cy_cp5;

                for (int ix = 0; ix < out_w; ix++)
                {
                    //1ピクセルを作成
                    double d = 1 / (cp7_cy_1_cp6_cx);
                    int    x = (int)((cp1_cy_cp2_cp0_cx) * d);
                    int    y = (int)((cp4_cy_cp5_cp3_cx) * d);
                    if (x < 0)
                    {
                        x = 0;
                    }
                    else if (x >= in_w)
                    {
                        x = in_w - 1;
                    }
                    if (y < 0)
                    {
                        y = 0;
                    }
                    else if (y >= in_h)
                    {
                        y = in_h - 1;
                    }

                    int bp = (x + y * in_w) * 4;
                    r = (i_in_buf[bp + 2] & 0xff);
                    g = (i_in_buf[bp + 1] & 0xff);
                    b = (i_in_buf[bp + 0] & 0xff);
                    cp7_cy_1_cp6_cx   += cp6;
                    cp1_cy_cp2_cp0_cx += cp0;
                    cp4_cy_cp5_cp3_cx += cp3;

                    out_reader.setPixel(ix, iy, r, g, b);
                }
                cp7_cy_1   += cp7;
                cp1_cy_cp2 += cp1;
                cp4_cy_cp5 += cp4;
            }
            return;
        }
        private void multiPixel_INT1D_X8R8G8B8_32(int pk_l, int pk_t, int in_w, int in_h, int i_resolution, double[] cpara, INyARRgbPixelReader i_in_reader, INyARRgbRaster o_out)
        {
            Debug.Assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
            int res_pix = i_resolution * i_resolution;

            int[] rgb_tmp  = this.__pickFromRaster_rgb_tmp;
            int[] pat_data = (int[])o_out.getBuffer();

            //ピクセルリーダーを取得
            double cp0 = cpara[0];
            double cp3 = cpara[3];
            double cp6 = cpara[6];
            double cp1 = cpara[1];
            double cp4 = cpara[4];
            double cp7 = cpara[7];
            double cp2 = cpara[2];
            double cp5 = cpara[5];

            int out_w = o_out.getWidth();
            int out_h = o_out.getHeight();
            int p     = (out_w * out_h - 1);

            for (int iy = out_h - 1; iy >= 0; iy--)
            {
                //解像度分の点を取る。
                for (int ix = out_w - 1; ix >= 0; ix--)
                {
                    int r, g, b;
                    r = g = b = 0;
                    int    cy = pk_t + iy * i_resolution;
                    int    cx = pk_l + ix * i_resolution;
                    double cp7_cy_1_cp6_cx_b   = cp7 * cy + 1.0 + cp6 * cx;
                    double cp1_cy_cp2_cp0_cx_b = cp1 * cy + cp2 + cp0 * cx;
                    double cp4_cy_cp5_cp3_cx_b = cp4 * cy + cp5 + cp3 * cx;
                    for (int i2y = i_resolution - 1; i2y >= 0; i2y--)
                    {
                        double cp7_cy_1_cp6_cx   = cp7_cy_1_cp6_cx_b;
                        double cp1_cy_cp2_cp0_cx = cp1_cy_cp2_cp0_cx_b;
                        double cp4_cy_cp5_cp3_cx = cp4_cy_cp5_cp3_cx_b;
                        for (int i2x = i_resolution - 1; i2x >= 0; i2x--)
                        {
                            //1ピクセルを作成
                            double d = 1 / (cp7_cy_1_cp6_cx);
                            int    x = (int)((cp1_cy_cp2_cp0_cx) * d);
                            int    y = (int)((cp4_cy_cp5_cp3_cx) * d);
                            if (x < 0)
                            {
                                x = 0;
                            }
                            else if (x >= in_w)
                            {
                                x = in_w - 1;
                            }
                            if (y < 0)
                            {
                                y = 0;
                            }
                            else if (y >= in_h)
                            {
                                y = in_h - 1;
                            }

                            i_in_reader.getPixel(x, y, rgb_tmp);
                            r += rgb_tmp[0];
                            g += rgb_tmp[1];
                            b += rgb_tmp[2];
                            cp7_cy_1_cp6_cx   += cp6;
                            cp1_cy_cp2_cp0_cx += cp0;
                            cp4_cy_cp5_cp3_cx += cp3;
                        }
                        cp7_cy_1_cp6_cx_b   += cp7;
                        cp1_cy_cp2_cp0_cx_b += cp1;
                        cp4_cy_cp5_cp3_cx_b += cp4;
                    }
                    r          /= res_pix;
                    g          /= res_pix;
                    b          /= res_pix;
                    pat_data[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff));
                    p--;
                }
            }
            return;
        }
        private void onePixel_ANY(int pk_l, int pk_t, int in_w, int in_h, double[] cpara, INyARRgbPixelReader i_in_reader, INyARRgbRaster o_out)
        {
            int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;
            INyARRgbPixelReader out_reader = o_out.getRgbPixelReader();

            //ピクセルリーダーを取得
            double cp0 = cpara[0];
            double cp3 = cpara[3];
            double cp6 = cpara[6];
            double cp1 = cpara[1];
            double cp4 = cpara[4];
            double cp7 = cpara[7];

            int    out_w      = o_out.getWidth();
            int    out_h      = o_out.getHeight();
            double cp7_cy_1   = cp7 * pk_t + 1.0 + cp6 * pk_l;
            double cp1_cy_cp2 = cp1 * pk_t + cpara[2] + cp0 * pk_l;
            double cp4_cy_cp5 = cp4 * pk_t + cpara[5] + cp3 * pk_l;

            for (int iy = 0; iy < out_h; iy++)
            {
                //解像度分の点を取る。
                double cp7_cy_1_cp6_cx   = cp7_cy_1;
                double cp1_cy_cp2_cp0_cx = cp1_cy_cp2;
                double cp4_cy_cp5_cp3_cx = cp4_cy_cp5;

                for (int ix = 0; ix < out_w; ix++)
                {
                    //1ピクセルを作成
                    double d = 1 / (cp7_cy_1_cp6_cx);
                    int    x = (int)((cp1_cy_cp2_cp0_cx) * d);
                    int    y = (int)((cp4_cy_cp5_cp3_cx) * d);
                    if (x < 0)
                    {
                        x = 0;
                    }
                    else if (x >= in_w)
                    {
                        x = in_w - 1;
                    }
                    if (y < 0)
                    {
                        y = 0;
                    }
                    else if (y >= in_h)
                    {
                        y = in_h - 1;
                    }

                    i_in_reader.getPixel(x, y, rgb_tmp);
                    cp7_cy_1_cp6_cx   += cp6;
                    cp1_cy_cp2_cp0_cx += cp0;
                    cp4_cy_cp5_cp3_cx += cp3;

                    out_reader.setPixel(ix, iy, rgb_tmp);
                }
                cp7_cy_1   += cp7;
                cp1_cy_cp2 += cp1;
                cp4_cy_cp5 += cp4;
            }
            return;
        }
Exemple #22
0
        public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt)
        {
            int i2x, i2y;//プライム変数
            int x, y;
            int w;
            int r, g, b;

            int resolution = this._resolution;
            int res_pix    = resolution * resolution;
            int img_x      = image.getWidth();
            int img_y      = image.getHeight();

            int[] rgb_tmp = this._rgb_temp;
            int[] rgb_px  = this._rgb_px;
            int[] rgb_py  = this._rgb_py;

            double[] cp1cy_cp2 = this._cp1cy_cp2;
            double[] cp4cy_cp5 = this._cp4cy_cp5;
            double[] cp7cy_1   = this._cp7cy_1;

            double cp0 = i_cpara[0];
            double cp3 = i_cpara[3];
            double cp6 = i_cpara[6];
            double cp1 = i_cpara[1];
            double cp2 = i_cpara[2];
            double cp4 = i_cpara[4];
            double cp5 = i_cpara[5];
            double cp7 = i_cpara[7];


            int pick_y = this._lt_ref.y;
            int pick_x = this._lt_ref.x;
            //ピクセルリーダーを取得
            INyARRgbPixelReader reader = image.getRgbPixelReader();
            int p = 0;


            for (int iy = 0; iy < this._size_ref.h * resolution; iy += resolution)
            {
                w            = pick_y + iy;
                cp1cy_cp2[0] = cp1 * w + cp2;
                cp4cy_cp5[0] = cp4 * w + cp5;
                cp7cy_1[0]   = cp7 * w + 1.0;
                for (i2y = 1; i2y < resolution; i2y++)
                {
                    cp1cy_cp2[i2y] = cp1cy_cp2[i2y - 1] + cp1;
                    cp4cy_cp5[i2y] = cp4cy_cp5[i2y - 1] + cp4;
                    cp7cy_1[i2y]   = cp7cy_1[i2y - 1] + cp7;
                }
                //解像度分の点を取る。

                for (int ix = 0; ix < this._size_ref.w * resolution; ix += resolution)
                {
                    int n = 0;
                    w = pick_x + ix;
                    for (i2y = resolution - 1; i2y >= 0; i2y--)
                    {
                        double cp0cx = cp0 * w + cp1cy_cp2[i2y];
                        double cp6cx = cp6 * w + cp7cy_1[i2y];
                        double cp3cx = cp3 * w + cp4cy_cp5[i2y];

                        double m = 1 / (cp6cx);
                        double d = -cp6 / (cp6cx * (cp6cx + cp6));

                        double m2 = cp0cx * m;
                        double m3 = cp3cx * m;
                        double d2 = cp0cx * d + cp0 * (m + d);
                        double d3 = cp3cx * d + cp3 * (m + d);
                        for (i2x = resolution - 1; i2x >= 0; i2x--)
                        {
                            //1ピクセルを作成
                            x = rgb_px[n] = (int)(m2);
                            y = rgb_py[n] = (int)(m3);
                            if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                            {
                                if (x < 0)
                                {
                                    rgb_px[n] = 0;
                                }
                                else if (x >= img_x)
                                {
                                    rgb_px[n] = img_x - 1;
                                }
                                if (y < 0)
                                {
                                    rgb_py[n] = 0;
                                }
                                else if (y >= img_y)
                                {
                                    rgb_py[n] = img_y - 1;
                                }
                            }
                            n++;
                            m2 += d2;
                            m3 += d3;
                        }
                    }
                    reader.getPixelSet(rgb_px, rgb_py, res_pix, rgb_tmp);
                    r = g = b = 0;
                    for (int i = res_pix * 3 - 1; i > 0;)
                    {
                        b += rgb_tmp[i--];
                        g += rgb_tmp[i--];
                        r += rgb_tmp[i--];
                    }
                    r        /= res_pix;
                    g        /= res_pix;
                    b        /= res_pix;
                    o_patt[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff));
                    p++;
                }
            }
            return;
        }
Exemple #23
0
        public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt)
        {
            double d0, m0;
            int    x, y;

            int img_x  = image.getWidth();
            int img_y  = image.getHeight();
            int patt_w = this._size_ref.w;

            int[] rgb_tmp = this._rgb_temp;
            int[] rgb_px  = this._rgb_px;
            int[] rgb_py  = this._rgb_py;



            double cp0 = i_cpara[0];
            double cp3 = i_cpara[3];
            double cp6 = i_cpara[6];
            double cp1 = i_cpara[1];
            double cp4 = i_cpara[4];
            double cp7 = i_cpara[7];


            int pick_y = this._lt_ref.y;
            int pick_x = this._lt_ref.x;
            //ピクセルリーダーを取得
            INyARRgbPixelReader reader = image.getRgbPixelReader();
            int p = 0;


            double cp0cx0, cp3cx0;
            double cp1cy_cp20 = cp1 * pick_y + i_cpara[2] + cp0 * pick_x;
            double cp4cy_cp50 = cp4 * pick_y + i_cpara[5] + cp3 * pick_x;
            double cp7cy_10   = cp7 * pick_y + 1.0 + cp6 * pick_x;


            for (int iy = this._size_ref.h - 1; iy >= 0; iy--)
            {
                m0 = 1 / (cp7cy_10);
                d0 = -cp6 / (cp7cy_10 * (cp7cy_10 + cp6));

                cp0cx0 = cp1cy_cp20;
                cp3cx0 = cp4cy_cp50;

                //ピックアップシーケンス

                //0番目のピクセル(検査対象)をピックアップ


                for (int ix = patt_w - 1; ix >= 0; ix--)
                {
                    //1ピクセルを作成
                    x = rgb_px[ix] = (int)(cp0cx0 * m0);
                    y = rgb_py[ix] = (int)(cp3cx0 * m0);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[ix] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[ix] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[ix] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[ix] = img_y - 1;
                        }
                    }
                    cp0cx0 += cp0;
                    cp3cx0 += cp3;
                    m0     += d0;
                }

                cp1cy_cp20 += cp1;
                cp4cy_cp50 += cp4;
                cp7cy_10   += cp7;

                reader.getPixelSet(rgb_px, rgb_py, patt_w, rgb_tmp);
                for (int ix = patt_w - 1; ix >= 0; ix--)
                {
                    int idx = ix * 3;
                    o_patt[p] = (rgb_tmp[idx] << 16) | (rgb_tmp[idx + 1] << 8) | ((rgb_tmp[idx + 2] & 0xff));
                    p++;
                }
            }

            return;
        }
Exemple #24
0
        public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt)
        {
            int    x, y;
            double d, m;
            double cp6cx, cp0cx, cp3cx;

            int[] rgb_px = this._rgb_px;
            int[] rgb_py = this._rgb_py;

            int r, g, b;
            //遠近法のパラメータを計算

            int img_x = image.getWidth();
            int img_y = image.getHeight();

            int[]  rgb_tmp = this._rgb_temp;
            double cp0     = i_cpara[0];
            double cp3     = i_cpara[3];
            double cp6     = i_cpara[6];
            double cp1     = i_cpara[1];
            double cp2     = i_cpara[2];
            double cp4     = i_cpara[4];
            double cp5     = i_cpara[5];
            double cp7     = i_cpara[7];


            int pick_lt_x = this._lt_ref.x;
            //ピクセルリーダーを取得
            INyARRgbPixelReader reader = image.getRgbPixelReader();


            int p  = 0;
            int py = this._lt_ref.y;

            for (int iy = this._size_ref.h - 1; iy >= 0; iy--, py += 4)
            {
                double cp1cy_cp2_0 = cp1 * py + cp2;
                double cp4cy_cp5_0 = cp4 * py + cp5;
                double cp7cy_1_0   = cp7 * py + 1.0;

                double cp1cy_cp2_1 = cp1cy_cp2_0 + cp1;
                double cp1cy_cp2_2 = cp1cy_cp2_1 + cp1;
                double cp1cy_cp2_3 = cp1cy_cp2_2 + cp1;

                double cp4cy_cp5_1 = cp4cy_cp5_0 + cp4;
                double cp4cy_cp5_2 = cp4cy_cp5_1 + cp4;
                double cp4cy_cp5_3 = cp4cy_cp5_2 + cp4;

                int px = pick_lt_x;
                //解像度分の点を取る。
                for (int ix = this._size_ref.w - 1; ix >= 0; ix--, px += 4)
                {
                    cp6cx = cp6 * px;
                    cp0cx = cp0 * px;
                    cp3cx = cp3 * px;

                    cp6cx += cp7cy_1_0;
                    m      = 1 / cp6cx;
                    d      = -cp7 / ((cp6cx + cp7) * cp6cx);

                    //1ピクセルを作成[0,0]
                    x = rgb_px[0] = (int)((cp0cx + cp1cy_cp2_0) * m);
                    y = rgb_py[0] = (int)((cp3cx + cp4cy_cp5_0) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[0] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[0] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[0] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[0] = img_y - 1;
                        }
                    }

                    //1ピクセルを作成[0,1]
                    m += d;
                    x  = rgb_px[4] = (int)((cp0cx + cp1cy_cp2_1) * m);
                    y  = rgb_py[4] = (int)((cp3cx + cp4cy_cp5_1) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[4] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[4] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[4] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[4] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[0,2]
                    m += d;
                    x  = rgb_px[8] = (int)((cp0cx + cp1cy_cp2_2) * m);
                    y  = rgb_py[8] = (int)((cp3cx + cp4cy_cp5_2) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[8] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[8] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[8] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[8] = img_y - 1;
                        }
                    }

                    //1ピクセルを作成[0,3]
                    m += d;
                    x  = rgb_px[12] = (int)((cp0cx + cp1cy_cp2_3) * m);
                    y  = rgb_py[12] = (int)((cp3cx + cp4cy_cp5_3) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[12] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[12] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[12] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[12] = img_y - 1;
                        }
                    }

                    cp6cx += cp6;
                    cp0cx += cp0;
                    cp3cx += cp3;

                    m = 1 / cp6cx;
                    d = -cp7 / ((cp6cx + cp7) * cp6cx);

                    //1ピクセルを作成[1,0]
                    x = rgb_px[1] = (int)((cp0cx + cp1cy_cp2_0) * m);
                    y = rgb_py[1] = (int)((cp3cx + cp4cy_cp5_0) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[1] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[1] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[1] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[1] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[1,1]
                    m += d;
                    x  = rgb_px[5] = (int)((cp0cx + cp1cy_cp2_1) * m);
                    y  = rgb_py[5] = (int)((cp3cx + cp4cy_cp5_1) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[5] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[5] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[5] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[5] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[1,2]
                    m += d;
                    x  = rgb_px[9] = (int)((cp0cx + cp1cy_cp2_2) * m);
                    y  = rgb_py[9] = (int)((cp3cx + cp4cy_cp5_2) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[9] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[9] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[9] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[9] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[1,3]
                    m += d;
                    x  = rgb_px[13] = (int)((cp0cx + cp1cy_cp2_3) * m);
                    y  = rgb_py[13] = (int)((cp3cx + cp4cy_cp5_3) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[13] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[13] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[13] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[13] = img_y - 1;
                        }
                    }

                    cp6cx += cp6;
                    cp0cx += cp0;
                    cp3cx += cp3;

                    m = 1 / cp6cx;
                    d = -cp7 / ((cp6cx + cp7) * cp6cx);

                    //1ピクセルを作成[2,0]
                    x = rgb_px[2] = (int)((cp0cx + cp1cy_cp2_0) * m);
                    y = rgb_py[2] = (int)((cp3cx + cp4cy_cp5_0) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[2] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[2] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[2] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[2] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[2,1]
                    m += d;
                    x  = rgb_px[6] = (int)((cp0cx + cp1cy_cp2_1) * m);
                    y  = rgb_py[6] = (int)((cp3cx + cp4cy_cp5_1) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[6] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[6] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[6] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[6] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[2,2]
                    m += d;
                    x  = rgb_px[10] = (int)((cp0cx + cp1cy_cp2_2) * m);
                    y  = rgb_py[10] = (int)((cp3cx + cp4cy_cp5_2) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[10] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[10] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[10] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[10] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[2,3](ここ計算ずれします。)
                    m += d;
                    x  = rgb_px[14] = (int)((cp0cx + cp1cy_cp2_3) * m);
                    y  = rgb_py[14] = (int)((cp3cx + cp4cy_cp5_3) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[14] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[14] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[14] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[14] = img_y - 1;
                        }
                    }
                    cp6cx += cp6;
                    cp0cx += cp0;
                    cp3cx += cp3;

                    m = 1 / cp6cx;
                    d = -cp7 / ((cp6cx + cp7) * cp6cx);

                    //1ピクセルを作成[3,0]
                    x = rgb_px[3] = (int)((cp0cx + cp1cy_cp2_0) * m);
                    y = rgb_py[3] = (int)((cp3cx + cp4cy_cp5_0) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[3] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[3] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[3] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[3] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[3,1]
                    m += d;
                    x  = rgb_px[7] = (int)((cp0cx + cp1cy_cp2_1) * m);
                    y  = rgb_py[7] = (int)((cp3cx + cp4cy_cp5_1) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[7] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[7] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[7] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[7] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[3,2]
                    m += d;
                    x  = rgb_px[11] = (int)((cp0cx + cp1cy_cp2_2) * m);
                    y  = rgb_py[11] = (int)((cp3cx + cp4cy_cp5_2) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[11] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[11] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[11] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[11] = img_y - 1;
                        }
                    }
                    //1ピクセルを作成[3,3]
                    m += d;
                    x  = rgb_px[15] = (int)((cp0cx + cp1cy_cp2_3) * m);
                    y  = rgb_py[15] = (int)((cp3cx + cp4cy_cp5_3) * m);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[15] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[15] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[15] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[15] = img_y - 1;
                        }
                    }

                    reader.getPixelSet(rgb_px, rgb_py, 4 * 4, rgb_tmp);

                    r         = (rgb_tmp[0] + rgb_tmp[3] + rgb_tmp[6] + rgb_tmp[9] + rgb_tmp[12] + rgb_tmp[15] + rgb_tmp[18] + rgb_tmp[21] + rgb_tmp[24] + rgb_tmp[27] + rgb_tmp[30] + rgb_tmp[33] + rgb_tmp[36] + rgb_tmp[39] + rgb_tmp[42] + rgb_tmp[45]) / 16;
                    g         = (rgb_tmp[1] + rgb_tmp[4] + rgb_tmp[7] + rgb_tmp[10] + rgb_tmp[13] + rgb_tmp[16] + rgb_tmp[19] + rgb_tmp[22] + rgb_tmp[25] + rgb_tmp[28] + rgb_tmp[31] + rgb_tmp[34] + rgb_tmp[37] + rgb_tmp[40] + rgb_tmp[43] + rgb_tmp[46]) / 16;
                    b         = (rgb_tmp[2] + rgb_tmp[5] + rgb_tmp[8] + rgb_tmp[11] + rgb_tmp[14] + rgb_tmp[17] + rgb_tmp[20] + rgb_tmp[23] + rgb_tmp[26] + rgb_tmp[29] + rgb_tmp[32] + rgb_tmp[35] + rgb_tmp[38] + rgb_tmp[41] + rgb_tmp[44] + rgb_tmp[47]) / 16;
                    o_patt[p] = ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff));
                    p++;
                }
            }
            return;
        }
        /**
         * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。
         * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
         * 検出した場合、関数は失敗します。
         * 
         * @param i_y1
         * @param i_y2
         * @param i_th_h
         * @param i_th_l
         * @param o_edge_index
         * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。
         * [FRQ_POINTS]以上の配列を指定してください。
         * @return
         * @throws NyARException
         */
        public int getRowFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_y1, int i_th_h, int i_th_l, int[] o_edge_index)
        {
            //3,4,5,6,7,8,9,10
            int[] freq_count_table = this._freq_count_table;
            //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列
            int[] freq_table = this._freq_table;
            //初期化
            double[] cpara = this._cparam;
            int[] ref_x = this._ref_x;
            int[] ref_y = this._ref_y;
            int[] pixcel_temp = this._pixcel_temp;
            for (int i = 0; i < 10; i++)
            {
                freq_count_table[i] = 0;
            }
            for (int i = 0; i < 110; i++)
            {
                freq_table[i] = 0;
            }
            int raster_width = i_raster_size.w;
            int raster_height = i_raster_size.h;

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

            //10-20ピクセル目からタイミングパターンを検出
            for (int i = 0; i < FREQ_SAMPLE_NUM; i++)
            {
                //2行分のピクセルインデックスを計算
                double cy0 = 1 + i_y1 + i;
                double cpy0_12 = cpara[1] * cy0 + cpara[2];
                double cpy0_45 = cpara[4] * cy0 + cpara[5];
                double cpy0_7 = cpara[7] * cy0 + 1.0;

                int pt = 0;
                for (int i2 = 0; i2 < FRQ_POINTS; i2++)
                {
                    double cx0 = 1 + i2 * FRQ_STEP + FRQ_EDGE;
                    double d = (cpara_6 * cx0) + cpy0_7;
                    int x = (int)((cpara_0 * cx0 + cpy0_12) / d);
                    int y = (int)((cpara_3 * cx0 + cpy0_45) / d);
                    if (x < 0 || y < 0 || x >= raster_width || y >= raster_height)
                    {
                        return -1;
                    }
                    ref_x[pt] = x;
                    ref_y[pt] = y;
                    pt++;
                }

                //ピクセルを取得(入力画像を多様化するならここから先を調整すること)
                i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp);

                //o_edge_indexを一時的に破壊して調査する
                int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index);

                //周期は3-10であること
                if (freq_t < MIN_FREQ || freq_t > MAX_FREQ)
                {
                    continue;
                }
                //周期は等間隔であること
                if (!checkFreqWidth(o_edge_index, freq_t))
                {
                    continue;
                }
                //検出カウンタを追加
                freq_count_table[freq_t]++;
                int table_st = (freq_t - 1) * freq_t;
                for (int i2 = 0; i2 < freq_t * 2; i2++)
                {
                    freq_table[table_st + i2] += o_edge_index[i2];
                }
            }
            return getMaxFreq(freq_count_table, freq_table, o_edge_index);
        }
        public int getColFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_x1, int i_th_h, int i_th_l, int[] o_edge_index)
        {
            double[] cpara       = this._cparam;
            int[]    ref_x       = this._ref_x;
            int[]    ref_y       = this._ref_y;
            int[]    pixcel_temp = this._pixcel_temp;
            //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110
            //初期化
            int[] freq_count_table = this._freq_count_table;
            for (int i = 0; i < 10; i++)
            {
                freq_count_table[i] = 0;
            }
            int[] freq_table = this._freq_table;
            for (int i = 0; i < 110; i++)
            {
                freq_table[i] = 0;
            }
            int raster_width  = i_raster_size.w;
            int raster_height = i_raster_size.h;


            double cpara7 = cpara[7];
            double cpara4 = cpara[4];
            double cpara1 = cpara[1];

            //基準点から4ピクセルを参照パターンとして抽出
            for (int i = 0; i < FREQ_SAMPLE_NUM; i++)
            {
                int    cx0    = 1 + i + i_x1;
                double cp6_0  = cpara[6] * cx0;
                double cpx0_0 = cpara[0] * cx0 + cpara[2];
                double cpx3_0 = cpara[3] * cx0 + cpara[5];

                int pt = 0;
                for (int i2 = 0; i2 < FRQ_POINTS; i2++)
                {
                    int cy = 1 + i2 * FRQ_STEP + FRQ_EDGE;

                    double d = cp6_0 + cpara7 * cy + 1.0;
                    int    x = (int)((cpx0_0 + cpara1 * cy) / d);
                    int    y = (int)((cpx3_0 + cpara4 * cy) / d);
                    if (x < 0 || y < 0 || x >= raster_width || y >= raster_height)
                    {
                        return(-1);
                    }
                    ref_x[pt] = x;
                    ref_y[pt] = y;
                    pt++;
                }

                //ピクセルを取得(入力画像を多様化するならここを調整すること)
                i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp);

                int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index);
                //周期は3-10であること
                if (freq_t < MIN_FREQ || freq_t > MAX_FREQ)
                {
                    continue;
                }
                //周期は等間隔であること
                if (!checkFreqWidth(o_edge_index, freq_t))
                {
                    continue;
                }
                //検出カウンタを追加
                freq_count_table[freq_t]++;
                int table_st = (freq_t - 1) * freq_t;
                for (int i2 = 0; i2 < freq_t * 2; i2++)
                {
                    freq_table[table_st + i2] += o_edge_index[i2];
                }
            }
            return(getMaxFreq(freq_count_table, freq_table, o_edge_index));
        }
        public int getColFrequency(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, int i_x1, int i_th_h, int i_th_l, int[] o_edge_index)
        {
            double[] cpara = this._cparam;
            int[] ref_x = this._ref_x;
            int[] ref_y = this._ref_y;
            int[] pixcel_temp = this._pixcel_temp;
            //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110
            //初期化
            int[] freq_count_table = this._freq_count_table;
            for (int i = 0; i < 10; i++)
            {
                freq_count_table[i] = 0;
            }
            int[] freq_table = this._freq_table;
            for (int i = 0; i < 110; i++)
            {
                freq_table[i] = 0;
            }
            int raster_width = i_raster_size.w;
            int raster_height = i_raster_size.h;


            double cpara7 = cpara[7];
            double cpara4 = cpara[4];
            double cpara1 = cpara[1];
            //基準点から4ピクセルを参照パターンとして抽出
            for (int i = 0; i < FREQ_SAMPLE_NUM; i++)
            {

                int cx0 = 1 + i + i_x1;
                double cp6_0 = cpara[6] * cx0;
                double cpx0_0 = cpara[0] * cx0 + cpara[2];
                double cpx3_0 = cpara[3] * cx0 + cpara[5];

                int pt = 0;
                for (int i2 = 0; i2 < FRQ_POINTS; i2++)
                {
                    int cy = 1 + i2 * FRQ_STEP + FRQ_EDGE;

                    double d = cp6_0 + cpara7 * cy + 1.0;
                    int x = (int)((cpx0_0 + cpara1 * cy) / d);
                    int y = (int)((cpx3_0 + cpara4 * cy) / d);
                    if (x < 0 || y < 0 || x >= raster_width || y >= raster_height)
                    {
                        return -1;
                    }
                    ref_x[pt] = x;
                    ref_y[pt] = y;
                    pt++;
                }

                //ピクセルを取得(入力画像を多様化するならここを調整すること)
                i_reader.getPixelSet(ref_x, ref_y, FRQ_POINTS, pixcel_temp);

                int freq_t = getFreqInfo(pixcel_temp, i_th_h, i_th_l, o_edge_index);
                //周期は3-10であること
                if (freq_t < MIN_FREQ || freq_t > MAX_FREQ)
                {
                    continue;
                }
                //周期は等間隔であること
                if (!checkFreqWidth(o_edge_index, freq_t))
                {
                    continue;
                }
                //検出カウンタを追加
                freq_count_table[freq_t]++;
                int table_st = (freq_t - 1) * freq_t;
                for (int i2 = 0; i2 < freq_t * 2; i2++)
                {
                    freq_table[table_st + i2] += o_edge_index[i2];
                }
            }
            return getMaxFreq(freq_count_table, freq_table, o_edge_index);
        }
Exemple #28
0
        public void pickFromRaster(double[] i_cpara, INyARRgbRaster image, int[] o_patt)
        {
            double d0, m0, d1, m1;
            int    x, y;

            int img_x  = image.getWidth();
            int img_y  = image.getHeight();
            int patt_w = this._size_ref.w;

            int[] rgb_tmp = this._rgb_temp;
            int[] rgb_px  = this._rgb_px;
            int[] rgb_py  = this._rgb_py;



            double cp0 = i_cpara[0];
            double cp3 = i_cpara[3];
            double cp6 = i_cpara[6];
            double cp1 = i_cpara[1];
            double cp4 = i_cpara[4];
            double cp7 = i_cpara[7];


            int pick_y = this._lt_ref.y;
            int pick_x = this._lt_ref.x;
            //ピクセルリーダーを取得
            INyARRgbPixelReader reader = image.getRgbPixelReader();
            int p = 0;


            double cp0cx0, cp3cx0;
            double cp1cy_cp20 = cp1 * pick_y + i_cpara[2] + cp0 * pick_x;
            double cp4cy_cp50 = cp4 * pick_y + i_cpara[5] + cp3 * pick_x;
            double cp7cy_10   = cp7 * pick_y + 1.0 + cp6 * pick_x;


            double cp0cx1, cp3cx1;
            double cp1cy_cp21 = cp1cy_cp20 + cp1;
            double cp4cy_cp51 = cp4cy_cp50 + cp4;
            double cp7cy_11   = cp7cy_10 + cp7;

            double cw0 = cp1 + cp1;
            double cw7 = cp7 + cp7;
            double cw4 = cp4 + cp4;

            for (int iy = this._size_ref.h - 1; iy >= 0; iy--)
            {
                cp0cx0 = cp1cy_cp20;
                cp3cx0 = cp4cy_cp50;
                cp0cx1 = cp1cy_cp21;
                cp3cx1 = cp4cy_cp51;

                m0 = 1 / (cp7cy_10);
                d0 = -cp6 / (cp7cy_10 * (cp7cy_10 + cp6));
                m1 = 1 / (cp7cy_11);
                d1 = -cp6 / (cp7cy_11 * (cp7cy_11 + cp6));

                int n = patt_w * 2 * 2 - 1;

                for (int ix = patt_w * 2 - 1; ix >= 0; ix--)
                {
                    //[n,0]
                    x = rgb_px[n] = (int)(cp0cx0 * m0);
                    y = rgb_py[n] = (int)(cp3cx0 * m0);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[n] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[n] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[n] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[n] = img_y - 1;
                        }
                    }
                    cp0cx0 += cp0;
                    cp3cx0 += cp3;
                    m0     += d0;
                    n--;
                    //[n,1]
                    x = rgb_px[n] = (int)(cp0cx1 * m1);
                    y = rgb_py[n] = (int)(cp3cx1 * m1);
                    if (x < 0 || x >= img_x || y < 0 || y >= img_y)
                    {
                        if (x < 0)
                        {
                            rgb_px[n] = 0;
                        }
                        else if (x >= img_x)
                        {
                            rgb_px[n] = img_x - 1;
                        }
                        if (y < 0)
                        {
                            rgb_py[n] = 0;
                        }
                        else if (y >= img_y)
                        {
                            rgb_py[n] = img_y - 1;
                        }
                    }
                    cp0cx1 += cp0;
                    cp3cx1 += cp3;
                    m1     += d1;
                    n--;
                }
                cp7cy_10 += cw7;
                cp7cy_11 += cw7;

                cp1cy_cp20 += cw0;
                cp4cy_cp50 += cw4;
                cp1cy_cp21 += cw0;
                cp4cy_cp51 += cw4;



                reader.getPixelSet(rgb_px, rgb_py, patt_w * 4, rgb_tmp);
                for (int ix = patt_w - 1; ix >= 0; ix--)
                {
                    int idx = ix * 12;//3*2*2
                    int r   = (rgb_tmp[idx + 0] + rgb_tmp[idx + 3] + rgb_tmp[idx + 6] + rgb_tmp[idx + 9]) / 4;
                    int g   = (rgb_tmp[idx + 1] + rgb_tmp[idx + 4] + rgb_tmp[idx + 7] + rgb_tmp[idx + 10]) / 4;
                    int b   = (rgb_tmp[idx + 2] + rgb_tmp[idx + 5] + rgb_tmp[idx + 8] + rgb_tmp[idx + 11]) / 4;
                    o_patt[p] = (r << 16) | (g << 8) | ((b & 0xff));
                    p++;
                }
            }

            return;
        }
        /**
         * 指定した場所のピクセル値を調査して、閾値を計算して返します。
         * @param i_reader
         * @param i_x
         * @param i_y
         * @return
         * @throws NyARException
         */
        public void detectThresholdValue(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, TThreshold o_threshold)
        {
            int[] th_pixels = this._th_pixels;

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

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

            //右上のピックアップ領域からピクセルを得る(50-74)
            rectPixels(i_reader, i_raster_size, THRESHOLD_SAMPLE_RB, THRESHOLD_SAMPLE_LT, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE * 2, th_pixels);

            //右下のピックアップ領域からピクセルを得る(75-99)
            rectPixels(i_reader, i_raster_size, THRESHOLD_SAMPLE_RB, THRESHOLD_SAMPLE_RB, THRESHOLD_STEP, THRESHOLD_STEP, THRESHOLD_PIXEL, THRESHOLD_PIXEL, THRESHOLD_SAMPLE * 3, th_pixels);

            THighAndLow hl = this.__detectThresholdValue_hl;
            //Ptailで求めたピクセル平均
            getPtailHighAndLow(th_pixels, hl);



            //閾値中心
            int th = (hl.h + hl.l) / 2;
            //ヒステリシス(差分の20%)
            int th_sub = (hl.h - hl.l) / 5;

            o_threshold.th = th;
            o_threshold.th_h = th + th_sub;//ヒステリシス付き閾値
            o_threshold.th_l = th - th_sub;//ヒステリシス付き閾値

            //エッジを計算(明点重心)
            int lt_x, lt_y, lb_x, lb_y, rt_x, rt_y, rb_x, rb_y;
            NyARIntPoint2d tpt = this.__detectThresholdValue_tpt;
            //LT
            if (getHighPixelCenter(0, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                lt_x = tpt.x * THRESHOLD_STEP;
                lt_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                lt_x = 11;
                lt_y = 11;
            }
            //LB
            if (getHighPixelCenter(THRESHOLD_SAMPLE * 1, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                lb_x = tpt.x * THRESHOLD_STEP;
                lb_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                lb_x = 11;
                lb_y = -1;
            }
            //RT
            if (getHighPixelCenter(THRESHOLD_SAMPLE * 2, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                rt_x = tpt.x * THRESHOLD_STEP;
                rt_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                rt_x = -1;
                rt_y = 11;
            }
            //RB
            if (getHighPixelCenter(THRESHOLD_SAMPLE * 3, th_pixels, THRESHOLD_PIXEL, THRESHOLD_PIXEL, th, tpt))
            {
                rb_x = tpt.x * THRESHOLD_STEP;
                rb_y = tpt.y * THRESHOLD_STEP;
            }
            else
            {
                rb_x = -1;
                rb_y = -1;
            }
            //トラッキング開始位置の決定
            o_threshold.lt_x = (lt_x + lb_x) / 2 + THRESHOLD_SAMPLE_LT - 1;
            o_threshold.rb_x = (rt_x + rb_x) / 2 + THRESHOLD_SAMPLE_RB + 1;
            o_threshold.lt_y = (lt_y + rt_y) / 2 + THRESHOLD_SAMPLE_LT - 1;
            o_threshold.rb_y = (lb_y + rb_y) / 2 + THRESHOLD_SAMPLE_RB + 1;
            return;
        }
        public bool readDataBits(INyARRgbPixelReader i_reader, NyARIntSize i_raster_size, PerspectivePixelReader.TThreshold i_th, MarkerPattEncoder o_bitbuffer)
        {
            double[] index_x = this.__readDataBits_index_bit_x;
            double[] index_y = this.__readDataBits_index_bit_y;
            //読み出し位置を取得
            int size       = detectDataBitsIndex(i_reader, i_raster_size, i_th, index_x, index_y);
            int resolution = size + size - 1;

            if (size < 0)
            {
                return(false);
            }
            if (!o_bitbuffer.initEncoder(size - 1))
            {
                return(false);
            }

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

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


            int th = i_th.th;
            int p  = 0;

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

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

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

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

                    d         = cp6_0 + cpy0_7;
                    ref_x[pt] = (int)((cpx0_0 + cpy0_12) / d);
                    ref_y[pt] = (int)((cpx3_0 + cpy0_45) / d);
                    pt++;

                    d         = cp6_0 + cpy1_7;
                    ref_x[pt] = (int)((cpx0_0 + cpy1_12) / d);
                    ref_y[pt] = (int)((cpx3_0 + cpy1_45) / d);
                    pt++;

                    d         = cp6_1 + cpy0_7;
                    ref_x[pt] = (int)((cpx0_1 + cpy0_12) / d);
                    ref_y[pt] = (int)((cpx3_1 + cpy0_45) / d);
                    pt++;

                    d         = cp6_1 + cpy1_7;
                    ref_x[pt] = (int)((cpx0_1 + cpy1_12) / d);
                    ref_y[pt] = (int)((cpx3_1 + cpy1_45) / d);
                    pt++;
                }
                //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
                i_reader.getPixelSet(ref_x, ref_y, resolution * 4, pixcel_temp);
                //グレースケールにしながら、line→mapへの転写
                for (int i2 = 0; i2 < resolution; i2++)
                {
                    int index = i2 * 3 * 4;
                    int pixel = (pixcel_temp[index + 0] + pixcel_temp[index + 1] + pixcel_temp[index + 2] +
                                 pixcel_temp[index + 3] + pixcel_temp[index + 4] + pixcel_temp[index + 5] +
                                 pixcel_temp[index + 6] + pixcel_temp[index + 7] + pixcel_temp[index + 8] +
                                 pixcel_temp[index + 9] + pixcel_temp[index + 10] + pixcel_temp[index + 11]) / (4 * 3);
                    //暗点を1、明点を0で表現します。
                    o_bitbuffer.setBitByBitIndex(p, pixel > th ? 0 : 1);
                    p++;
                }
            }

            /*
             *      for(int i=0;i<225*4;i++){
             *          this.vertex_x[i]=0;
             *          this.vertex_y[i]=0;
             *      }
             *      for(int i=0;i<(resolution)*2;i++){
             *          for(int i2=0;i2<(resolution)*2;i2++){
             *              this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2];
             *              this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i];
             *
             *          }
             *      }
             */
            return(true);
        }
        public NyARRgbRaster_Blank(int i_width, int i_height)
            : base(i_width, i_height, NyARBufferType.NULL_ALLZERO)
	    {
		    this._reader = new PixelReader();
		    return;
	    }
 public NyARRgbRaster_Blank(int i_width, int i_height)
     : base(i_width, i_height, NyARBufferType.NULL_ALLZERO)
 {
     this._reader = new PixelReader();
     return;
 }
        /**
         * 回転方向を指定してラスタをセットします。
         * @param i_reader
         * @param i_direction
         * 右上の位置です。0=1象限、1=2象限、、2=3象限、、3=4象限の位置に対応します。
         * @throws NyARException
         */
        public void setRaster(INyARRgbRaster i_raster, int i_direction)
        {
            int width                  = this._size.w;
            int height                 = this._size.h;
            int i_number_of_pix        = width * height;
            INyARRgbPixelReader reader = i_raster.getRgbPixelReader();

            int[] rgb  = new int[3];
            int[] dout = this._data;
            int   ave;      //<PV/>

            //<平均値計算>
            ave = 0;
            for (int y = height - 1; y >= 0; y--)
            {
                for (int x = width - 1; x >= 0; x--)
                {
                    reader.getPixel(x, y, rgb);
                    ave += rgb[0] + rgb[1] + rgb[2];
                }
            }
            //<平均値計算>
            ave = i_number_of_pix * 255 * 3 - ave;
            ave = 255 - (ave / (i_number_of_pix * 3));    //(255-R)-ave を分解するための事前計算

            int sum = 0, w_sum;
            int input_ptr = i_number_of_pix * 3 - 1;

            switch (i_direction)
            {
            case 0:
                for (int y = height - 1; y >= 0; y--)
                {
                    for (int x = width - 1; x >= 0; x--)
                    {
                        reader.getPixel(x, y, rgb);
                        w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //B
                        w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //G
                        w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //R
                    }
                }
                break;

            case 1:
                for (int x = 0; x < width; x++)
                {
                    for (int y = height - 1; y >= 0; y--)
                    {
                        reader.getPixel(x, y, rgb);
                        w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //B
                        w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //G
                        w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //R
                    }
                }
                break;

            case 2:
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        reader.getPixel(x, y, rgb);
                        w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //B
                        w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //G
                        w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //R
                    }
                }
                break;

            case 3:
                for (int x = width - 1; x >= 0; x--)
                {
                    for (int y = 0; y < height; y++)
                    {
                        reader.getPixel(x, y, rgb);
                        w_sum = (ave - rgb[2]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //B
                        w_sum = (ave - rgb[1]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //G
                        w_sum = (ave - rgb[0]); dout[input_ptr--] = w_sum; sum += w_sum * w_sum;                   //R
                    }
                }
                break;
            }
            //<差分値計算>
            //<差分値計算(FORの1/8展開)/>
            double p = Math.Sqrt((double)sum);

            this._pow = (p != 0.0?p:0.0000001);
        }