如何/为什么为imageData存储为char - OpenCV的 [英] How/Why is imagedata stored as char - OpenCV
问题描述
我是一点点困惑。
我刚开始接触的OpenCV和图像数据是由一个字符指针指向。我不能完全制定出如何工作的考虑到实际数据本身可能是任何数量的数据类型,例如UINT,浮点型,双。据我所知,指针必须是相同类型的指针,重新presents的。
这也许值得一提的OpenCV的是C库和我的背景是C ++,所以我不知道如何需要的变量类型,这些问题用C都解决了。
例如来自OpenCV的学习采取的follwing code说明了我的困惑:
无效saturate_sv(*的IplImage IMG){
对于(INT Y = 0; Y< img->高度; Y ++){
UCHAR * PTR =(UCHAR *)(
img->的imageData + Y * img-> widthStep
);
对于(INT X = 0; X< img->宽度; X ++){
ptr的[3 * X + 1] = 255;
ptr的[3 * X + 2] = 255;
}
}
}
所以这个工作,但是当我尝试在类型IPL_DEPTH_64F的IplImage的操作使用PTR [3 * X + 1] = 1的结果是不正确的。因此,要提炼出自己的问题:我怎么能在整数或浮点数通过字符指针工作点数据,具体我怎么能纠正上面的例子有双precision数据进行工作。
感谢
-
IPL_DEPTH_64F
或双击
图像会照顾数据从0 - 1 - 如果你习惯了C ++,你应该看看 OpenCV2.0 其中有几个C ++类,最重要的一类,即
垫
来处理图像,矩阵等。
下面是访问图像有效元素的简单方法:
的IplImage * IMG = cvCreateImage(cvSize(300,300),IPL_DEPTH_64F,1);
对于(INT Y = 0; Y< img->高度; Y ++)
{
双* PTR = reinter pret_cast<双* GT;(img->的imageData + Y * img-> widthStep);
对于(INT X = 0; X< img->宽度; X ++)
{
PTR [X] =双(255);
}
}
cvNamedWindow(SO);
cvShowImage(SO,IMG);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage(安培; IMG);
既然你正在使用一个双击
图像,则更有意义:
- 与
双击
指针,这样你就可以轻松地分配在一排的元素与PTR工作[X]
- 请以字节为指针运算(
img->的imageData + Y * img-> widthStep
),它要转换成双
指针
此外,它的重要你做字节(指针算术或 UCHAR
,即 unsigned char型
),因为 OpenCV的趋于垫图片有额外的字节以效益为行(尤其是双击
图像)。
所以,即使一个双击
元素是8个字节,你有,比如说,300行,一行不能保证在8 * 300或2400个字节,因为结束OpenCV的威力垫结束。
因此,从初始化指针图像的第一元件,然后使用此prevents你 ptr的[Y * img->高度+ X]
访问元素,因为每行可能比 8 *(Y * img->高度)以上。
字节
这是为什么例如code。使用每次计算指针到每一行 img-> widthStep
从而重新presents每一行的真实大小以字节计。
OpenCV的2.0
如果您使用垫
类,你可以做同样的事情沿着这些路线:
CV ::垫IMG(300,300,CV_64FC1);
对于(INT Y = 0; Y< img.rows; Y ++)
{
双* PTR = reinter pret_cast<双* GT;(img.data + Y * img.step);
为(中间体X = 0; X&下; img.cols; X ++)
{
PTR [X] =双(255);
}
}
CV :: namedWindow(SO);
CV :: imshow(SO,IMG);
CV :: waitKey();
,其中img.step是字节连续行之间的距离
如果你想直接访问该元素(慢):
img.at<双>(Y,X)
I'm a tad confused.
I am just getting started with OpenCV and its image data is pointed to by a char pointer. I can't quite work out how that works considering the actual data itself could be any number of data types, e.g. uint, float, double. As far as I knew, a pointer had to be of the same type as the pointer it represents.
It's probably worth noting that openCV is a C library and my background is C++, so I am unaware of how these problems of needing variable types are solved in C.
For example the follwing code taken from Learning OpenCV illustrates my confusion:
void saturate_sv( IplImage* img ) {
for( int y=0; y<img->height; y++ ) {
uchar* ptr = (uchar*) (
img->imageData + y * img->widthStep
);
for( int x=0; x<img->width; x++ ) {
ptr[3*x+1] = 255;
ptr[3*x+2] = 255;
}
}
}
So this works, but when I try to operate on a iplImage of type IPL_DEPTH_64F and use ptr[3*x+1] = 1 The results are incorrect. So to distil my problems: how can I work on integer or floating point data through char pointers and specifically how could I rectify the above example to work with a double precision data.
Thanks
IPL_DEPTH_64F
ordouble
images will take care of the data from 0 - 1.- If you're used to C++ you should check out OpenCV2.0 which has several C++ classes and most importantly, one class, i.e.
Mat
to handle images, matrices, etc.
Here's a simple way to access elements in your image efficiently:
IplImage* img = cvCreateImage(cvSize(300,300),IPL_DEPTH_64F,1);
for( int y=0; y<img->height; y++ )
{
double* ptr = reinterpret_cast<double*>(img->imageData + y * img->widthStep);
for( int x=0; x<img->width; x++ )
{
ptr[x] = double(255);
}
}
cvNamedWindow("SO");
cvShowImage("SO",img);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage(&img);
Since you're working with a double
image, it makes more sense to:
- Work with a
double
pointer so you can easily assign elements in a row withptr[x]
- Do the pointer arithmetic in bytes (
img->imageData + y * img->widthStep
) and the cast it to adouble
pointer
Also, it's important that you do the pointer arithmetic in bytes (or uchar
, i.e. unsigned char
) since OpenCV tends to pad the rows of the images with extra bytes for efficiency (especially for double
images).
So even if a double
element is 8 bytes, and you have, say, 300 rows, a row is not guaranteed to end at 8*300 or 2400 bytes since OpenCV might pad the end.
Therefore, this prevents you from initializing a pointer to the first element of the image and then using ptr[y*img->height+x]
to access elements since each row might have more than 8*(y*img->height)
bytes.
That's why the example code calculates the pointer to each row each time using img->widthStep
which represents the true size of each row in bytes.
OpenCV 2.0
If you use the Mat
class, you can do the same thing along these lines:
cv::Mat img(300,300,CV_64FC1);
for( int y=0; y<img.rows; y++ )
{
double* ptr = reinterpret_cast<double*>(img.data + y * img.step);
for( int x=0; x<img.cols; x++ )
{
ptr[x] = double(255);
}
}
cv::namedWindow("SO");
cv::imshow("SO",img);
cv::waitKey();
where img.step is the distance between successive rows in bytes
And if you want to directly access the element (slower):
img.at<double>(y,x)
这篇关于如何/为什么为imageData存储为char - OpenCV的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!