将opencv窗口与mfc窗口绑定之后就可以通过cv::imshow("video",img)显示mat格式的img了
cv::namedWindow("video", CV_WINDOW_NORMAL);//设置窗口名
HWND m_wincv = (HWND)cvGetWindowHandle("video");//获取opencv窗口句柄
HWND hParent1 = ::GetParent(m_wincv);//取窗口的父窗口句柄
//IDC_VIDEO为mfc中picture control的ID号
HWND hw = ::SetParent(m_wincv, GetDlgItem(IDC_VIDEO)->m_hWnd); // 设置新的父窗口句柄
::ShowWindow(hParent1, SW_HIDE); //隐葳原openCV窗口的边框
CRect rect;
GetDlgItem(IDC_VIDEO)->GetClientRect(rect); //获取mfc窗口的大小
//将opencv窗口设置位与mfc窗口大小移植
cv::resizeWindow("video", rect.Width(), rect.Height());
CImage这个类可以实现mfc界面的贴图功能
void MatToCImage(cv::Mat& mat, CImage& cImage) //将mat类型转为CImage
{
//create new CImage
int width = mat.cols;
int height = mat.rows;
int channels = mat.channels();
cImage.Destroy(); //clear
cImage.Create(width, height, 8 * channels); //默认图像像素单通道占用1个字节
//copy values
uchar* ps;
uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer
int step = cImage.GetPitch();
for (int i = 0; i < height; ++i)
{
ps = (mat.ptr<uchar>(i));
for (int j = 0; j < width; ++j)
{
if (channels == 1) //gray
{
*(pimg + i * step + j) = ps[j];
}
else if (channels == 3) //color
{
for (int k = 0; k < 3; ++k)
{
*(pimg + i * step + j * 3 + k) = ps[j * 3 + k];
}
}
}
}
}
//下面这段代码是实现mfc的贴图功能
RECT m_rect;
CImage cimage;
GetDlgItem(IDC_VIDEO)->GetClientRect(&m_rect);
CDC* pdc =GetDlgItem(IDC_VIDEO)->GetDC();
int win_w = m_rect.right - m_rect.left;
int win_h = m_rect.bottom - m_rect.top;
MatToCImage(matImg, cimage); //将mat转CImage
SetStretchBltMode(pdc->m_hDC, STRETCH_HALFTONE); //不执行该语句会导致窗口绘制出的图片有很多噪点,严重失真
cimage.Draw(pdc->m_hDC, 0, 0, win_w, win_h,0,0, matImg.cols, matImg.rows);
ReleaseDC(pdc);
//在mfc窗口绘制矩形框
void DrawRect(CDC* pDC, int x1, int y1, int x2, int y2, int color)
{
// 在鼠标点击窗体的位置、且以该位置为中心绘制一个非填充的红色方框
//CRect rect;
int i = 0;
switch (color)
{
case 0:
{
CPen NewPen(PS_SOLID, 1, RGB(255, 0, 0)); // 定义一个红色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
case 1:
{
CPen NewPen(PS_SOLID, 1, RGB(0, 255, 0)); // 定义一个绿色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
case 2:
{
CPen NewPen(PS_SOLID, 1, RGB(0, 0, 255)); // 定义一个蓝色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
case 3:
{
CPen NewPen(PS_SOLID, 1, RGB(255, 255, 0)); // 定义一个红绿色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
case 4:
{
CPen NewPen(PS_SOLID, 1, RGB(255, 0, 255)); // 定义一个红蓝色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
case 5:
{
CPen NewPen(PS_SOLID, 1, RGB(0, 255, 255)); // 定义一个蓝绿色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
case 6:
{
CPen NewPen(PS_SOLID, 1, RGB(255, 255, 255)); // 定义一个红绿蓝色的画笔
pDC->SelectObject(&NewPen);
pDC->SelectObject(GetStockObject(NULL_BRUSH)); // 选择画刷(空的画刷,不对矩形框进行填充)
pDC->Rectangle(x1, y1, x2, y2);
break;
}
}
}
MFC OpenCV:显示图片的3种方法(详细)