4

スタックオーバーフローエラーが発生するため、次のコードの効率的な方法を探しています。できる限り多くの情報を提供しましたが、これらすべての説明は必要ないかもしれませんが、コード自体だけで十分です。このエラーに対処していただきありがとうございます。

一度に 9x9 の領域に演算子 (Hueckel エッジ検出演算子) を適用し、画像全体に対してそれを繰り返します。したがって、これは通常のエッジ検出の基本です。2番目の写真で私が言いたいことがわかります。

ここに画像の説明を入力 ここに画像の説明を入力

関数 a() は、hueckel_operator() という別の関数で一度に 8 回呼び出されており、hueckel_operator は、x パラメーターと y パラメーターの両方に対して毎回 +5 を呼び出す再帰関数です。つまり、大きな画像と実際の問題 MyImage[] が emgucv Image<> オブジェクトに対してかなり a() が呼び出されていることを意味します。MyImage[] は 9x9 マトリックスのすべてのピクセルをチェックしてその値を取得する必要があるため、関数 a() よりも 69 * j 倍多く呼び出されています。

関数 input_i_y() は y 座標をもたらし、9x9 マトリックスの x 座標をもたらす input_i_x() と呼ばれる別の関数があります。別の関数のパラメーターとして使用するために2つの別個の関数を作成するのは極端ですが、より良い解決策が見つかりませんでした。HueckelDisk クラスは、x、y 座標に従って、9 つの異なる Hueckel ディスクの式を計算しています。フィッティング精度により、エッジの有無が分かります。

ここに画像の説明を入力

ここにhueckel_operator()の終了条件があります

if (mod_width + counter4 + 10 >= MyImage.Width && mod_height + counter5 + 10 >= MyImage.Height)
            {
                goto EXIT2;
            }

これがhueckel_operator()の始まりと終わりです

public void hueckel_operator(int counter2, int counter3)
        {      
            counter2 = counter4;
            counter3 = counter5;

               int mod_width = MyImage.Width % 5;
            int mod_height = MyImage.Height % 5;

            if (mod_width + counter4 + 10 >= MyImage.Width && mod_height + counter5 + 10 >= MyImage.Height)
            {
                goto EXIT2;
            }
            else
            {
                if (mod_width + counter4 + 10 >= MyImage.Width)
                {
                    if (counter5 == 1)
                    {
                        counter5 += 4;
                    }
                    else
                    {
                        counter5 += 5;
                    }
                    counter4 = 1;
                }
                if (counter4 == 1)
                {
                    counter4 += 4;
                }

                else if(counter4 != 0)

                {
                    counter4 += 5;
                }

                if (counter5 == 0 && counter4 == 0)
                {
                    counter4 = 1;
                    counter5 = 1;
                }
            }

これがhueckel_operator();の終わりです。

出口:

               hueckel_operator(counter5, counter4);

        EXIT2:

            MessageBox.Show("done");
        }

ここに関数 a() があります

 public double a(int j,  int counter6,  int counter7)
                {

                    double result = 0;

                    HueckelDisks hueckel_formula = new HueckelDisks();

                    counter6 = counter4;
                    counter7 = counter5;


                    for (int II = 0; II <= j ; II++)
                    {
                        for (KK = 1; KK < 69; KK++)
                        {

                            result += hueckel_formula.HueckelDisk(input_i_x(KK),input_i_y(KK),j) * MyImage[point_a, point_b].Intensity;

                        }
                    }

                    return result;
                }


         public int input_i_y(int y)
                {        
                    Tuple<int, int>[] myArray =
                    {
                        Tuple.Create(3,1),Tuple.Create(4,1),Tuple.Create(5,1),Tuple.Create(6,1),Tuple.Create(7,1),Tuple.Create(2,2),
                        Tuple.Create(3,2),Tuple.Create(4,2),Tuple.Create(5,2),Tuple.Create(6,2),Tuple.Create(7,2),Tuple.Create(8,2),
                        Tuple.Create(1,3),Tuple.Create(2,3),Tuple.Create(3,3),Tuple.Create(4,3),Tuple.Create(5,3),Tuple.Create(6,3),
                        Tuple.Create(7,3),Tuple.Create(8,3),Tuple.Create(9,3),Tuple.Create(1,4),Tuple.Create(2,4),Tuple.Create(3,4),
                        Tuple.Create(4,4),Tuple.Create(5,4),Tuple.Create(6,4),Tuple.Create(7,4),Tuple.Create(8,4),Tuple.Create(9,4),
                        Tuple.Create(1,5),Tuple.Create(1,5),Tuple.Create(2,5),Tuple.Create(3,5),Tuple.Create(4,5),Tuple.Create(5,5),
                        Tuple.Create(6,5),Tuple.Create(7,5),Tuple.Create(8,5),Tuple.Create(9,5),Tuple.Create(1,6),Tuple.Create(2,6),
                        Tuple.Create(3,6),Tuple.Create(4,6),Tuple.Create(5,6),Tuple.Create(6,6),Tuple.Create(7,6),Tuple.Create(8,6),
                        Tuple.Create(8,6),Tuple.Create(1,7),Tuple.Create(2,7),Tuple.Create(3,7),Tuple.Create(4,7),Tuple.Create(5,7),
                        Tuple.Create(6,7),Tuple.Create(7,7),Tuple.Create(8,7),Tuple.Create(9,7),Tuple.Create(2,8),Tuple.Create(3,8),
                        Tuple.Create(4,8),Tuple.Create(5,8),Tuple.Create(6,8),Tuple.Create(7,8),Tuple.Create(8,8),Tuple.Create(3,9),
                        Tuple.Create(4,9),Tuple.Create(5,9),Tuple.Create(6,9),Tuple.Create(7,9),

                    };


                    return myArray[y].Item2;


                }
