1. 程式人生 > >獲取RGB影象的單個點的資料-視訊處理基礎(1)

獲取RGB影象的單個點的資料-視訊處理基礎(1)

    把最近看的整理一下。

    視訊旋轉照我的理解就是處理影象中的unsigned char指標所指的資料點,現在的思路是對RGB影象進行旋轉,但是旋轉之前,我們應該要先獲得RGB影象點的資料結;

    RGB影象資料的儲存是一個畫素點佔三個位元組,也就是說二個畫素點(x1,y1),(x1,y1),那麼它們的畫素值分別是B0,G0,R0,B1,G1,R1。這六個值花佔六個位元組,而且是連線存放在一片記憶體空間。那麼,要怎麼了獲得每個畫素點的RGB呢?

    首先,我們得知道影象每行的位元組數

    一、影象每行位元組數的計算  
方法一:.利用巨集:#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)
    方法二: (nImageWidth*nBitCount+31)/32*4;
     nImageWidth為影象寬度;nBitCount為每個畫素所佔的位數,如:二值為1,灰度為8,真彩24
     方法三:  (mImageWidth * (mImageBitCount / 8) + 3) & ~3 

      方法一說明:這裡有一個巨集,可以很方便的算出這個位元組數:#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4),使用方法如下:long lLineBytes = WIDTHBYTES(m_lWidth * 24)。如果是8位的bmp影象,或4位,2位,則將算式中的24改為相應的位數即可。另外bmp檔案分檔案頭14位元組,資訊40位元組,調色盤若干位元組,資料lLineBytes*height位元組。

     注意:bmp檔案的資料塊部分不是直接的一個個畫素排列後儲存。為了要保證每行的位元組數都能夠被4整除,往往要在每行資料後面補充1,2或3個位元組的冗餘資訊。
X*Y大小的24位bmp影象,每個畫素佔3個位元組,如果X*3後不能夠被4整除,則每行有可能是X*3+1, X*3+2或X*3+3, 取決於哪個數值可以被4整除。

     二、訪問影象中特定的一個第x行,第y列的畫素

     假設檔案的起始位置是影象的左上角,畫素依次從左向右,從上到下排列。 
   假設指向檔案的資料區的指標byte* p_bmpdata, 檔案為24位,為了訪問第x行,第y列,可以用如下公式:
      b = p_bmpdata[lLineBytes * x + y*3]; 
     g = p_bmpdata[lLineBytes *x + y*3+1]; 
      r = p_bmpdata[lLineBytes * x + y*3+2];
      如果要從第一個畫素開始遍歷整個資料區,可以用這樣的方式:
      for (i = 0; i <height; i ++)
      {
         for (j = 0; j < width; j ++)

       {
            b = p_bmpdata[lLineBytes * i + j*3];
            g = p_bmpdata[lLineBytes * i + j*3+1];
            r = p_bmpdata[lLineBytes * i + j*3+2];
         }
      }
      注意,這裡的height和width是影象的列畫素數和行畫素數。而迴圈內與i相乘的是整行的位元組數,不是行畫素數。

    三、建立影象緩衝區

    當使用自己建立的影象緩衝區是,遍歷的方法又有所不同。假設為上bmp檔案的資料作一個緩衝。
     byte *p_bmpbuffer = new byte[height*width*3];
     for(i = 0; i< width; i++)
     {
        for(j=0; j<height; j++)
        {
            p_bmpbuffer[(i*height+j)*3] =  p_bmpdata[lLineBytes * i + j*3];
            p_bmpbuffer[(i*height+j)*3+1] =  p_bmpdata[lLineBytes * i + j*3+1];
            p_bmpbuffer[(i*height+j)*3+2] =  p_bmpdata[lLineBytes * i + j*3+2];
        }
     }

     //這裡不用memcpy的原因是p_bmpdata的長度為height*lLineBytes, 而p_bmpbuffer的長度是height*width*3, p_bmpdata在每行末都有1,2或3個位元組的冗餘。

     byte b, g, r; 
     for(i = 0; i< height; i++)
     {
       for(j=0; j<width; j++)

    {
            b = p_bmpbuffer[(i*width+j)*3];
           g = p_bmpbuffer[(i*width+j)*3+1];
            r = p_bmpbuffer[(i*width+j)*3+2];
        }
     }
     //這裡對畫素的訪問i,j的意義發生變化,之前的迴圈順序訪問下來,影象的行被列值y中間截斷,雖然可以順序依次訪問每個畫素,但i,j值沒有實際意義。第二次迴圈,i值即對應當前畫素y座標,j值對應當前畫素x座標。這樣在運用模板濾波時,或是進行相鄰畫素計算時是準確的。