VC++ MFC OpenCV 显示摄像头 拍照

参考:如何利用MFC及opencv读入摄像头并显示画面

实现一个拍照功能  如图   左边是一个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;//不保存图片
}

 前摄像头镜像显示问题参考

opencv3 图像翻转--cv::flip()详解

注意看评论,我也没测试过不知道行不行

原文地址:https://www.cnblogs.com/ckrgd/p/14110691.html