2005年在南航期间写的,基于VC6,MFC的SDI架构,用的还是OpenCV beta 3.1,菜单功能有:
打开图像,并显示到视图,直方图、均衡化、细化、直线检测等。
打开USB摄像头显示于视图,配置源及格式、光流跟踪、畸变校正等;
运动分析,平滑、锐化、帧差、金字塔分割等。
当年的开发日志:
删除了不相关的图像处理的函数和菜单项, 精简了图像和视频预览,包括视图的成员变量和OnDraw, 注意OnDraw中对闪烁的处理! 20:20 2005-4-8
贴一段代码吧。
void CMyMotionView::OnDraw(CDC* pDC) { CMyMotionDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); /// //防止重叠闪烁 static BOOL bFirstRun=TRUE; if(bFirstRun) { CBrush brushBgColor; brushBgColor.CreateSolidBrush(RGB(0,0,0)); CRect r; GetClientRect (&r); pDC->FillRect(r,&brushBgColor); bFirstRun=FALSE; } // //显示图像 IplImage* img0 = pDoc ->m_image; if (img0 && !m_camera.IsRunning()) { IplImage* ShownImage = NULL; CvSize size = cvGetSize(pDoc->m_image); if(m_camera.IsInitialized()){ m_camera.Uninitialize(); } ShownImage = m_frame.GetImage(); cvSetImageROI(ShownImage, cvRect( 0, 0, size.width,size.height)); int interpolation=CV_INTER_LINEAR; // 插值方法: // CV_INTER_NN - 最近邻差值, // CV_INTER_LINEAR - 双线性差值 (缺省使用) // CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法.. // CV_INTER_CUBIC - 立方差值. cvResize(img0, ShownImage, interpolation ); if (!ShownImage) return; //if(m_bUndistort) // MyUnDistort(ShownImage);//需要跟摄像机对应 CRect rect; pDC->GetClipBox(&rect); pDC->FillSolidRect( rect.left, rect.top, rect.Width(), rect.Height(), RGB(0,0,0)); m_frame.Show(pDC->GetSafeHdc() , 0, 0, size.width, size.height, 0, 0 ); ReleaseDC( pDC ); // //status bar start CMainFrame * pFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd; CStatusBar * pStatus=(CStatusBar *)&pFrame->GetStatusBar(); CString string; string.Format("%dx%d x %dbits x %dchannels", img0->width,img0->height,img0->depth,img0->nChannels); pStatus->SetPaneText( pStatus->CommandToIndex(ID_INDICATOR_FORMAT),string); string.ReleaseBuffer(); } /// //视频预览 else if(m_camera.IsInitialized()) { IplImage* img = m_camera.GetFrame().GetImage(); if( img ) { m_canvas.Create( img->width, img->height, 24 ); IplImage* dst_img = m_canvas.GetImage(); cvCopy( img, dst_img ); // //实时处理开始 //平滑滤波去噪 if(m_bSmooth) MySmooth(dst_img); //金字塔分割 if(m_bPyramid) MyPyramidSegment(dst_img); //阈值分割跟踪 if(m_bThreshold) MyThreshold(dst_img); //轮廓 if(m_bContours)//暂时不在菜单中显示 MyFindContours(dst_img); //帧差计算背景 if(m_bFrameDiff) MyFrameDiff(dst_img); //锐化,有先后顺序 if(m_bSharpen) MySharpen(dst_img); // if(m_bOpticalFlow) //MyOpticalFlow(dst_img);//测试而已 MyMotion(dst_img);//暂时没有效果 // MyKeyFrameSave(dst_img); //>>直方图均衡化 /* IplImage *planes[3]={0,0,0}; for( int i = 0; i < 3; i++ ) planes[i] = cvCreateImage( cvGetSize(dst_img), 8, 1 ); cvCvtPixToPlane(dst_img, planes[0], planes[1], planes[2], 0 ); for( i = 0; i < 3; i++ ) MyEqualizeHist(planes[i],planes[i]); cvCvtPlaneToPix( planes[0], planes[1], planes[2], 0, dst_img ); for( i = 0; i < 3; i++ ) cvReleaseImage(&planes[i]); */ //<<直方图均衡化 //>>畸变校正 if(m_bUndistort) MyUnDistort(dst_img); // //光流法跟踪 if(m_track){ TrackFeatures(); if( m_night_mode ) cvZero( dst_img ); int i, count = m_tracker.GetCount(); const CPointArray& array = m_tracker.GetPoints(); for( i = 0; i < count; i++ ) { CvPoint pt; CvScalar color;//qiansen,new version if( i != m_moved_idx ) { pt = cvPoint( cvRound(array[i].x), cvRound(array[i].y)); color=CV_RGB(0,255,0); } else { pt = cvPoint( cvRound(m_moved_point.x), cvRound(m_moved_point.y)); color=CV_RGB(255,0,0); } cvCircle( dst_img, pt, 3, color, CV_FILLED ); }//for m_track = count > 0; }//if(m_track) //实时处理结束 // HDC dc = ::GetDC( m_hWnd ); CRect rect; GetClientRect( &rect ); m_canvas.DrawToHDC( dc, &rect ); ::ReleaseDC( m_hWnd, dc ); //status bar start CMainFrame * pFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd; CStatusBar * pStatus=(CStatusBar *)&pFrame->GetStatusBar(); static DWORD dwTime=GetTickCount()-100;//避免被零除 DWORD dwNow=GetTickCount(); CString string;//FPS int dFPS=(int)1000/(dwNow-dwTime); dwTime=dwNow; string.Format("%d FPS",dFPS); pStatus->SetPaneText( pStatus->CommandToIndex(ID_INDICATOR_FPS),string); string.Format("%dx%d x %dbits x %dchannels", img->width,img->height,img->depth,img->nChannels); pStatus->SetPaneText( pStatus->CommandToIndex(ID_INDICATOR_FORMAT),string); string.ReleaseBuffer(); }//if( img ) }//else if(m_camera.IsInitialized()) else MyWelcome(pDC); }//OnDraw()