实现一个拍照功能 如图 左边是一个picture control控件 右边是2个按钮
如何利用MFC及opencv读入摄像头并显示画面
打开对话框就打开摄像头,在pic控件中显示摄像头的内容,点拍照保存图片后退出,点取消直接退出
显示摄像头内容的方式是得到摄像头的一帧数据,把这个数据当成一张图片显示出来,然后重复这个过程
图片的质量取决于摄像头和得到摄像头数据的处理,当然显示的好也会体验更好,这里只指图片的质量
这个显示摄像头图片的速度就是帧率
#include <opencv2opencv.hpp> BOOL xxxDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 在此添加额外的初始化 cv::namedWindow("view", cv::WINDOW_AUTOSIZE); HWND hWnd = (HWND)cvGetWindowHandle("view"); HWND hParent = ::GetParent(hWnd); ::SetParent(hWnd, GetDlgItem(IDC_STA_TakePhoto)->m_hWnd); ::ShowWindow(hParent, SW_HIDE); CRect picRect; GetDlgItem(IDC_STA_TakePhoto)->GetClientRect(picRect); cv::VideoCapture capture(1);//这里是摄像头个数一个一个试 0 1 2,前置摄像头会有一个镜像显示的问题 if (!capture.isOpened()) { MessageBox(_T("打开摄像头失败")); EndDialog(IDCANCEL);//把这个窗口也关掉 return FALSE; } cv::Mat frame; cv::Mat showFrame; b_isShutter = FALSE;//是拍照 b_takingPhoto = TRUE;//正在拍照 m_strTakePhotoPathName.Empty(); while (TRUE) { capture >> frame;//得到摄像头的一帧数据 resize(frame, showFrame, cv::Size(picRect.Width(), picRect.Height()));//设置这一帧图片的大小是pic控件的大小 imshow("view", showFrame);//显示 cv::waitKey(33);//设置帧率是30帧左右 if (!b_takingPhoto) { if (b_isShutter) { CString strPath, strName, strPathName; strPath = //算一下路径 if (strPath.IsEmpty()) { return FALSE; } strName = _T("\") + m_strPicName + _T(".jpg"); strPathName = strPath + strName; char chPathName[MAX_PATH]; WideCharToMultiByte(CP_ACP, 0, LPCTSTR(strPathName), -1, chPathName, MAX_PATH, NULL, NULL); //保存这一帧图片 BOOL ret; ret = imwrite(chPathName, frame); if (!ret) { MessageBox(_T("照片保存失败")); } else { m_strTakePhotoPathName = strPathName;//图片的路径和名字 } } break; } } frame.release(); showFrame.release(); EndDialog(IDCANCEL);//关闭窗口 return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } void xxxDlg::OnBnClickedBtnShutter() { // TODO: 在此添加控件通知处理程序代码 b_takingPhoto = FALSE;//结束拍照 b_isShutter = TRUE;//保存图片 } void xxxDlg::OnBnClickedBtnTakephotoconcel() { // TODO: 在此添加控件通知处理程序代码 b_takingPhoto = FALSE;//结束拍照 b_isShutter = FALSE;//不保存图片 }
前摄像头镜像显示问题参考
注意看评论,我也没测试过不知道行不行