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

OpenCV与Windows MFC的图片显示

2017-03-20 10:02 399 查看
问题:

        经常需要为某个算法做一个demo的时候,会经常使用Windows的MFC程序框架进行简单快速的开发,

        也因此经常需要涉及到MFC上Picture Control上实时显示视频源的图片。

代码:

//
// MFC上Picture Control控件显示图像
// src 待显示的图像 (OpenCV库Mat对象结构)
// hwnd MFC显示图像的窗口句柄
//
void ShowImage (Mat& src, HWND hwnd) {
//
HDC hdc = ::GetDC (hwnd);
//
RECT rect;
::GetWindowRect (hwnd, &rect);
//
int dst_width = rect.right - rect.left;
int dst_height = rect.bottom - rect.top;
Mat image = Mat::zeros (dst_height, dst_width, src.type());
//
resize (src, image, Size (dst_width, dst_height));
int depth = image.depth();
int channel = image.channels();
int type = image.type();
CV_8U;
IPL_DEPTH_8U;
int bpp = 8 * image.channels();// 24;//8;//32;//
uchar buffer[sizeof (BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*) buffer;
BITMAPINFOHEADER* bmih = & (bmi->bmiHeader);
memset (bmih, 0, sizeof (*bmih));
bmih->biSize = sizeof (BITMAPINFOHEADER);
bmih->biWidth = image.cols;
bmih->biHeight = -image.rows;
bmih->biPlanes = 1;
bmih->biBitCount = (unsigned short) bpp;
bmih->biCompression = BI_RGB;

if (bpp == 8) {
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;
}
}

//
CvRect dst (rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top);
::StretchDIBits (
hdc,
0, 0, dst.width, dst.height,
0, 0, image.cols, image.rows,
image.data, bmi, DIB_RGB_COLORS, SRCCOPY);
//
::ReleaseDC (hwnd, hdc);
}
// Mylaf


测试及效果:

// 获取显示控件的窗口句柄
HWND hwnd = GetDlgItem (IDC_PIC_LEFT)->GetSafeHwnd();
// 获取显示的图像
Mat img = imread ("D:\\Mylaf\\Project\\VS2013\\XMRK\\testOpenCV320\\ambush_5_left.jpg");
// 调用显示函数
ShowImage (img, hwnd);


扩展:

// header file
// mylaf
struct StDisplayWnd {
HWND hwnd;
HDC  hdc;
RECT rect;
BITMAPINFO* bmi;
cv::Mat image;
};

void initDisplayParam(StDisplayWnd* wnd, HWND hwnd);
//
void Display(StDisplayWnd* wnd, cv::Mat& img);

void releaseDisplay(StDisplayWnd* wnd);


// implement file
// mylaf
void initDisplayParam(StDisplayWnd* wnd, HWND hwnd) {
//
unsigned int buff_size = sizeof(BITMAPINFOHEADER) + 1024;
unsigned char* buff = new unsigned char[buff_size];
//
wnd->hwnd = hwnd;//GetDlgItem(id)->GetSafeHwnd();
wnd->hdc = ::GetDC(wnd->hwnd);
::GetWindowRect(wnd->hwnd, &wnd->rect);
//
int dst_width = wnd->rect.right - wnd->rect.left;
int dst_height = wnd->rect.bottom - wnd->rect.top;
int dst_bpp = 24;// 8 * image.channels();
//
wnd->bmi = (BITMAPINFO*)buff;
BITMAPINFOHEADER* bmih = &(wnd->bmi->bmiHeader);
memset(bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = dst_width;// image.cols;
bmih->biHeight = -dst_height;// -image.rows;
bmih->biPlanes = 1;
bmih->biBitCount = (unsigned short)dst_bpp;
bmih->biCompression = BI_RGB;
//
if (dst_bpp == 8) {
RGBQUAD* palette = wnd->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;
}
}
//
wnd->image = cv::Mat::zeros(dst_height, dst_width, CV_8UC3);
}

void Display(StDisplayWnd* wnd, cv::Mat& img) {
// 图像缩放
resize(img, wnd->image, cv::Size(wnd->image.cols, wnd->image.rows));
//
::StretchDIBits(
wnd->hdc,
0, 0, wnd->bmi->bmiHeader.biWidth, -wnd->bmi->bmiHeader.biHeight,
0, 0, wnd->image.cols, wnd->image.rows,
wnd->image.data, wnd->bmi, DIB_RGB_COLORS, SRCCOPY);
}

void releaseDisplay(StDisplayWnd* wnd) {
::ReleaseDC(wnd->hwnd, wnd->hdc);
unsigned char* buff = (unsigned char*)wnd->bmi;
delete[] buff;
}




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: