OpenCV Mat到数组访问

时间:2016-01-10 23:42:28

标签: c++ opencv mat

我从Mat.data访问数据时遇到问题。我对图片执行操作,我需要分别访问每个像素。 我必须对简单类型(float,int等)进行必要的操作。 我访问数据的方式如下:

for (int idx = 0; idx < image.rows; idx++) {
        for (int idy = 0; idy < image.cols; idy++) {
            int color_tid = idx * image.cols * image.channels() + idy * image.channels();
            uint8_t blue = image.data[color_tid];
            uint8_t green = image.data[color_tid + 1];
            uint8_t red = image.data[color_tid + 2];
            float pixelVal = (int) blue + (int) green + (int) red;
            (...)
        }
    }

此方法仅适用于方形图像(NxN像素),但对于NxM,方形区域外(较小边缘)存在异常。 有谁知道任何其他方式来访问图片Mat的数据? 示例图像(正确结果):

enter image description here

异常(我的问题)

enter image description here

2 个答案:

答案 0 :(得分:1)

您问题中的代码包含一些缺陷:

  • 交换行和列(行为Y,列为X)
  • 行之间的步长(又名“stride”)并不总是等于列数

使用Mat::at<>使代码更简单:

 for(int row = 0; row < image.rows; ++row)
 {
     for(int col = 0; col < image.cols; ++col)
     {
         const Vec3b& pt = image.at<Vec3b>(row, col);
         float pixelVal = pt[0] + pt[1] + pt[2];
         ...    
     }   
 } 

答案 1 :(得分:1)

我建议您关注Mat

中的data layout

enter image description here

所以你的循环变成了:

for (int r = 0; r < img.rows; ++r)
{
    for (int c = 0; c < img.cols; ++c)
    {
        uchar* ptr  = img.data + img.step[0] * r + img.step[1] * c;
        uchar blue  = ptr[0];
        uchar green = ptr[1];
        uchar red   = ptr[2];

        float pixelVal = blue + green + red;
    }
}

您最终可以执行少量操作,例如:

for (int r = 0; r < img.rows; ++r)
{
    uchar* pt = img.data + img.step[0] * r;
    for (int c = 0; c < img.cols; ++c)
    {
        uchar* ptr  = pt + img.step[1] * c;
        uchar blue  = ptr[0];
        uchar green = ptr[1];
        uchar red   = ptr[2];

        float pixelVal = blue + green + red;
    }
}