OpenCV的IplImage與我的CHYBitmap的互轉

一. CHYBitmap

CHYBitmap是我自己讀取bmp文件的一個類.

二. IplImage

IplImage是OpenCV裏管理圖像的一個類.(經常被它的名稱誤導, 總以爲它是一個接口!!!)

三. 互轉

3.1 互轉

// 圖像在垂直方向的行互反拷貝
void ReVCopy(const unsigned char* pDataSrc, unsigned char* pDataTar, long lHeight, long lStep)
{
	int i = 0;
	for(i = 0; i < lHeight; ++i)
	{
		memcpy(pDataTar + i * lStep, pDataSrc + (lHeight - 1 - i) * lStep, lStep);
	}
}


void CHYBitmapToSTIplImage(const CHYBitmap& refCHYBitmap, STIplImage& refSTIplImage)
{
	refSTIplImage.Release();
	refSTIplImage.m_pIplImage = cvCreateImage(
		cvSize(refCHYBitmap.m_pBITMAPINFO->bmiHeader.biWidth, refCHYBitmap.m_pBITMAPINFO->bmiHeader.biHeight), 
		IPL_DEPTH_8U, refCHYBitmap.m_pBITMAPINFO->bmiHeader.biBitCount / 8);
	ReVCopy(refCHYBitmap.m_pBITMAPDATA, (unsigned char *)(refSTIplImage.m_pIplImage->imageData), 
		refSTIplImage.m_pIplImage->height, refSTIplImage.m_pIplImage->widthStep);
}


void STIplImageToCHYBitmap(const STIplImage& refSTIplImage, CHYBitmap& refCHYBitmap)
{
	refCHYBitmap.Create(refSTIplImage.m_pIplImage->depth * refSTIplImage.m_pIplImage->nChannels,
		refSTIplImage.m_pIplImage->width, refSTIplImage.m_pIplImage->height, true);
	ReVCopy((unsigned char *)(refSTIplImage.m_pIplImage->imageData), refCHYBitmap.m_pBITMAPDATA,
		refSTIplImage.m_pIplImage->height, refSTIplImage.m_pIplImage->widthStep);
}

3.2 說明

1. IplImage與我的CHYBitmap非常相似. 也是由BMP頭和數據組成.
2. STIplImage是對IplImage的封裝, 只爲自動釋放.
3. 使用CHYBitmap加載一幅bmp圖片, 用DC顯示能正常顯示; 使用IplImage加載一幅bmp圖片, 用OpenCV的窗口顯示也能正常; 都與使用Window的默認圖片瀏覽軟件顯示是一致的.  但是CHYBitmap轉IplImage後, IplImage顯示就會反了過來.(或者IplImage轉CHYBitmap後, CHYBitmap顯示也會反了過來).
4. 查看了CHYBitmap和IplImage的圖像數據, 發現他們在內存上是反的(CHYBitmap的第一行是IplImage的最後一行). CHYBitmap中讀取圖像數據是順序讀取的, IplImage內部讀取可能是反過來讀取的).
5. StretchDIBits函數中最後一個參數可以設置反轉顯示. 爲了統一, 我在它們轉換的時候, 使用ReVCopy函數把數據轉換一下.
6. OpenCV中也可以使用cvFlip函數對IplImage進行反轉.

四. 其他

觸類旁通, IplImage與其他的圖像類的轉換也類似, 無非就是bmp頭和圖像數據. 其中bmp頭的主要信息是長, 寬, 深度和頻道等等.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章