1

我正在尝试编写边缘检测方法。而且我使用了 emgucv Image 类。由于我需要灰度值,我已将其声明为

Image<Gray,float> MyImage = new Image<Gray,float>;

我选择一个图像并将其像素值分配给 MyImage 作为

public void selectImage()
          { 
               OpenFileDialog opp = new OpenFileDialog();
              if (opp.ShowDialog() == DialogResult.OK)
              {                 
                   MyImage = new Image<Gray,float>(opp.FileName);
                  InputArray = new Image<Gray, float>(opp.FileName);
                  Convert.ToString(MyImage);
                  pictureBox1.Image = MyImage.ToBitmap();                
              }             
          }

当我单击边缘检测按钮时,它会调用主递归函数

private void detect_edges_Click(object sender, EventArgs e)
        {          
           hueckel_operator(1, 1);
        }

该运算符以 5 像素间隔重复自身。换句话说,我通过将 x 参数增加 5 并将其应用于 x 轴,并在行的末尾将 y 轴增加 5,依此类推。

在hueckel_operator中,再次计算一个非常重的公式的函数“a()”被调用了8次。这是 a() 函数

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

                for (int II = 0; II <= j ; II++)
                {
                    for (KK = 1; KK < 70; KK++)
                    {
                         x_value = input_i_x(KK); //this function brings the x coordinate
                         y_value = input_i_y(KK); // this function brings the y coordinate

                result += HueckelDisk(x_value,y_value,j) * MyImage[x_value+counter6, y_value+counter7].Intensity;
                //MyImage.Dispose();
                    }
                }                           
                return result;
            }

但问题大约在坐标 (75,5) 处,它会引发堆栈溢出异常。我用性能分析调试了它,MyImage 似乎吃掉了所有的内存。您可能想查看递归函数,但由于它太大,我不能把它放在这里,而且我确信递归函数 (hueckel_operator()) 无法达到终止条件,因为我发现它被调用了多少次。我想要的是找出是否有另一种方法可以更有效地计算“结果”。

我的另一个问题是,对象 MyImage 在函数 a() 中使用了 69*j 次,这是否意味着每当调用 a() 时它都会分配 69*j 次内存空间?

在我绝望的尝试中,我已经将几乎每个变量都声明并定义为全局变量,以减少内存使用量,因为我曾想过,每当调用hueckel_operator() 和a() 时,局部变量会一遍又一遍地在堆栈中分配额外的内存,这是一个好的或必要的方法吗?

我使用了 4 个非常嵌套且繁重的函数,并且我不使用任何类。会是主要问题吗?老实说,我在这里看不到任何可以转换为课堂的东西。

我知道,我问了太多问题,但我现在真的很绝望。几周以来我一直在阅读文章,我想我需要一个开始。任何帮助,将不胜感激。

在此处输入图像描述

4

1 回答 1

3

堆栈溢出异常与内存使用并没有太大关系 - 它来自堆栈使用。在你的情况下,一个递归调用。

递归只能走这么深,直到堆栈耗尽。一旦发生这种情况,您的堆栈就会溢出。

如果您不在无限递归中但需要更深入,则可以在创建线程时指定堆栈大小,并在其上运行递归函数:

var stackSize = 10000000;
var thread = new Thread(new ThreadStart(StartDetection), stackSize);

但是,默认大小是 1MB - 对于大多数任务来说,这已经是相当大的了。您可能想要验证您的递归实际上不是未绑定的,或者您不能减少或删除它。

于 2012-07-09T13:02:03.977 回答