OpenCV中cv::Mat字節對齊方法


使用OpenCV過程中,cv::Mat比IplImage更容易操作,也符合C++使用者的習慣。但是一般Mat的數據並不是字節對齊的對於需要字節對齊數據的函數(比如控件上的位圖顯示)來說,就會產生相應的問題。下面介紹將Mat數據轉換為字節對齊的uchar數據的方法,以三通道圖像為例,代碼如下:

 

[cpp]  view plain  copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. //  這里 frame 為三通道圖像  
  2.         cv::Mat roiImg;   
  3.         frame.rowRange(frame.rows/2, frame.rows).  
  4.               colRange(frame.cols/4, frame.cols*3/4).  
  5.               copyTo(roiImg); // 提取ROI區域  
  6.   
  7.         int widthStep = (roiImg.cols*roiImg.elemSize()+3)/4*4// 補齊行字節數,使它能夠被4整除    4字節對齊
  8.         uchar *frameData = (uchar *)calloc(roiImg.rows*widthStep, sizeof(uchar)); // 申請內存  
  9.         memset(frameData, 0, roiImg.rows*widthStep);  
  10.           
  11. // 逐一復制數據  
  12.         uchar *p1, *p2;  
  13.         for (int i = 0; i < roiImg.rows; i++)  
  14.         {  
  15.             p1 = roiImg.data + i*roiImg.cols*roiImg.channels();  
  16.             p2 =  frameData + i * widthStep;  
  17.             for (int j = 0; j < roiImg.cols; j++)  
  18.             {  
  19.                 *(p2) = *(p1);  
  20.                 *(p2+1) = *(p1+1);  
  21.                 *(p2+2) = *(p1+2);        
  22.                 p1 += 3;  
  23.                 p2 += 3;  
  24.             }  
  25.         }  

 

附加說明:

1、對應IplImage的cvLoadImage函數加載的圖片數據是字節對齊的,而直接將cv::Mat轉換為IplImage類型,並不會將字節對齊,只是加了個文件頭而已

2、我在寫代碼的過程中,還發現另一個問題(與主題無關),提取ROI區域時,如果采用:

 

[cpp]  view plain  copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. cv::Mat roiImg = frame(cv::Rect(10, 10, 50, 50));  

這樣的拷貝為淺拷貝,對后續采用指針引用逐個復制數據的過程中,實際訪問的是原frame的數據。roiImg的許多參數都仍為frame的參數,並沒有相應的改變,容易引發錯誤。這里還是采用copyTo這樣的深拷貝比較穩妥。這是實驗過程中發現的問題,也困擾了我很長時間。記錄下來,以防下次出錯。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM