cvGetRawData()的奇怪问题

最近在使用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)
=a(m)+256;
               end
               d(i,j,k)
=a(m);m=m+1;
           end
      end
end
figure,imshow(uint8(d));


無題.JPG

应该是图像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:





 



 

posted on 2006-11-28 16:11 肥虫 阅读(2032) 评论(0)  编辑  收藏 所属分类: Image ProcessingJava Language


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2006年11月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

常用链接

留言簿(2)

随笔分类

随笔档案

相册

搜索

最新评论

阅读排行榜

评论排行榜