如何/为什么imagedata存储为char – OpenCV
我有点困惑。
我刚刚开始使用OpenCV,它的图像数据由char指针指向。 考虑到实际数据本身可以是任意数量的数据类型,例如uint,float,double,我无法弄清楚它是如何工作的。 据我所知,指针必须与它所代表的指针的类型相同。
值得注意的是openCV是一个C库,我的背景是C ++,所以我不知道如何在C中解决这些需要变量类型的问题。
例如,从学习OpenCV中获取的以下代码说明了我的困惑:
void saturate_sv( IplImage* img ) { for( int y=0; yheight; y++ ) { uchar* ptr = (uchar*) ( img->imageData + y * img->widthStep ); for( int x=0; xwidth; x++ ) { ptr[3*x+1] = 255; ptr[3*x+2] = 255; } } }
这样可行,但是当我尝试对IPL_DEPTH_64F类型的iplImage进行操作并使用ptr [3 * x + 1] = 1时结果不正确。 为了解决我的问题:我如何通过char指针处理整数或浮点数据,具体如何纠正上面的例子来处理双精度数据。
谢谢
-
IPL_DEPTH_64F
或double
图像将处理0 – 1中的数据。 - 如果你已经习惯了C ++,你应该看看OpenCV2.0 ,它有几个C ++类,最重要的是,一个类,即
Mat
来处理图像,矩阵等。
这是一种有效访问图像中元素的简单方法:
IplImage* img = cvCreateImage(cvSize(300,300),IPL_DEPTH_64F,1); for( int y=0; yheight; y++ ) { double* ptr = reinterpret_cast(img->imageData + y * img->widthStep); for( int x=0; xwidth; x++ ) { ptr[x] = double(255); } } cvNamedWindow("SO"); cvShowImage("SO",img); cvWaitKey(); cvDestroyAllWindows(); cvReleaseImage(&img);
由于您正在处理double
图像,因此更有意义:
- 使用
double
指针,以便您可以使用ptr[x]
轻松分配行中的元素 - 指针算术以字节为单位(
img->imageData + y * img->widthStep
)并将其转换为double
指针
此外,以字节(或uchar
,即unsigned char
)执行指针运算非常重要 ,因为OpenCV倾向于使用额外字节填充图像行以提高效率(特别是对于double
图像)。
因此,即使double
元素是8个字节,并且你有300行,也不能保证一行不会以8 * 300或2400字节结束,因为OpenCV可能会填充结尾。
因此,这会阻止您初始化指向图像的第一个元素的指针,然后使用ptr[y*img->height+x]
来访问元素,因为每行可能有超过8*(y*img->height)
字节。
这就是为什么示例代码每次使用img->widthStep
计算每行的指针,这表示每行的真实大小(以字节为单位)。
OpenCV 2.0
如果你使用Mat
类,你可以沿着这些方向做同样的事情:
cv::Mat img(300,300,CV_64FC1); for( int y=0; y(img.data + y * img.step); for( int x=0; x
其中img.step是连续行之间的距离,以字节为单位
如果你想直接访问元素(更慢):
img.at