2011-08-09 344 views
0

我似乎無法弄清楚如何做到這一點,我搜索了谷歌並找到了兩個代碼示例,一個來自github屏幕捕獲庫,另一個來自發布組,他們似乎在工作。將HBITMAP轉換爲cv :: Mat

我有一個結構:

struct ClacksScreen 
{ 
    HWND hDesktopWnd; 
    int width, height; 
    RECT wr, cr; 
    HDC hdcClacksScreen; // hardware ClacksScreen 
    HDC hdcMemDC; // ClacksScreen in memory 
    HBITMAP hbmClacksScreen; //hbitmap of the ClacksScreen 
    BITMAP bmpClacksScreen; 
    BITMAPINFOHEADER bi; 
}; 

此更新。我定義了一些函數,包括將位圖寫入磁盤的函數,這工作正常,捕獲屏幕並將一個bmp寫入磁盤,這是我想要的。

現在我想將屏幕上的HBITMAP直接轉換成OpenCV2.1的cv :: Mat。

這是一種作品,除了圖像是純灰色的,它崩潰。很明顯,當我談到C++的時候,我仍然非常努力,所以可能有一些簡單的東西,我只是不想做。

static cv::Mat copyToCVMat(const ClacksScreen * s) 
{ 
    cv::Mat image; 
    image.create(s->bmpClacksScreen.bmWidth, s->bmpClacksScreen.bmHeight, CV_8UC4); 
    GetDIBits(s->hdcMemDC, s->hbmClacksScreen, 0, 
      (UINT)s->bmpClacksScreen.bmHeight, 
      image.data, 
      (BITMAPINFO *)&s->bi, DIB_RGB_COLORS); 
    return image; 
} 

當我包裝一個cv :: imwrite(image);在try catch中,我得到一個錯誤的分配錯誤。很明顯,在這一點上,我們已經確定我沒有任何線索如何做到這一點,所以任何幫助,將不勝感激。

UPDATE

如果我運行此代碼:

try { 
    cv::Mat screen = cv::imread("captureqwsx.jpg"); 
    if (!screen.data) { 
     printf("no image data?"); 
    } 
    cv::imwrite("out.jpg",screen); 
} catch(std::exception e) { 
    printf("Exception %s\n",e.what()); 
} 

我得到的輸出:

沒有圖像數據嗎?異常錯誤的分配

當我試圖運行高級gui時,它和以前一樣,問題出現在寫入磁盤的.jpg和.bmps文件中,這些文件在圖像查看器和MS Paint中都可以看到。

我嘗試了一個完全不同的圖像,一個網站的.png,同樣的問題。

那麼我現在做錯了什麼呢?

回答

1

從OpenCV的文檔

數據 - 指向用戶數據。採用數據 和步驟參數的矩陣構造函數不分配矩陣數據。相反,它們只是 初始化指向指定數據的矩陣標頭,即 未複製任何數據。此操作非常高效,可用於使用OpenCV函數處理外部數據。外部數據不是 自動解除分配,用戶應該照顧它。

我覺得這是一點,使用此構造不會複製要傳遞給構造函數的緩衝,所以你不應該釋放這個數據,直到你不再需要的品種::墊。此外,我對這些東西幾乎一無所知,但爲什麼你將BITMAPINFOHEADER和BITMAPFILEHEADER傳遞給你的cv :: Mat對象,這看起來並不正確。

+0

對不起,當它不工作我都試過了。看到上面的更新,我現在正在使用GetDIBits版本。 此外,在文檔中還有一個構造函數,它接受的數據爲: //構造函數指向用戶分配的數據的矩陣標頭 Mat(Size _size,int _type,void * _data,size_t _step = AUTO_STEP); –

0

我不知道它是什麼,但是當我問一個問題的時候,我不明白找到答案。無論如何,這個問題的一部分,通過回答實際上是解決了這個問題:

OpenCV 2.0 C++ API using imshow: returns unhandled exception and "bad-flag"

在Visual C++:

去項目 - >屬性(或按Alt-F7)配置 屬性 - >連接器 - >輸入 - >附加依賴

由 「 cv210d.lib cxcore210d.lib highgui210d.lib」 代替通常的 「cv210.lib cxcore210.lib highgui210.lib」 - 這是調試 升ibraries。

highgui仍然顯示爲灰色並且不起作用,但是使用上述方法從HBITMAP中讀取現在可行。我並不需要highgui,它只是用於測試。