2017-12-06 4 views
0

私はOpenCVのプロジェクトにレンズ口径食を補償するための関数を記述しようとしています。問題は、マットの最初のピクセルにアクセスしようとすると、メモリアクセスエラーが発生することです。それはおそらく愚かなエラーですが、もし私がそれを指摘できるなら、それを感謝します。ここでは、関数の:OpenCVのマットメモリアクセスエラー

void EckOpCam::FlatField(cv::Mat & parmI) 
{ 
// workaround for access violation error 
cv::Mat I = parmI; 
const int channels = I.channels(); 
if (flatField.rows == 0) 
    MakeFlatFieldMat(I.rows); 
// accept only char type matrices 
ASSERT(I.depth() == CV_8U); 
// make sure the matrices are the same size 
ASSERT(I.cols == flatField.cols); 
ASSERT(channels == flatField.channels()); 


// Try the really slow way... 
int nRows = I.rows; 
int nCols = I.cols; 
unsigned int ipix0, ipix1, ipix2; // B,G,r values of pixel in I 
float fpix0, fpix1,fpix2;   // B,G,r values of pixel in flatField 
float pix0, pix1, pix2; 
switch (channels) 
{ 
case 1: 
    for (int y = 0; y < nRows; ++y) 
     for (int x = 0; x < nCols; ++x) 
     { 
      { 
       ipix0 = I.at<cv::Vec3b>(x, y)[0]; 
       fpix0 = flatField.at<cv::Vec3f>(x, y)[0]; 
       pix0 = ipix0 * fpix0; 
       I.at<cv::Vec3b>(x, y)[0] = (pix0 > 255) ? 255 : uchar(pix0); 
      } 
     } 
    break; 
case 3: 
    for (int y = 0; y < nRows; ++y) 
     for (int x = 0; x < nCols; ++x) 
     { 
      { 
       ipix0 = static_cast<uchar>(I.at<cv::Vec3b>(x, y)[0]); //<<< memory access error! 
       ipix1 = static_cast<uchar>(I.at<cv::Vec3b>(x, y)[1]); 
       ipix2 = static_cast<uchar>(I.at<cv::Vec3b>(x, y)[2]); 
       fpix0 = flatField.at<cv::Vec3f>(x, y)[0]; 
       fpix1 = flatField.at<cv::Vec3f>(x, y)[1]; 
       fpix2 = flatField.at<cv::Vec3f>(x, y)[2]; 
       pix0 = ipix0 * fpix0; 
       pix1 = ipix1 * fpix1; 
       pix2 = ipix2 * fpix2; 
       I.at<cv::Vec3b>(x, y)[0] = (pix0 > 255) ? 255 : uchar(pix0); 
       I.at<cv::Vec3b>(x, y)[1] = (pix1 > 255) ? 255 : uchar(pix1); 
       I.at<cv::Vec3b>(x, y)[2] = (pix2 > 255) ? 255 : uchar(pix2); 
      } 
     } 
} 

}

エラーがある:例外がスローさ:アクセス違反をお読みください。 cv :: Vec :: operatorが0x240C37EC4A8を返しました。与えられた

アドレスは正確にI.dataのアドレスです。どうしましたか?ご協力いただきありがとうございます。

+0

'CV ::マット&parmI'は、あなたが本当に参照渡しする必要があります。とにかく、Matクラスの代入はすでにポインタ代入です。 – macroland

+0

基本的に彩度を持つ要素ごとの乗算は何ですか? 'I = I.mul(flatField);'のように、すべてのコードの代わりに? –

+0

@macroland:はい、参照渡しが必要です。私は価値あるものを通そうとしていて、イメージは戻ってこなかった。 –

答えて

0

Accessing elements of a cv::Mat with at<float>(i, j). Is it (x,y) or (row,col)?をお読みになる場合は、xyをコード内のマトリックスの要素にアクセスするすべての場所で入れ替えてください。

+0

おっと!私はそれをするつもりだった。私は機能が働いたのであれば確かに気づいたでしょう。残念ながら、メモリアクセスエラーは、xとyの両方が0の場合に発生するため、問題は解決しません。 –

0

UMが...気にしません。例外は実際であり、このコードでは問題ではないことが判明しました。 Point Grayのサンプルコードを使用しています。ポインタはデータにコピーするだけのMatコンストラクタを使用して、Point Gray ImagePtrからMatに変換されます。 ImagePtrが範囲外になったため、データを使用しようとするとデータが無効になりました。 Mat.CopyTo()は問題を解決しました。私は非常に同じような問題を解決するために必要な場合はthisを読むことを強くお勧めします。