【问题标题】:From IPLImage to Mat从 IPLImage 到 Mat
【发布时间】:2013-05-01 17:44:26
【问题描述】:

我非常熟悉 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 结构。我在这里和那里找到了几个函数,但是如果我将上述几行作为一个整体进行精确转换,这将非常有帮助。

【问题讨论】:

    标签: opencv image-processing iplimage


    【解决方案1】:

    首先,您可以对 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;
    }
    

    【讨论】:

    • 在 IPL 图像中完成所有操作,然后再转换回来 - 这是否足够快?我不希望这个过程花费一些额外的处理时间。对于那个过于复杂的事情 - 这只是一个示例代码,假设我需要为红绿和蓝提供不同的阈值。那你的方法行得通吗?
    • 在 Mat 和 IplImage 之间转换时,您可以选择是否复制数据。如果不复制,开销真的很小。即使您复制,我怀疑开销很大,因为您的整个处理时间超过 1 秒左右。添加了不同阈值的案例。
    • 如果矩阵有步骤,您的代码将不起作用。就是这种情况,例如对于创建为另一个矩阵的 ROI 的矩阵标题。使用迭代器或行指针访问来避免此类错误!
    【解决方案2】:
    // 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2011-06-07
      相关资源
      最近更新 更多