1. 程式人生 > >使用OpenCV 讀取圖片 ,再用OpenGL顯示,影象有錯位

使用OpenCV 讀取圖片 ,再用OpenGL顯示,影象有錯位

最近在做Kinect跟蹤的時候需要做視差圖與蒙版的運算。因為圖片很多,所以想利用OpenGL的GLSL來加速。做到最後發現生成的影象不對!自習檢查了程式碼流程,沒發現問題。

單步除錯的時候看到影象變數有資料也沒有追究,浪費N個小時之後,決定去掉各種複雜功能,單獨用GLSL顯示一張圖片看看效果。

於是發現了問題所在:

就是用OpenCV讀取圖片的問題。最簡單的就是用OpenCV自帶的函式,一句程式碼即可讀取一張圖片到記憶體。

幾點說明:

  1. 用 imread() 函式讀取圖片,儲存在Mat型別變數裡面;
  2. 用imshow() 函式顯示該圖片的時候顯示正常!!(這裡極具迷惑性!!)
  3. 但是!用OpenGL的glDrawPixels()函式顯示不正常;用GLSL顯示(紋理)不正常。但是不正常的這兩個是一樣的,具體可見下面的對比。
  4. 試過3通道,4通道的影象,結果一樣
  5. 有的jpg影象能正常顯示,有的不能(求大神解釋==)



可以看到:

  1. 結果圖是上下顛倒的(看”1“的尖端)
  2. 結果圖的紅線拼湊到一起就是原圖的”1“,並且結果圖上的幾個”1“並不是重合的,估計正好可以拼成原圖的”1"

==========================================此為分割線===============================================================

於是我換了一種思路,不用OpenCV讀取影象,而是用C語言自帶的檔案讀取,遵循BMP檔案格式,自己讀取BMP影象,程式碼參考如下:

// LoadBitmapFile
// desc: Returns a pointer to the bitmap image of the bitmap specified
//       by filename. Also returns the bitmap header information.
//		 No support for 8-bit bitmaps.
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
	FILE *filePtr;								// the file pointer
	BITMAPFILEHEADER	bitmapFileHeader;		// bitmap file header
	unsigned char		*bitmapImage;			// bitmap image data
	int					imageIdx = 0;			// image index counter
	unsigned char		tempRGB;				// swap variable

	// open filename in "read binary" mode
	filePtr = fopen(filename, "rb");
	if (filePtr == NULL)
		return NULL;

	// read the bitmap file header
	fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);

	// verify that this is a bitmap by checking for the universal bitmap id
	if (bitmapFileHeader.bfType != BITMAP_ID)
	{
		fclose(filePtr);
		return NULL;
	}

	// read the bitmap information header
	fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);

	// move file pointer to beginning of bitmap data
	fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);

	// allocate enough memory for the bitmap image data
	bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);

	// verify memory allocation
	if (!bitmapImage)
	{
		free(bitmapImage);
		fclose(filePtr);
		return NULL;
	}

	// read in the bitmap image data
	fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);

	// make sure bitmap image data was read
	if (bitmapImage == NULL)
	{
		fclose(filePtr);
		return NULL;
	}

	// swap the R and B values to get RGB since the bitmap color format is in BGR
	//for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)  // 不需要!OpenGL 紋理引數 GL_BGR_EXT就可以簡單實現
	//{
	//	tempRGB = bitmapImage[imageIdx];
	//	bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
	//	bitmapImage[imageIdx + 2] = tempRGB;
	//}

	// close the file and return the bitmap image data
	fclose(filePtr);
	return bitmapImage;
}

結果真的正確了!!!真是要感動哭了!!!!雖然我也不知道為啥==

不知道有沒有大神知道:為啥OpenCV讀取的圖片OpenGL來使用會出錯呢?