2011-08-09 219 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,它只是用于测试。