cvGetRawData()的奇怪問題

          最近在使用JNI,設(shè)法從Java中調(diào)用OpenCV的函數(shù)。在OpenCV中圖像是以IplImage的形式封裝的。IplImage是一個Header,定義了圖像的各種屬性,通過查看IplImage結(jié)構(gòu)體我們可以發(fā)現(xiàn),圖像數(shù)據(jù)實際上也是在一段連續(xù)的內(nèi)存中分配的,IplImage.imageData就是指向這塊數(shù)據(jù)的指針。隨便訪問一個結(jié)構(gòu)體的成員是不好的,所以O(shè)penCV提供了訪問原始數(shù)據(jù)RawData的方法
          void cvGetRawData( const CvArr* arr, uchar** data, int* step=NULL, CvSize* roi_size=NULL );

          典型的,對于一個三通道,顏色深度為256的圖像img,假設(shè)我們知道它的width,height,為了取得其RawData,可以定義一個數(shù)組data,并調(diào)用cvGetRawData()函數(shù),將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內(nèi)部是如何組織的呢?按照一般的邏輯,它應(yīng)該是這樣
          {{34,123,90},{34,122,87},{21,123,88},......}

          按照從左到右,從上到下的順序,每個像素占三個byte。
          如果把這個數(shù)據(jù)通過JNI傳給Java程序,然后再按照上述邏輯重新“組裝”成一幅圖像,問題就來了。
          為了便于調(diào)試,我使用了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

          應(yīng)該是圖像RawData的Size,Step之類的錯誤。

          最終我沒有找到具體錯在那里,但是用下面的代碼可以得到正確的數(shù)據(jù)。

           

          // 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的圖像對應(yīng)起來了。至于如何在兩者之間傳遞圖像數(shù)據(jù),請參見@todo:





           



           

          posted on 2006-11-28 16:11 肥蟲 閱讀(2048) 評論(0)  編輯  收藏 所屬分類: Image ProcessingJava Language


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

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

          統(tǒng)計

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          相冊

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 论坛| 石狮市| 称多县| 象州县| 舒城县| 穆棱市| 吉林市| 厦门市| 张家川| 邹城市| 泾川县| 双峰县| 阿瓦提县| 镇平县| 甘孜县| 宝山区| 桂平市| 罗平县| 隆昌县| 黄大仙区| 霞浦县| 武冈市| 昌宁县| 梅州市| 古田县| 南康市| 桦甸市| 伊宁县| 资源县| 平潭县| 彩票| 琼结县| 阳谷县| 新化县| 成安县| 南投县| 宁城县| 富宁县| 庐江县| 文山县| 革吉县|