简体   繁体   中英

opencv Mat memory access error

I'm trying to write a function to compensate lens vignetting in an OpenCV project. The problem is that when I attempt to access the first pixel in the Mat, I get a memory access error. It's probably a silly error, but I'd appreciate it if you could point it out to me. Here's the function:

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);
            }
        }
}

}

The error is: Exception thrown: read access violation. cv::Vec::operator returned 0x240C37EC4A8.

The address given is exactly the address for I.data. What's wrong? Thanks for your help.

Um... Never mind. It turned out that the exception was real and not a problem with this code. I am using sample code from Point Grey. It converts from a Point Grey ImagePtr to a Mat using a Mat constructor that just copies the pointer to the data. The ImagePtr went out of scope, so the data was invalid when I attempted to use it. Mat.CopyTo() solved the problem. I highly recommend reading this if you need a fast way to solve a similar problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM