Search code examples
c#image-processingstack-overflow

Stack overflow error due to large amount of calculations


I am just looking for a efficient way for the following code since I get an stack overflow error, I gave as much as info I can but maybe you don't need all these explanations but just the code itself would suffice, any help would be appreciated to make me get ride of this error;

What I am trying to do applying an operator (Hueckel edge detection operator) to an 9x9 area at a time and repeat it for the whole image. So it is a regular edge detection fundamental. You can see what I mean at the second picture.

enter image description here enter image description here

Function a() is being called 8 times in another function called hueckel_operator() at a time and hueckel_operator is a recursive function which call itself +5 for both x and y parameters every time. That means a() is being called pretty much for the big images and the real problem MyImage[] which is an emgucv Image<> object. Because MyImage[] should check every pixel in a 9x9 matrix and bring the value of it, it is being called 69 * j times more than the function a().

Function input_i_y() brings the y coordinate and there is another function called input_i_x() which brings the x coordinate of the 9x9 matrix. I know, it is extreme to make two seperate function in order to use them as parameter of another function but I couldn't find any better solution. HueckelDisk class is calculating the formula of the 9 different hueckel disks according to the x,y coordinates. According to the fitting accuracy we become sure if there is an edge or not.

enter image description here

here is the terminating condition of the hueckel_operator()

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

here is the beginning and end of the 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;
                }
            }

Here is the end of the hueckel_operator();

EXIT:

               hueckel_operator(counter5, counter4);

        EXIT2:

            MessageBox.Show("done");
        }

here is the function 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;


                }

Solution

  • please check out creating the myArray outside of input_i_y.

    it even could be static as it will not change in between calls.

    // ...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), 
                 };
    

    Inside your input_i_y you can use it as before:

    return myArray[y].Item2;
    

    Should remove some load of the stack.