2016-08-20 5 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にアクセスしようとしましたが、そのエラーの原因はほとんど確かです。

面白いことに、私は最後または最初にエラーが発生しないということです。私は中央の周りにセグフォルトを取得します。 たとえば、行:915、列:793、チャネル:1

Row:829 Col:729 Channel:0でエラーが発生します。

このエラーの原因を特定できません。

+0

適切なツールは、あなたのデバッガを使用することですが、お願いしませんあなたがそうする前にスタックオーバーフローで。 1つ目の行でコードを検査するときに行ったすべての観察を教えてください。また、[**小さなプログラムをデバッグする方法(Eric Lippertによる)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**]を読んでみてください。あなたの問題を再現する** [MCVE] **を私たちに任せてください。 (これはπάνταῥεῖ™によって提供される個人的なコメントです) –

+0

私は一般に同意します。その場合、代わりに 'electricfence'の仕事があります。もしあなたがLinuxを使っていればうまくいきます。 –

+0

私はあなたに同意します。しかし、私はよく知られていないビルドツール(bazel)で慣れていません。だから私はバゼルに協力してもらうよう説得しようとしている間にこれを尋ねると思った。 –

答えて

2

あなたの行ポインタが間違った計算は、cols代わりにrows次のようになります。

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

あなたは行列のフラットな表現を使用する場合、あなたは非常に慎重でなければならない、それは実際にエラーが発生しやすいのです。

+0

これは、各行の最後に余白がない場合にのみ機能します。 imho正しい方法は、char * oder uchar *のrow_ptrを '.data + r * widthStep'で計算し、その後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

関連する問題