mymfcDlg.cpp
资源名称:mymfc_v2.rar [点击查看]
上传用户:wjt888999
上传日期:2022-08-11
资源大小:5225k
文件大小:16k
源码类别:
OpenCV
开发平台:
Visual C++
- // mymfcDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "mymfc.h"
- #include "mymfcDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- // CAboutDlg dialog used for App About
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
- // Dialog Data
- enum { IDD = IDD_ABOUTBOX };
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- // Implementation
- protected:
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- END_MESSAGE_MAP()
- // CmymfcDlg dialog
- CmymfcDlg::CmymfcDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CmymfcDlg::IDD, pParent)
- , TheImage(NULL)
- , vPath(_T(""))
- , pCapture(NULL)
- , m_run(0)
- , mCamIndex(0)
- {
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
- void CmymfcDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- DDX_Control(pDX, IDC_CamList, m_camList);
- }
- BEGIN_MESSAGE_MAP(CmymfcDlg, CDialog)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- //}}AFX_MSG_MAP
- ON_BN_CLICKED(IDC_ReadImg, &CmymfcDlg::OnBnClickedReadimg)
- ON_BN_CLICKED(IDC_EdgeDetect, &CmymfcDlg::OnBnClickedEdgedetect)
- ON_BN_CLICKED(IDC_ReadVideo, &CmymfcDlg::OnBnClickedReadvideo)
- ON_BN_CLICKED(IDC_Play, &CmymfcDlg::OnBnClickedPlayVideo)
- ON_CBN_SELCHANGE(IDC_CamList, &CmymfcDlg::OnCbnSelchangeCamlist)
- ON_BN_CLICKED(IDC_Pause, &CmymfcDlg::OnBnClickedPause)
- ON_BN_CLICKED(IDOK, &CmymfcDlg::OnBnClickedOk)
- ON_BN_CLICKED(IDCANCEL, &CmymfcDlg::OnBnClickedCancel)
- ON_BN_CLICKED(IDC_StopCam, &CmymfcDlg::OnBnClickedStopcam)
- ON_BN_CLICKED(IDC_RunCam, &CmymfcDlg::OnBnClickedRuncam)
- END_MESSAGE_MAP()
- // CmymfcDlg message handlers
- BOOL CmymfcDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- // 初始化 创建 TheImage
- CvSize ImgSize;
- ImgSize.height = IMAGE_HEIGHT;
- ImgSize.width = IMAGE_WIDTH;
- TheImage = cvCreateImage( ImgSize, IPL_DEPTH_8U, IMAGE_CHANNELS );
- /*
- // 初始化 BMP 的显示缓存
- bmi = ( BITMAPINFO* )buffer;
- bmih = &( bmi->bmiHeader );
- memset( bmih, 0, sizeof( *bmih ) ); // 把bmih里的内容清零,返回bmih
- bmih->biSize = sizeof( BITMAPINFOHEADER );
- bmih->biWidth = IMAGE_WIDTH;
- bmih->biHeight = -IMAGE_HEIGHT;
- bmih->biPlanes = 1;
- bmih->biCompression = BI_RGB;
- bmih->biBitCount = 8 * TheImage->nChannels;
- palette = bmi->bmiColors;
- if( TheImage->nChannels == 1 )
- {
- for( int i = 0; i < 256; i++ )
- {
- palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
- palette[i].rgbReserved = 0;
- }
- }
- */
- // 初始化视频、摄像头显示循环的执行和中断(m_run)
- m_run = 0;
- // 获取摄像头数目
- int cam_count = CCameraDS::CameraCount();
- // 在组合框CamList中添加摄像头名称的字符串
- for(int i=0; i < cam_count; i++)
- {
- char camera_name[1024];
- int retval = CCameraDS::CameraName(i, camera_name, sizeof(camera_name) );
- char istr[25];
- sprintf_s(istr, " # %d", i);
- //strcat_s( camera_name, istr );
- CString camstr;
- camstr.Format("%s%s",camera_name, istr );
- if(retval >0)
- m_camList.AddString( camstr );
- else
- AfxMessageBox(_T("不能获取摄像头的名称"));
- }
- UpdateData( FALSE );
- // 使边缘检测按钮、视频播放和暂停按钮失效
- GetDlgItem( IDC_EdgeDetect )->EnableWindow( FALSE );
- GetDlgItem( IDC_Play )->EnableWindow( FALSE );
- GetDlgItem( IDC_Pause )->EnableWindow( FALSE );
- GetDlgItem( IDC_RunCam )->EnableWindow( FALSE );
- GetDlgItem( IDC_StopCam )->EnableWindow( FALSE );
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CmymfcDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- void CmymfcDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint(); // 重绘对话框
- CDialog::UpdateWindow(); // 更新windows窗口,如果无这步调用,图片显示还会出现问题
- ShowImage( TheImage, IDC_ShowImg ); // 重绘图片函数
- }
- }
- // The system calls this function to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CmymfcDlg::OnQueryDragIcon()
- {
- return static_cast<HCURSOR>(m_hIcon);
- }
- /*=======================================
- *************图片读取处理****************
- ========================================*/
- void CmymfcDlg::OnBnClickedReadimg()
- {
- // TODO: Add your control notification handler code here
- CFileDialog dlg(
- TRUE, _T("*.bmp"), NULL,
- OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
- _T("image files (*.bmp; *.jpg) |*.bmp; *.jpg; *.jpeg | All Files (*.*) |*.*||"), NULL
- ); // 选项图片的约定
- dlg.m_ofn.lpstrTitle = _T("Open Image"); // 打开文件对话框的标题名
- if( dlg.DoModal() != IDOK ) // 判断是否获得图片
- return;
- CString mPath = dlg.GetPathName(); // 获取图片路径
- IplImage* ipl = cvLoadImage( mPath, 1 ); // 读取图片、缓存到一个局部变量 ipl 中
- if( !ipl ) // 判断是否成功读取图片
- return;
- if( TheImage ) // 对上一幅显示的图片数据清零
- cvZero( TheImage );
- // 使边缘检测按钮生效
- GetDlgItem( IDC_EdgeDetect )->EnableWindow( TRUE );
- ResizeImage( ipl ); // 对读入的图片进行缩放,使其宽或高最大值者刚好等于 256,再复制到 TheImage 中
- ShowImage( TheImage, IDC_ShowImg ); // 调用显示图片函数
- cvReleaseImage( &ipl ); // 释放 ipl 占用的内存
- }
- void CmymfcDlg::OnBnClickedEdgedetect()
- {
- // TODO: Add your control notification handler code here
- IplImage *gray = 0, *edge = 0;
- gray = cvCreateImage( cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 1 );
- edge = cvCreateImage( cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 1 );
- cvCvtColor( TheImage, gray, CV_BGR2GRAY );
- cvCanny( gray, edge, 30, 100, 3 );
- cvCvtColor( edge, TheImage, CV_GRAY2BGR );
- ShowImage( TheImage, IDC_ShowImg ); // 调用显示图片函数
- // 边缘检测只执行一次,完成后则令按钮失效
- GetDlgItem( IDC_EdgeDetect )->EnableWindow( FALSE );
- cvReleaseImage( &gray );
- cvReleaseImage( &edge );
- }
- void CmymfcDlg::ShowImage( IplImage* img, UINT ID ) // ID 是Picture Control控件的ID号
- {
- CDC* pDC = GetDlgItem( ID ) ->GetDC(); // 获得显示控件的 DC
- HDC hDC = pDC ->GetSafeHdc(); // 获取 HDC(设备句柄) 来进行绘图操作
- CRect rect;
- GetDlgItem(ID) ->GetClientRect( &rect );
- int rw = rect.right - rect.left; // 求出图片控件的宽和高
- int rh = rect.bottom - rect.top;
- int iw = img->width; // 读取图片的宽和高
- int ih = img->height;
- int tx = (int)(rw - iw)/2; // 使图片的显示位置正好在控件的正中
- int ty = (int)(rh - ih)/2;
- SetRect( rect, tx, ty, tx+iw, ty+ih );
- CvvImage cimg;
- cimg.CopyOf( img ); // 复制图片
- cimg.DrawToHDC( hDC, &rect ); // 将图片绘制到显示控件的指定区域内
- ReleaseDC( pDC );
- }
- void CmymfcDlg::ResizeImage(IplImage* img)
- {
- // 读取图片的宽和高
- int w = img->width;
- int h = img->height;
- // 找出宽和高中的较大值者
- int max = (w > h)? w: h;
- // 计算将图片缩放到TheImage区域所需的比例因子
- float scale = (float) ( (float) max / 256.0f );
- // 缩放后图片的宽和高
- int nw = (int)( w/scale );
- int nh = (int)( h/scale );
- // 为了将缩放后的图片存入 TheImage 的正中部位,需计算图片在 TheImage 左上角的期望坐标值
- int tlx = (nw > nh)? 0: (int)(256-nw)/2;
- int tly = (nw > nh)? (int)(256-nh)/2: 0;
- // 设置 TheImage 的 ROI 区域,用来存入图片 img
- cvSetImageROI( TheImage, cvRect( tlx, tly, nw, nh) );
- // 对图片 img 进行缩放,并存入到 TheImage 中
- cvResize( img, TheImage );
- // 重置 TheImage 的 ROI 准备读入下一幅图片
- cvResetImageROI( TheImage );
- }
- /*=======================================
- *************本地视频处理****************
- ========================================*/
- void CmymfcDlg::OnBnClickedReadvideo()
- {
- // TODO: Add your control notification handler code here
- CFileDialog dlg(
- TRUE, _T("*.avi"), NULL,
- OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
- _T("*.avi|*.avi|*.rmvb|*.rmvb|*.mp4|*.mp4|*.wmv|*.wmv| All Files (*.*) |*.*||"), NULL
- ); // 选项视频的约定
- dlg.m_ofn.lpstrTitle = _T("Open Video"); // 打开文件对话框的标题名
- if( dlg.DoModal() != IDOK ) // 判断是否获得视频
- return;
- vPath = dlg.GetPathName(); // 获取视频路径
- // 使能视频播放按钮
- GetDlgItem( IDC_Play )->EnableWindow( TRUE );
- GetDlgItem( IDC_Pause )->EnableWindow( TRUE );
- }
- void CmymfcDlg::OnBnClickedPlayVideo()
- {
- // TODO: Add your control notification handler code here
- CvCapture *pCapture = NULL;
- IplImage *pFrame = NULL;
- if( vPath == "" ) //判断文件路径是否为空
- {
- MessageBox("请先选择视频文件!");
- return;
- }
- else
- {
- if(!(pCapture = cvCreateFileCapture( vPath )))
- {
- MessageBox("打开视频文件失败!");
- return;
- }
- }
- // 播放视频时令读入图片和视频、以及播放的按钮失效
- GetDlgItem( IDC_ReadImg )->EnableWindow( FALSE );
- GetDlgItem( IDC_ReadVideo )->EnableWindow( FALSE );
- GetDlgItem( IDC_Play )->EnableWindow( FALSE );
- GetDlgItem( IDC_CamList )->EnableWindow( FALSE );
- GetDlgItem( IDC_RunCam )->EnableWindow( FALSE );
- GetDlgItem( IDC_StopCam )->EnableWindow( FALSE );
- cvNamedWindow("video");
- cvResizeWindow("video",1,1);
- HWND hWnd = (HWND) cvGetWindowHandle("video");
- HWND hParent = ::GetParent(hWnd);
- HWND hwnd1=::FindWindow("CmymfcDlg","mymfc");
- ::SetParent(hWnd, hwnd1);
- ::ShowWindow(hParent, SW_HIDE);
- // 读取视频文件的帧数
- int frames = (int) cvGetCaptureProperty( pCapture, CV_CAP_PROP_FRAME_COUNT );
- int numfrm = 0;
- // 对图像数据清零
- if( TheImage )
- cvZero( TheImage );
- m_run = 1;
- while( (numfrm < frames) & (m_run == 1) )
- {
- pFrame = cvQueryFrame( pCapture );
- IplImage* newframe = cvCloneImage(pFrame);
- ResizeImage( newframe );
- ShowImage( TheImage, IDC_ShowImg );
- if (cvWaitKey(20) == 27) break;
- numfrm++;
- cvReleaseImage( &newframe );
- }
- m_run = 0;
- // 对图像数据清零
- if( TheImage )
- {
- cvZero( TheImage );
- ShowImage( TheImage, IDC_ShowImg );
- }
- // 视频结束后令读入图片和视频按钮生效
- GetDlgItem( IDC_ReadImg )->EnableWindow( TRUE );
- GetDlgItem( IDC_ReadVideo )->EnableWindow( TRUE );
- GetDlgItem( IDC_Play )->EnableWindow( TRUE );
- GetDlgItem( IDC_CamList )->EnableWindow( TRUE );
- cvReleaseCapture(&pCapture);
- cvDestroyWindow("video");
- return;
- }
- void CmymfcDlg::OnBnClickedPause()
- {
- // TODO: Add your control notification handler code here
- m_run = 0;
- return;
- }
- /*=======================================
- 摄像头处理区
- ========================================*/
- void CmymfcDlg::OnCbnSelchangeCamlist()
- {
- // TODO: Add your control notification handler code here
- mCamIndex = m_camList.GetCurSel();
- GetDlgItem( IDC_RunCam )->EnableWindow( TRUE );
- return;
- }
- void CmymfcDlg::OnBnClickedStopcam()
- {
- // TODO: Add your control notification handler code here
- m_run = 0;
- return;
- }
- void CmymfcDlg::OnBnClickedRuncam()
- {
- // TODO: Add your control notification handler code here
- CString camName;
- camName.Format("%s%d","Camera # ", mCamIndex );
- UpdateData( FALSE );
- // 创建1个摄像头实例
- CCameraDS camera;
- //打开第一个摄像头
- //if(! camera.OpenCamera(0, true)) //弹出属性选择窗口
- if( (! camera.OpenCamera(mCamIndex, false, 320,240) ) ) //不弹出属性选择窗口,用代码制定图像宽和高
- {
- AfxMessageBox(_T("Can not open camera.n"));
- return;
- }
- // 读取摄像头数据时令读入图片和视频、播放、暂停的按钮失效
- GetDlgItem( IDC_ReadImg )->EnableWindow( FALSE );
- GetDlgItem( IDC_ReadVideo )->EnableWindow( FALSE );
- GetDlgItem( IDC_Play )->EnableWindow( FALSE );
- GetDlgItem( IDC_Pause )->EnableWindow( FALSE );
- // 使关闭摄像头按钮生效
- GetDlgItem( IDC_StopCam )->EnableWindow( TRUE );
- // 创建一个Ipl图像指针来读取摄像头的帧画面
- IplImage* cFrame;
- // 创建一个视频播放窗口
- cvNamedWindow("camera");
- // 将这个窗口缩至最小
- cvResizeWindow("camera",1,1);
- // 获取窗口句柄
- HWND hWnd = (HWND) cvGetWindowHandle("camera");
- // 获取该窗口的父窗口句柄
- HWND hParent = ::GetParent(hWnd);
- // 获取mymfc的GUI窗口句柄
- HWND hwnd1=::FindWindow("CmymfcDlg","mymfc");
- // 将GUI窗口设置为视频播放窗口的父窗口,使视频在 GUI 的指定区域播放
- ::SetParent(hWnd, hwnd1);
- // 隐藏所创建的视频播放窗口
- ::ShowWindow(hParent, SW_HIDE);
- // 对图像数据清零
- if( TheImage )
- cvZero( TheImage );
- // 初始化在图像中显示字符的字体格式
- CvFont tFont;
- cvInitFont(&tFont, CV_FONT_HERSHEY_COMPLEX, 0.5f,0.7f,0,1,8);
- // 为读取系统时间信息分配内存
- char timestr[26];
- memset(timestr, 0, 26 * sizeof(char));
- m_run = 1;
- while( m_run )
- {
- //获取一帧
- cFrame = camera.QueryFrame();
- IplImage* newframe = cvCloneImage(cFrame);
- // 获取系统时间信息
- __time64_t rawtime;
- struct tm timeinfo ;
- errno_t err;
- // Get time as 64-bit integer
- _time64( &rawtime );
- // Convert to local time
- err = _localtime64_s( &timeinfo, &rawtime );
- // Convert to an ASCII representation
- asctime_s( timestr, 26, &timeinfo );
- CString strTime;
- strTime.Format( "%s", timestr );
- strTime.Replace( "n", "" );
- /*rawtime = time( NULL );
- timeinfo = localtime( &rawtime );
- char* p = asctime( timeinfo );
- // 字符串 p 的第25个字符是换行符 'n',但在图像中将乱码显示
- // 故仅读取 p 的前 24 个字符
- for (int i = 0; i < 24; i++)
- {
- timestr[i] = *p;
- p++;
- }
- p = NULL; */
- // 在图像上显示摄像头序号以及系统时间信息
- cvPutText( newframe, camName, cvPoint(95,15), &tFont, CV_RGB(255,0,0) );
- cvPutText( newframe, strTime, cvPoint(5,225), &tFont, CV_RGB(255,0,0) );
- ResizeImage( newframe );
- ShowImage( TheImage, IDC_ShowImg );
- if (cvWaitKey(20) == 27) break;
- cvReleaseImage( &newframe );
- }
- // 对图像数据清零
- if( TheImage )
- {
- cvZero( TheImage );
- ShowImage( TheImage, IDC_ShowImg );
- }
- camera.CloseCamera();
- cvDestroyWindow("camera");
- // 读取摄像头数据时令读入图片和视频、播放、暂停的按钮失效
- GetDlgItem( IDC_ReadImg )->EnableWindow( TRUE );
- GetDlgItem( IDC_ReadVideo )->EnableWindow( TRUE );
- GetDlgItem( IDC_Play )->EnableWindow( TRUE );
- GetDlgItem( IDC_Pause )->EnableWindow( TRUE );
- return;
- }
- /*=======================================
- *************退出GUI窗口****************
- ========================================*/
- void CmymfcDlg::OnBnClickedOk()
- {
- // TODO: Add your control notification handler code here
- m_run = 0;
- cvDestroyAllWindows();
- OnOK();
- }
- void CmymfcDlg::OnBnClickedCancel()
- {
- // TODO: Add your control notification handler code here
- m_run = 0;
- cvDestroyAllWindows();
- OnCancel();
- }