一个opencv与JAI的图像数据组织问题
2006-12-26 14:35
344 查看
最近在使用JNI,设法从Java中调用OpenCV的函数。在OpenCV中图像是以IplImage的形式封装的。IplImage是一个 Header,定义了图像的各种属性,通过查看IplImage结构体我们可以发现,图像数据实际上也是在一段连续的内存中分配的, IplImage.imageData就是指向这块数据的指针。随便访问一个结构体的成员是不好的,所以OpenCV提供了访问原始数据RawData的 方法
void cvGetRawData( const CvArr* arr, uchar** data, int* step=NULL, CvSize* roi_size=NULL );
典型的,对于一个三通道,颜色深度为256的图像img,假设我们知道它的width,height,为了取得其RawData,可以定义一个数组data,并调用cvGetRawData()函数,将RawData存放到data中:
int raw_data_length = width*height*3;
byte* data= (byte *)malloc(raw_data_length * sizeof(byte));
cvGetRawData( img, (uchar**)&data, NULL, NULL );
那么,这个时候,data内部是如何组织的呢?按照一般的逻辑,它应该是这样
{{34,123,90},{34,122,87},{21,123,88},......}
按照从左到右,从上到下的顺序,每个像素占三个byte。
如果把这个数据通过JNI传给Java程序,然后再按照上述逻辑重新“组装”成一幅图像,问题就来了。
为了便于调试,我使用了Matlab来“组装”并观察这幅Raw图像(height=13, width=17):
a=[34,123,90,34,122,
];
m=1;
for i=1:13
for j=1:17
for k=1:3
if a(m)<0
a(m)=
4000
a(m)+256;
end
d(i,j,k)=a(m);m=m+1;
end
end
end
figure,imshow(uint8(d));
应该是图像RawData的Size,Step之类的错误。
最终我没有找到具体错在那里,但是用下面的代码可以得到正确的数据。
// reconstruct image data
char *data;
int i, j, step;
CvSize size;
cvGetRawData( rstImg, (uchar**)&data, &step, &size );
step /= sizeof(data[0]);
int k = 0, offset = 0;
for ( i=0; i<size.height; i++, offset=i*step) {
for ( j=0; j<size.width; j++ ) {
result[k++] = data[offset+2];
result[k++] = data[offset+1];
result[k++] = data[offset];
offset += 3;
}
}
注意,Java里面的RGB图像和OpenCV的通道顺序正好是反过来的,即一个是RGB,一个是BGR。
至此,总算可以把OpenCV的图像和Java的图像对应起来了。至于如何在两者之间传递图像数据,请参见@todo:
void cvGetRawData( const CvArr* arr, uchar** data, int* step=NULL, CvSize* roi_size=NULL );
典型的,对于一个三通道,颜色深度为256的图像img,假设我们知道它的width,height,为了取得其RawData,可以定义一个数组data,并调用cvGetRawData()函数,将RawData存放到data中:
int raw_data_length = width*height*3;
byte* data= (byte *)malloc(raw_data_length * sizeof(byte));
cvGetRawData( img, (uchar**)&data, NULL, NULL );
那么,这个时候,data内部是如何组织的呢?按照一般的逻辑,它应该是这样
{{34,123,90},{34,122,87},{21,123,88},......}
按照从左到右,从上到下的顺序,每个像素占三个byte。
如果把这个数据通过JNI传给Java程序,然后再按照上述逻辑重新“组装”成一幅图像,问题就来了。
为了便于调试,我使用了Matlab来“组装”并观察这幅Raw图像(height=13, width=17):
a=[34,123,90,34,122,
];
m=1;
for i=1:13
for j=1:17
for k=1:3
if a(m)<0
a(m)=
4000
a(m)+256;
end
d(i,j,k)=a(m);m=m+1;
end
end
end
figure,imshow(uint8(d));
应该是图像RawData的Size,Step之类的错误。
最终我没有找到具体错在那里,但是用下面的代码可以得到正确的数据。
// reconstruct image data
char *data;
int i, j, step;
CvSize size;
cvGetRawData( rstImg, (uchar**)&data, &step, &size );
step /= sizeof(data[0]);
int k = 0, offset = 0;
for ( i=0; i<size.height; i++, offset=i*step) {
for ( j=0; j<size.width; j++ ) {
result[k++] = data[offset+2];
result[k++] = data[offset+1];
result[k++] = data[offset];
offset += 3;
}
}
注意,Java里面的RGB图像和OpenCV的通道顺序正好是反过来的,即一个是RGB,一个是BGR。
至此,总算可以把OpenCV的图像和Java的图像对应起来了。至于如何在两者之间传递图像数据,请参见@todo:
相关文章推荐
- 一个贯穿图像处理与数据挖掘的永恒问题
- 一个贯穿图像处理与数据挖掘的永恒问题
- opencv中读取图像像素数据的问题
- 解决OpenCV图像数据倒立的问题
- opencv中imread读取不了图像数据问题解决
- 在visual studio 2010中使用opencv imread函数读取图像失败,数据为空的问题解决方法。
- OpenCV图像数据字节对齐问题
- opencv图像显示遇到的一个问题
- oracle 数据泵 通过表空间导入导出的时候遇到的一个问题
- 使用LEFT JOIN多次关联同一个表获取数据不正确的问题
- 一个TCP包中的数据数据问题
- opencv-python图像数据的读取
- float数据的一个问题
- 一个关于Java数据类型的有趣问题
- openCV获取图像数据的方式
- OpenCV——Opencv彩色图像在matplot中显示问题的解决
- asp问题之“在文本框中无法显示出一个数据中空格后的部分”
- 向大家请教一个关于sharepoint2003的问题,如何使一个Custom List in Datasheet View中某个field从其他list抽取数据当显示时?
- OpenCV_复制一个或多个ROI图像区域
- OpenCV 处理内存中的图像数据