/**
         * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。
         * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。
         * @param i_pixcel
         * @param i_initial
         * @param i_out
         */
        private void getPtailHighAndLow(int[] i_pixcel, THighAndLow i_out)
        {
            int h3, h2, h1, h0, l3, l2, l1, l0;

            h3 = h2 = h1 = h0 = l3 = l2 = l1 = l0 = i_pixcel[0];

            for (int i = i_pixcel.Length - 1; i >= 1; i--)
            {
                int pix = i_pixcel[i];
                if (h0 < pix)
                {
                    if (h1 < pix)
                    {
                        if (h2 < pix)
                        {
                            if (h3 < pix)
                            {
                                h0 = h1;
                                h1 = h2;
                                h2 = h3;
                                h3 = pix;
                            }
                            else
                            {
                                h0 = h1;
                                h1 = h2;
                                h2 = pix;
                            }
                        }
                        else
                        {
                            h0 = h1;
                            h1 = pix;
                        }
                    }
                    else
                    {
                        h0 = pix;
                    }
                }
                if (l0 > pix)
                {
                    if (l1 > pix)
                    {
                        if (l2 > pix)
                        {
                            if (l3 > pix)
                            {
                                l0 = l1;
                                l1 = l2;
                                l2 = l3;
                                l3 = pix;
                            }
                            else
                            {
                                l0 = l1;
                                l1 = l2;
                                l2 = pix;
                            }
                        }
                        else
                        {
                            l0 = l1;
                            l1 = pix;
                        }
                    }
                    else
                    {
                        l0 = pix;
                    }
                }
            }
            i_out.l = (l0 + l1 + l2 + l3) / 4;
            i_out.h = (h0 + h1 + h2 + h3) / 4;
            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;
        }
        /**
         * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。
         * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。
         * @param i_pixcel
         * @param i_initial
         * @param i_out
         */
        private void getPtailHighAndLow(int[] i_pixcel, THighAndLow i_out)
        {
            int h3, h2, h1, h0, l3, l2, l1, l0;
            h3 = h2 = h1 = h0 = l3 = l2 = l1 = l0 = i_pixcel[0];

            for (int i = i_pixcel.Length - 1; i >= 1; i--)
            {
                int pix = i_pixcel[i];
                if (h0 < pix)
                {
                    if (h1 < pix)
                    {
                        if (h2 < pix)
                        {
                            if (h3 < pix)
                            {
                                h0 = h1;
                                h1 = h2;
                                h2 = h3;
                                h3 = pix;
                            }
                            else
                            {
                                h0 = h1;
                                h1 = h2;
                                h2 = pix;
                            }
                        }
                        else
                        {
                            h0 = h1;
                            h1 = pix;
                        }
                    }
                    else
                    {
                        h0 = pix;
                    }
                }
                if (l0 > pix)
                {
                    if (l1 > pix)
                    {
                        if (l2 > pix)
                        {
                            if (l3 > pix)
                            {
                                l0 = l1;
                                l1 = l2;
                                l2 = l3;
                                l3 = pix;
                            }
                            else
                            {
                                l0 = l1;
                                l1 = l2;
                                l2 = pix;
                            }
                        }
                        else
                        {
                            l0 = l1;
                            l1 = pix;
                        }
                    }
                    else
                    {
                        l0 = pix;
                    }
                }
            }
            i_out.l = (l0 + l1 + l2 + l3) / 4;
            i_out.h = (h0 + h1 + h2 + h3) / 4;
            return;
        }