4

2 に答える 2

2

myArrayの外側の作成を確認してくださいinput_i_y

呼び出し間で変更されないため、静的である可能性さえあります。

// ...somewhereinside you Hueckel class

public Tuple<int, int>[] myArray { get; set; }

// Initialize it
public void InitializeHueckel()
{
    CreateMyArray();
}

// and build it 
public void  CreateMyArray()
{
   myArray = new Tuple<int, int>[] {
             Tuple.Create(3, 1), Tuple.Create(4, 1), Tuple.Create(5, 1), 
             Tuple.Create(6, 1), Tuple.Create(7, 1), Tuple.Create(2, 2), 
             Tuple.Create(3, 2), Tuple.Create(4, 2), Tuple.Create(5, 2), 
             Tuple.Create(6, 2), Tuple.Create(7, 2), Tuple.Create(8, 2), 
             Tuple.Create(1, 3), Tuple.Create(2, 3), Tuple.Create(3, 3), 
             Tuple.Create(4, 3), Tuple.Create(5, 3), Tuple.Create(6, 3), 
             Tuple.Create(7, 3), Tuple.Create(8, 3), Tuple.Create(9, 3), 
             Tuple.Create(1, 4), Tuple.Create(2, 4), Tuple.Create(3, 4), 
             Tuple.Create(4, 4), Tuple.Create(5, 4), Tuple.Create(6, 4), 
             Tuple.Create(7, 4), Tuple.Create(8, 4), Tuple.Create(9, 4), 
             Tuple.Create(1, 5), Tuple.Create(1, 5), Tuple.Create(2, 5), 
             Tuple.Create(3, 5), Tuple.Create(4, 5), Tuple.Create(5, 5), 
             Tuple.Create(6, 5), Tuple.Create(7, 5), Tuple.Create(8, 5), 
             Tuple.Create(9, 5), Tuple.Create(1, 6), Tuple.Create(2, 6), 
             Tuple.Create(3, 6), Tuple.Create(4, 6), Tuple.Create(5, 6), 
             Tuple.Create(6, 6), Tuple.Create(7, 6), Tuple.Create(8, 6), 
             Tuple.Create(8, 6), Tuple.Create(1, 7), Tuple.Create(2, 7), 
             Tuple.Create(3, 7), Tuple.Create(4, 7), Tuple.Create(5, 7), 
             Tuple.Create(6, 7), Tuple.Create(7, 7), Tuple.Create(8, 7), 
             Tuple.Create(9, 7), Tuple.Create(2, 8), Tuple.Create(3, 8), 
             Tuple.Create(4, 8), Tuple.Create(5, 8), Tuple.Create(6, 8), 
             Tuple.Create(7, 8), Tuple.Create(8, 8), Tuple.Create(3, 9), 
             Tuple.Create(4, 9), Tuple.Create(5, 9), Tuple.Create(6, 9), 
             Tuple.Create(7, 9), 
             };

input_i_y 内では、以前と同じように使用できます。

return myArray[y].Item2;

スタックの負荷をいくらか取り除く必要があります。

于 2012-07-08T16:22:53.730 に答える
1

The very beginning of your hueckel_operator method contains a hint of the likely source of your infinite recursion.

public void hueckel_operator(int counter2, int counter3)
        {      
            counter2 = counter4;
            counter3 = counter5;

You are, instead of using the values of your two parameters, immediately assigning them values that must come from fields that we can't see in your posted code.

The rest of the visible code doesn't even reference these parameters.

あなたが投稿したコードのビットが与えられたときにエラーがどこにあるのかを確実に言うことは不可能ですが、実際にロジックを駆動するこれらのフィールド値が変更されていないか、再帰を終了させる方法で変更されていない可能性が非常に高いです.

根本的な問題は、自分のコードを理解できないことにあると思います。counter2、などの代わりに意味のある変数名を使用counter3し、フィールドにパラメーターとは異なる名前を付け、パラメーターの再割り当てを避け、実際に使用されるパラメーターのみを定義する必要があります。

そして、私も同様に取り除こうとしgotoます。

于 2012-07-08T16:00:42.520 に答える