从IPLImage到Mat

时间:2013-05-07 17:04:20

标签: opencv image-processing iplimage

我很熟悉OpenCV 1.1中使用的IPL图像格式。但是我使用的是最新的2.4版本,并希望切换到OpenCV的C ++界面。这是我访问图像中像素的方法:

int step = img->widthStep;
int height = img->height;
int width = img->width;
unsigned char* data = (unsigned char*) img->imageData;

for (int i=0; i<height; i++)
{
    for (int j=0; j<step; j+=3)          // 3 is the number of channels.
    {
        if (data[i*step + j] > 200)      // For blue
            data[i*step + j] = 255;

        if (data[i*step + j + 1] > 200)  // For green
            data[i*step + j + 1] = 255;

        if (data[i*step + j + 2] > 200)  // For red
            data[i*step + j + 2] = 255;
    }
} 

我需要帮助才能使用Mat结构转换这个精确的代码块。我在这里和那里找到了几个函数,但如果我得到上面几行整体的精确转换将会非常有用。

2 个答案:

答案 0 :(得分:8)

// Mat mat; // a bgr, CV_8UC3 mat

for (int i=0; i<mat.rows; i++)
{
    // get a new pointer per row. this replaces fumbling with widthstep, etc.
    // also a pointer to a Vec3b pixel, so no need for channel offset, either
    Vec3b *pix = mat.ptr<Vec3b>(i); 
    for (int j=0; j<mat.cols; j++)
    {
        Vec3b & p = pix[j];
        if ( p[0] > 200 ) p[0] = 255;
        if ( p[1] > 200 ) p[1] = 255;
        if ( p[2] > 200 ) p[2] = 255;
    }
}

答案 1 :(得分:3)

首先,您可以对IPLImage执行相同的操作,并使用Mat的内置构造函数进行转换。

其次,您的代码似乎过于复杂,因为您对所有3个维度执行相同的操作。以下是更整洁的(用mat表示法):

unsigned char* data = (unsigned char*) img.data;

for (int i = 0; i < image.cols * image.rows * image.channels(); ++i) {
  if (*data > 200) *data = 255;
  ++data;
}

如果您希望频道的节目不同,那么:

unsigned char* data = (unsigned char*) img.data;
assert(image.channels() == 3);

for (int i = 0; i < image.cols * image.rows; ++i) {
  if (*data > 200) *data = 255;
  ++data;
  if (*data > 201) *data = 255;
  ++data;
  if (*data > 202) *data = 255;
  ++data;
}