2012-07-09 101 views
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); 
     } 

這種操作重複本身5pixel間隔。換句話說,我通過將x參數增加5來在x軸上應用它,在行的末尾我將y軸增加5,依此類推。

在hueckel_operator,其中再次計算一個非常沉重的公式被稱爲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在功能使用的()69 *進行j次?它意味着它分配內存空間,69 *進行j次每當()被調用?在我絕望的嘗試期間,爲了減少內存使用,我已經聲明和定義了幾乎所有的變量作爲全局變量,因爲除非調用hueckel_operator()和a(),否則本地變量會在堆棧中分配額外的內存一遍又一遍,這是一個好的還是必要的方法?

我用4個非常嵌套,重功能,我不使用任何類。這會是主要問題嗎?說實話,我沒有看到任何東西可以轉化爲課堂。

我知道,我都問了太多問題,但我真的絕望了現在。自從幾周以來,我正在閱讀文章,我想我需要一個開始。任何幫助,將不勝感激。

enter image description here

回答

3

堆棧溢出異常並沒有真正有很多工作要做,內存使用情況 - 這是從堆棧使用。在你的情況下,遞歸調用。

遞歸只能走這麼深,直到堆棧耗盡。一旦發生這種情況,你的堆棧溢出。

如果在無限遞歸,但你需要更進一步,你可以當你創建一個線程指定堆棧大小,並運行在您的遞歸函數:

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

然而,默認大小是1MB - 對於大多數任務來說這是相當多的。您可能需要驗證您的遞歸實際上並未解除綁定,或者您無法減少或移除它。

+0

確定這似乎解決我的問題,但我必須先了解它,因爲我不知道在哪裏把它或者寫什麼,而不是「開始檢測」(可能命名功能)。我也寧願修改我的算法,但我真的沒有時間,我不知道,也許它不是無限的,你說 – mctuna 2012-07-09 13:40:00

+0

是'StartDetection'在我的例子是一些函數的名稱(可能只會有一個行:'hueckel_operator(1,1);') – 2012-07-09 13:52:00

+0

太謝謝你了 – mctuna 2012-07-09 14:03:32