使用OpenCV 讀取圖片 ,再用OpenGL顯示,影象有錯位
阿新 • • 發佈:2018-12-30
最近在做Kinect跟蹤的時候需要做視差圖與蒙版的運算。因為圖片很多,所以想利用OpenGL的GLSL來加速。做到最後發現生成的影象不對!自習檢查了程式碼流程,沒發現問題。
單步除錯的時候看到影象變數有資料也沒有追究,浪費N個小時之後,決定去掉各種複雜功能,單獨用GLSL顯示一張圖片看看效果。
於是發現了問題所在:
就是用OpenCV讀取圖片的問題。最簡單的就是用OpenCV自帶的函式,一句程式碼即可讀取一張圖片到記憶體。
幾點說明:
- 用 imread() 函式讀取圖片,儲存在Mat型別變數裡面;
- 用imshow() 函式顯示該圖片的時候顯示正常!!(這裡極具迷惑性!!)
- 但是!用OpenGL的glDrawPixels()函式顯示不正常;用GLSL顯示(紋理)不正常。但是不正常的這兩個是一樣的,具體可見下面的對比。
- 試過3通道,4通道的影象,結果一樣
- 有的jpg影象能正常顯示,有的不能(求大神解釋==)
可以看到:
- 結果圖是上下顛倒的(看”1“的尖端)
- 結果圖的紅線拼湊到一起就是原圖的”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來使用會出錯呢?