您的位置:首页 > 运维架构

opencv2 在mfc窗口中显示关于cv::Mat 的解决方法

2014-10-09 16:37 603 查看
opencv2 采用c++代替c,IplImage是原来opencv最常用的数据结构,在opencv2中被cv::Mat取代,opencv2没有直接提供将cv::Mat显示到mfc窗口的接口,需要自己实现。

和原来的IplImage结构不同,cv::Mat 内部的图像数据没有采用行对齐全的方式,即内存上图像每行的内存数据是4的整数倍,所以当图像的列数不是4的倍数是,按IplImage的方式在mfc窗口上显示cv::Mat会没办正确显示。

解决的办法是使数据按4的倍数对齐,我采用的方法是复制,也可以转成IplImage,

<span style="white-space:pre"> </span>//画出指定位置图像
void show(cv::Mat m_img, HDC dc, int x, int y, int w, int h, int from_x, int from_y )
{
//内存中的图像数据拷贝到屏幕上
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset(bmih, 0, sizeof(*bmih));

bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = m_img.cols;
bmih->biHeight = -m_img.rows;
bmih->biPlanes = 1;
bmih->biBitCount = 8 * m_img.channels();
bmih->biCompression = BI_RGB;

if( m_img.channels() == 1 )
{
RGBQUAD* palette = bmi->bmiColors;
int i;
for( i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}

from_x = MIN( MAX( from_x, 0 ), m_img.cols - 1 );
from_y = MIN( MAX( from_y, 0 ), m_img.rows - 1 );

int sw = MAX( MIN( m_img.cols - from_x, w ), 0 );
int sh = MAX( MIN( m_img.rows - from_y, h ), 0 );

if(m_img.cols % 4 != 0 && m_img.isContinuous())
{
int nLineWidth = (sw * m_img.channels() + 3)/4*4; //凑成大于等于nColumn的最小的4的整倍数
BYTE *m_pImageBuffer = new BYTE[sh * nLineWidth];
for(int i = 0; i < sh; i++)
{
memcpy(m_pImageBuffer + i * nLineWidth, m_img.ptr<uchar>(i), m_img.step);
}
SetDIBitsToDevice(
dc,

x,
y,
sw,
sh,

from_x,
from_y,

from_y,
sh,

m_pImageBuffer + from_y * nLineWidth,
bmi,
DIB_RGB_COLORS
);
delete m_pImageBuffer;
}
else
{
SetDIBitsToDevice(
dc,

x,
y,
sw,
sh,

from_x,
from_y,

from_y,
sh,

m_img.data + from_y * m_img.step,

bmi,
DIB_RGB_COLORS
);
}
}IplImage既然是被抛弃,应该尽量少用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cvMat opencv2 mfc
相关文章推荐