为什么断言在这里失败

Why does assertion fail here

本文关键字:失败 在这里 断言 为什么      更新时间:2023-10-16

当我创建CvMat *时,为什么断言在这里失败?在cv::Mat中使用指针加载的图像不会发生这种情况。

    struct RGB { unsigned char b, g, r; };
    cv::Point p;
    RGB *data;
    CvMat* mat = cvCreateMat(300,300,CV_32FC1);
    for( row = 0; row < mat->rows; ++row) 
    {
            for ( col = 0; col < mat->cols; ++col) 
            {
                 p.x=row,p.y=col;
        ERROR ----->>>   assert((mat->step/mat->cols) == sizeof(RGB));
                 data = (RGB*)&mat->data;
                 data += p.y * mat->cols + p.x;
            }
    }

对于这段代码,断言不会失败:

    IplImage * img=cvLoadImage("blah.jpg");
    int row=0,col=0;
    cv::Mat in(img);
    cv::Mat *mat=&in;
    cv::Point p;
    struct RGB { unsigned char b, g, r; };
    RGB *data;
    for( row = 0; row < mat->rows; ++row) 
    {
            for ( col = 0; col < mat->cols; ++col) 
            {
                 p.x=row,p.y=col;
                 assert((mat->step/mat->cols) == sizeof(RGB));
                 data = (RGB*)&mat->data;
                 data += p.y * mat->cols + p.x;
                 printf("Row=%dxCol=%d      b=%u g=%u r=%un",row,col,data->b,data->g,data->r);
                 wait_for_frame(1);
            }
    }

因为sizeof(RGB) != sizeof(float),也就是你在这里填入的矩阵:

 CvMat* mat = cvCreateMat(300,300,CV_32FC1); 

CV_32FC1表示1个分量,32位浮点数。你可能需要CV_8UC3

如果使用,可以跳过整个IplImage的痛苦cv::Mat img = cv::loadImage("blah.jpg");此外,最好使用行ptr来遍历所有像素。
它会跳,所以你不用担心!

来自refman:

如果你需要处理2D数组的一整行,效率最高方法是先获得指向行的指针,然后使用C操作符[]

请注意,如果你正在加载数据中有"跳转"的大图像,你的代码将无法工作。在你的情况下

cv::Mat img = cv::loadImage("blah.jpg");
const cv::Mat& M = img;
for(int i = 0; i < rows; i++) 
{
    const Vec3b* Mi = M.ptr<Vec3b>(i); 
    for(int j = 0; j < cols; j++)
    {
        const Vec3b& Mij = Mi[j];
        std::cout<<"Row="<<i<<"Col="<<j<<"t";
        std::cout<<"b="<<Mij[0]<<" g="<<Mij[1]<<" r="<<Mij[2]<<std::endl;
    }
}

是最快的正确方法。否则,您可以使用M.at<Vec3b>(i,j)