2016-08-20 66 views
-2

所以我有這樣一段代碼:當我嘗試在OpenCV中輸入值時,爲什麼會出現seg故障?

if(channels == 3) 
    type = CV_32FC3; 
    else 
    type = CV_32FC1; 
    cv::Mat M(rows,cols,type); 
    std::cout<<"Cols:"<<cols<<" ColsMat:"<<M.cols<<std::endl; 
    float * source_data = (float*) M.data; 
    // copying the data into the corresponding pixel 
    for (int r = 0; r < rows; r++) 
    { 
     float* source_row = source_data + (r * rows * channels); 
     for (int c = 0; c < cols ; c++) 
    { 
     float* source_pixel = source_row + (c * channels); 
     for (int ch = 0; ch < channels; ch++) 
     { 
     std::cout<<"Row:"<<r<<" Col:"<<c<<" Channel:"<<ch<<std::endl; 
     std::cout<<"Type check: "<<typeid(T_M(0,r,c,ch)).name()<<std::endl; 
     float* source_value = source_pixel + ch; 
     *source_value = T_M(0, r, c, ch); 
     } 
    } 
    } 

T_M是本徵::張量

我首先想到的是我從T_M錯誤,但它並非如此。

我試着訪問* source_value,我基本確信這是錯誤的來源。

有趣的是,我沒有在最後或開始得到錯誤。我在中間發生seg故障。 例如,對於行:915,cols:793和通道:1

我在Row處得到錯誤:829 Col:729 Channel:0。我找不出這個錯誤的來源。

+0

解決這些問題的最佳工具是使用調試器,而不是問在堆棧溢出之前,你這樣做了。告訴我們您在檢查您的代碼時所做的所有觀察。您也可以閱讀[**如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**] At最少給我們留下一個** [MCVE] **,它可以再現您的問題。 (這是個人評論由πάνταῥεῖ™提供) –

+0

我普遍認同。在這種情況下,如果您使用Linux,那麼這將是'電氣'的工作。 –

+0

我同意你的意見。但是,我在一個陌生的地方使用了不熟悉的構建工具(bazel)。所以我想在我試圖說服Bazel合作時我會問這個問題。 –

回答

2

你計算你行指針錯誤,應該是cols而不是rows

float* source_row = source_data + (r * cols * channels); 

在一般情況下,則必須在採用了矩陣的平面表示要非常小心,這真的容易出錯。

+0

只有在每行末尾沒有填充的情況下才能使用。 imho正確的方法是通過'.data + r * widthStep'計算char * oder uchar *中的row_ptr,然後將其轉換爲float *。 – Micka

2

如果矩陣是連續的,Jean-FrançoisFabre的答案將起作用。如果你不能確定有關(例如,如果矩陣是別人提供的,如果你使用子矩陣等),你應該使用widthstep功能來計算行指針:

float* source_row = (float*)(M.data + r*M.step); 

這種自動使用正確的渠道數量,填充等

更簡單的方法是使用直接行PTR功能:

float* source_row = (float*)(M.ptr(r)); 
+1

還有[其他幾種方式](http://stackoverflow.com/a/31894250/5008845)。例如。 'float * source_row = M.ptr (r);'對我來說似乎更簡單 – Miki

相關問題