【问题标题】:writing to IplImage imageData写入 IplImage imageData
【发布时间】:2011-10-17 11:20:20
【问题描述】:

我想将数据直接写入 IplImage 的 imageData 数组,但我找不到很多关于它是如何格式化的信息。让我特别烦恼的一件事是,尽管创建了具有三个通道的图像,但每个像素有四个字节。

我用来创建图像的函数是:

IplImage *frame = cvCreateImage(cvSize(1, 1), IPL_DEPTH_8U, 3);

根据所有迹象,这应该会创建一个三通道 RGB 图像,但似乎并非如此。

例如,我如何将单个红色像素写入该图像?

感谢您的帮助,这让我很难过。

【问题讨论】:

  • 这个答案假定实际上每个像素会有 3 位。我已经确认我的图像的 nChannels 为 3,但每个像素仍有 4 位。就其价值而言,它们实际上并未与像素分组。它们似乎存储在每一行的末尾,全部设置为 0。

标签: image-processing opencv iplimage


【解决方案1】:

直接回答你的问题,将像素涂成红色:

IplImage *frame = cvCreateImage(cvSize(1, 1), IPL_DEPTH_8U, 3);
int y,x;
x=0;y=0; //Pixel coordinates. Use this for bigger images than a single pixel.
int C=2; //0 for blue, 1 for green and 2 for red (BGR is the default format).
frame->imageData[y*frame->widthStep+3*x+C]=(uchar)255;

【讨论】:

    【解决方案2】:

    如果您正在查看frame->imageSize,请记住它是frame->height * frame->widthStep,而不是frame->height * frame->width

    BGR 是 OpenCV 的原生格式,而不是 RGB。

    另外,如果您刚刚开始,您应该考虑使用 C++ 接口(其中 Mat 替换 IplImage),因为这是未来的方向,并且使用起来更容易。

    下面是一些直接访问像素数据的示例代码:

    int main (int argc, const char * argv[]) {
    
        IplImage *frame = cvCreateImage(cvSize(41, 41), IPL_DEPTH_8U, 3);
    
        for( int y=0; y<frame->height; y++ ) { 
            uchar* ptr = (uchar*) ( frame->imageData + y * frame->widthStep ); 
            for( int x=0; x<frame->width; x++ ) { 
                ptr[3*x+2] = 255; //Set red to max (BGR format)
            }
        }
    
        cvNamedWindow("window", CV_WINDOW_AUTOSIZE);
        cvShowImage("window", frame);
        cvWaitKey(0);
        cvReleaseImage(&frame);
        cvDestroyWindow("window");
        return 0;
    }
    

    【讨论】:

    • 谢谢。我终于发现了这一点,不幸的是,对于我在测试中使用的一个和两个像素行,行舍入分别增加了一个和两个像素。我会看看 mat,在浏览时它似乎是一个更不透明的系统,但我想这只是缺乏熟悉。
    • 我不是 OpenCV 的世界权威,但我看不出 Mat 在哪里比 IplImage 更不透明。运算符重载等 C++ 的花里胡哨使它更易于使用。文档位于opencv.itseez.com/modules/core/doc/basic_structures.html#mat
    【解决方案3】:

    unsigned char* imageData = [r1, g1, b1, r2, g2, b2, ..., rN, bn, gn]; // n = 高度*图像宽度 frame->imageData = imageData.

    将您的图像作为高度 N 和宽度 M 的维度数组,并将其排列成长度为 N*M 的行向量。为 IPL_DEPTH_8U 图像设置 unsigned char* 类型。

    【讨论】:

    • 问题是每个像素有四个字节。额外的字节似乎在每一行的末尾分组,并且都设置为零,但我不知道为什么。另外,我不知道这是否重要,但图像似乎存储在 BGR 中,而不是 RGB。
    • 不确定额外的 4 个字节?你怎么看?无论如何尝试将图像数据分配给 char* 数组。这对我有用。是的,有些 c++ 库使用 BGR,有些使用 RGB。如果显示时颜色层看起来切换了,则使用 cvCvtColor(frame, frame, CV_BRG2RGB) 切换 R 和 B 层。
    • 图像大小始终等于 4 * 像素数。我只是通过打印 imageData 数组来尝试找出数据的存储方式来找到位置。不管怎样,我会试试的。
    猜你喜欢
    • 2012-08-03
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 2012-04-20
    • 2023-03-17
    • 2012-07-01
    • 1970-01-01
    • 2011-07-08
    相关资源
    最近更新 更多