您的位置:首页 > 大数据 > 人工智能

一个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:

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  byte matlab jni java null header