Почему утверждение терпит неудачу здесь

#c #opencv

#c #opencv

Вопрос:

Почему утверждение терпит неудачу здесь, когда я создаю 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*)amp;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=amp;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*)amp;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);
            }
    }
 

Ответ №1:

Потому sizeof(RGB) != sizeof(float) что именно этим вы заполнили здесь матрицу:

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

CV_32FC1 означает 1 компонент, 32-разрядная с плавающей запятой. Вы, вероятно, хотите CV_8UC3 . Смотрите Здесь или другую ссылку на OpenCV.

Ответ №2:

Вы можете пропустить все IplImage страдания, если используете cv::Mat img = cv::loadImage("blah.jpg"); Также, лучше использовать строку ptr для просмотра всех пикселей.
Он знает переходы, так что вам не о чем беспокоиться!

От рефмана:

Если вам нужно обработать целую строку 2D-массива, наиболее эффективный способ — сначала получить указатель на строку, а затем просто использовать простой оператор C []

Имейте в виду, что если вы загружаете большие изображения, которые имеют «скачки» в своих данных, ваш код не будет работать. В вашей ситуации

 cv::Mat img = cv::loadImage("blah.jpg");
const cv::Matamp; M = img;
for(int i = 0; i < rows; i  ) 
{
    const Vec3b* Mi = M.ptr<Vec3b>(i); 
    for(int j = 0; j < cols; j  )
    {
        const Vec3bamp; 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) .

Комментарии:

1. Вероятно, вы имеете в виду const Vec3bamp; Mij = Mi[j];