zoukankan      html  css  js  c++  java
  • 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()详解

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

  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/ckrgd/p/14110691.html
Copyright © 2011-2022 走看看