opencv mat和CImage之间的转换

时间:2014-08-26 16:28:23

标签: c++ opencv mfc mat

我正在寻找一种将存储在opencv Mat变量中的图像转换为CImage对象的有效方法(CBitmap也会很好)。有效率我指的是快速和“短拼”。 我的扩展搜索导致找到代码,手动将位图标题和数据写入对象,我想避免,因为我不太明白那里发生了什么。为了使事情变得更糟,它看起来有点不赞成并产生运行时错误...... (我相信我在这里获得了它:http://howto-code-it.blogspot.com/2011/05/how-to-convert-iplimage-to-hbitmap.html

至于现在我只是一个接一个地按下像素,这不太明智(虽然我需要让它工作)并且是时候提高性能了;)

如果有人能以其他方式提出转换,也会受到赞赏。

2 个答案:

答案 0 :(得分:2)

要复制数据,您无需逐个像素地进行复制。一种方法是(及其标题):

CImage* m_pImg;
cv::Size m_sizeShow;
cv::Mat m_matCVImg;
BITMAPINFO bitInfo;
...
StretchDIBits(m_pImg->GetDC(), 0, 0,
    m_sizeShow.width, m_sizeShow.height, 0, 0,
    m_sizeShow.width, m_sizeShow.height,
    matImgTmp.data, &bitInfo, DIB_RGB_COLORS, SRCCOPY);

查看http://kvy.com.ua/transformation-of-opencv-image-to-mfc-image-in-msvc-project/以获取分步说明。

答案 1 :(得分:0)

需要进行一些检查,因为StretchDIBits要求m_matCVImg必须是DWORD对齐且必须是连续的

bool ok1 = m_matCVImg.isContinuous();
bool ok2 = (m_matCVImg.cols % 4) == 0;
  • ok1:如果您的m_matCVImg是ROI或稀疏矩阵,则无法直接使用StretchDIBits
  • ok2:只有当m_matCVImg具有模4列或32位深度时,它才是DWORD对齐的

如果你的检查失败,你需要创建一个带右cols的临时cv :: Mat

 if (!(ok1 && ok2)) {
   // create a new cv::Mat using
   // m_matCVImg.CopyTo(...) or cv::copyMakeBorder(m_matCVImg,...)
 }

最后,如果你的m_matCVImg是灰度级,你必须在bitInfo.bmiColors中准备一个平面调色板;