獲取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座標。這樣在運用模板濾波時,或是進行相鄰畫素計算時是準確的。