首先,我們爲我們的數據空(或unititialized)cv::Mat
讀入直接。這可以在啓動時完成一次,但另一方面cv::Mat::create
並沒有真正花費太多時,圖像已經具有匹配的大小和類型。類型取決於您的需求,通常它是類似於CV_8UC3
的24位彩色圖像。
cv::Mat img(height, width, CV_8UC3);
或
img.create(height, width, CV_8UC3);
那麼你必須考慮cv::Mat
不neccessarily存儲圖像行連續。在每行末尾可能會有一個小的填充值,以使行4字節對齊(或8?)。所以,你需要惹像素存儲模式:
//use fast 4-byte alignment (default anyway) if possible
glPixelStorei(GL_PACK_ALIGNMENT, (img.step & 3) ? 1 : 4);
//set length of one complete row in destination data (doesn't need to equal img.cols)
glPixelStorei(GL_PACK_ROW_LENGTH, img.step/img.elemSize());
接下來,矩陣的類型影響的glReadPixels
的格式和類型參數。如果你需要彩色圖像,你必須牢記OpenCV通常以BGR順序存儲顏色值,所以你需要使用GL_BGR(A)
(這是OpenGL 1.2中添加的)而不是GL_RGB(A)
。對於一個分量圖像,請使用GL_LUMINANCE
(它將各個顏色分量相加)或GL_RED
,GL_GREEN
,...(以獲取單個分量)。所以對於我們的CV_8UC3
圖像的最終調用直接讀入cv::Mat
是:
glReadPixels(0, 0, img.cols, img.rows, GL_BGR, GL_UNSIGNED_BYTE, img.data);
最後,OpenCV的商店圖片來自上下。因此,您可能需要在獲取它們後將它們翻轉或在OpenGL中翻轉它們(這可以通過調整投影矩陣來完成,但在這種情況下請注意三角形的方向)。要翻轉cv::Mat
垂直,您可以使用cv::flip
:
cv::flip(img, flipped, 0);
所以要記住OpenCV的:從上到下
- 將影像存儲,從左至右
- 專賣店在BGR順序彩色圖像
- 可能無法存儲圖像行排列緊密
真的很不錯的答案。我已經在研究翻轉,但我沒有注意到glPixelStorei。謝謝 – 2012-02-01 16:34:22
我不能調用GL_BGR,我不知道爲什麼連接器找不到它,因爲我有最新版本 – 2012-02-01 16:37:10
@Jav_Rock它是在OpenGL 1.2中引入的。因此,如果你的硬件和驅動程序支持它(這很有可能,除非你在20年前買了你的顯卡),你只需要定義這個符號,包括一個合理的新['glext.h'](http:// www.opengl.org/registry/api/glext.h),或者首先使用擴展管理庫(如GLEW),它應該爲自己的頭文件定義常量。無論如何,一旦你想使用高於1.1的任何功能(如PBO,這可能會加快你正常使用時的讀取性能),這將是必要的。 – 2012-02-01 16:39:56