1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
41 // MainFrm.cpp : implementation of the CMainFrame class
45 #include "cvstreams.h"
47 #include "CamShiftDemo.h"
55 static char THIS_FILE[] = __FILE__;
58 /////////////////////////////////////////////////////////////////////////////
61 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
63 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
64 //{{AFX_MSG_MAP(CMainFrame)
68 ON_COMMAND(ID_CAMERA, OnCamera )
69 ON_COMMAND(ID_BALL, OnBall )
70 ON_COMMAND(ID_FILE, OnFile)
71 ON_COMMAND(ID_PLAYPAUSE, OnPlayPause)
72 ON_UPDATE_COMMAND_UI(ID_CAMERA, OnUpdateCamera )
73 ON_UPDATE_COMMAND_UI(ID_BALL, OnUpdateBall )
74 ON_UPDATE_COMMAND_UI(ID_FILE, OnUpdateFile )
75 ON_UPDATE_COMMAND_UI(ID_PLAYPAUSE, OnUpdatePlayPause)
79 static UINT indicators[] =
81 ID_SEPARATOR, // status line indicator
87 /////////////////////////////////////////////////////////////////////////////
88 // CMainFrame construction/destruction
90 CMainFrame::CMainFrame()
104 m_src_rect = CRect(0,0,0,0);
107 CMainFrame::~CMainFrame()
112 static IPin* get_pin( IBaseFilter* pFilter, PIN_DIRECTION dir )
114 IEnumPins* pEnumPins = 0;
119 pFilter->EnumPins( &pEnumPins );
125 PIN_DIRECTION pinDir = PIN_DIRECTION(-1);
128 pEnumPins->Next( 1, &pPin, &cFetched );
129 if( cFetched == 0 || pPin == 0 ) break;
131 pPin->QueryDirection( &pinDir );
132 if( pinDir == dir ) break;
135 pEnumPins->Release();
142 static void show_prop_page( IBaseFilter* pFilter, const WCHAR* name )
146 ISpecifyPropertyPages* pispp = 0;
147 pFilter->QueryInterface( IID_ISpecifyPropertyPages, (void **)&pispp);
152 if( SUCCEEDED( pispp->GetPages( &caGUID )))
154 OleCreatePropertyFrame(
156 name, // Caption for the dialog box
157 1, // Number of filters
158 (IUnknown**)&pFilter, // Pointer to the filter whose property
163 SafeRelease( pispp );
169 bool CMainFrame::CreateCamShift()
171 CoCreateInstance( CLSID_CamShift, NULL, CLSCTX_INPROC_SERVER,
172 IID_IBaseFilter, (void**)&m_CamShift );
175 m_CamShift->QueryInterface(IID_ICamShift,(void**)&m_CamShiftProp);
178 if( m_CamShiftProp == 0)
180 SafeRelease( m_CamShift );
183 return m_CamShiftProp != 0;
187 bool CMainFrame::CreateCamera( int idx )
189 ICreateDevEnum* pCreateDevEnum = 0;
190 IEnumMoniker* pEnumMon = 0;
193 SafeRelease( m_SourceFilter );
195 CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
196 IID_ICreateDevEnum, (void**)&pCreateDevEnum );
198 /* Create capture device */
202 pCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnumMon, 0);
205 pEnumMon->Skip( idx );
207 if( pEnumMon && SUCCEEDED( pEnumMon->Next(1, &pMon, &cFetched)) && cFetched == 1 )
209 pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_SourceFilter );
212 SafeRelease( pEnumMon );
213 SafeRelease( pCreateDevEnum );
216 return m_SourceFilter != 0;
220 static const GUID CLSID_BouncingBall =
221 {0xFD501041,0x8EBE,0x11CE, {0x81, 0x83, 0x00, 0xAA, 0x00, 0x57, 0x7D, 0xA1 }};
223 /*static const GUID CLSID_AsyncFile =
224 {0xE436EBB5,0x524F,0x11CE,{0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70}};*/
226 static const GUID CLSID_ColorSpaceConverter =
227 {0x1643E180,0x90F5,0x11CE, {0x97, 0xD5, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A }};
229 void CMainFrame::CreateBouncingBall()
231 SafeRelease( m_SourceFilter );
233 CoCreateInstance( CLSID_BouncingBall, NULL, CLSCTX_INPROC_SERVER,
234 IID_IBaseFilter, (void **)&m_SourceFilter );
237 /* Create filter graph */
238 bool CMainFrame::CreateFilterGraph()
242 /* create graph objects */
243 if( m_CamShiftProp != 0 )
245 CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
246 IID_IGraphBuilder, (void **)&m_GraphBuilder );
248 if( m_GraphBuilder != 0 )
250 m_GraphBuilder->QueryInterface(IID_IMediaControl,(void**)&m_MediaControl);
251 m_GraphBuilder->QueryInterface(IID_IMediaEventEx,(void**)&m_MediaEventEx);
252 m_GraphBuilder->QueryInterface(IID_IVideoWindow, (void**)&m_VideoWindow );
253 m_GraphBuilder->QueryInterface(IID_IFilterGraph, (void**)&m_FilterGraph);
257 // Have the graph signal event via window callbacks for performance
258 m_MediaEventEx->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
268 WCHAR wname[1000] = L"";
269 CFileDialog open_dlg( true, 0, 0, OFN_FILEMUSTEXIST, "All files|*.*||", this );
271 if( open_dlg.DoModal() )
273 CString str = open_dlg.GetPathName();
274 if( str.GetLength() > 0 )
276 MultiByteToWideChar( CP_ACP, 0, str, -1, wname, sizeof(wname)/2 );
277 m_FilterGraph->AddFilter( m_CamShift, L"CamShift" );
278 m_GraphBuilder->RenderFile( wname, 0 );
282 else if( m_SourceFilter )
284 hr = m_FilterGraph->AddFilter( m_SourceFilter, L"Video Source" );
287 hr = m_SourceFilter->JoinFilterGraph( m_FilterGraph, L"Video Source" );*/
289 IPin* pSourceOut = get_pin( m_SourceFilter, PINDIR_OUTPUT );
290 IPin* pCamShiftIn = get_pin( m_CamShift, PINDIR_INPUT );
291 IPin* pCamShiftOut = get_pin( m_CamShift, PINDIR_OUTPUT );
294 hr = m_FilterGraph->AddFilter( m_CamShift, L"CamShift" );
297 hr = m_GraphBuilder->Connect( pSourceOut, pCamShiftIn );
300 hr = m_GraphBuilder->Render( pCamShiftOut );
302 SafeRelease( pSourceOut );
303 SafeRelease( pCamShiftIn );
304 SafeRelease( pCamShiftOut );
307 DestroyFilterGraph();
311 return m_FilterGraph != 0 && hr >= 0;
315 void CMainFrame::ClearFilterGraph()
319 IEnumFilters* pEnumFilters = 0;
320 m_FilterGraph->EnumFilters( &pEnumFilters );
324 IBaseFilter* pFilter = 0;
326 while( pEnumFilters->Next( 1, &pFilter, &cFetched ) == S_OK && pFilter != 0 )
328 m_FilterGraph->RemoveFilter( pFilter );
329 SafeRelease( pFilter );
332 SafeRelease( pEnumFilters );
338 // Destroy DirectShow Filter Graph
339 void CMainFrame::DestroyFilterGraph()
344 SafeRelease( m_VideoWindow );
345 SafeRelease( m_FilterGraph );
346 SafeRelease( m_GraphBuilder );
347 SafeRelease( m_MediaControl );
348 SafeRelease( m_MediaEventEx );
349 SafeRelease( m_SourceFilter );
353 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
355 if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
358 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
359 | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
360 !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
362 TRACE0("Failed to create toolbar\n");
363 return -1; // fail to create
366 if (!m_wndStatusBar.Create(this) ||
367 !m_wndStatusBar.SetIndicators(indicators,
368 sizeof(indicators)/sizeof(UINT)))
370 TRACE0("Failed to create status bar\n");
371 return -1; // fail to create
374 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
375 EnableDocking(CBRS_ALIGN_ANY);
376 DockControlBar(&m_wndToolBar);
378 m_wndBar.Create( this, IDD_BAR,CBRS_BOTTOM, IDC_BAR );
382 if( !CreateCamShift())
384 MessageBox("Can't create CamShift filter");
388 // Initialize sliders
389 CSliderCtrl* threshold = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_THRESHOLD);
390 CSliderCtrl* bins = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_BINS);
391 CSliderCtrl* smin = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_SMIN);
392 CSliderCtrl* vmin = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_VMIN);
393 CSliderCtrl* vmax = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_VMAX);
394 CSliderCtrl* wndWidth = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_WIDTH);
395 CSliderCtrl* wndHeight = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_HEIGHT);
397 CvCamShiftParams params;
398 m_CamShiftProp->GetParams( ¶ms );
400 smin->SetRange( 0, 255 );
401 vmin->SetRange( 0, 255 );
402 vmax->SetRange( 0, 255 );
403 threshold->SetRange( 0, 255 );
404 threshold->SetTicFreq( 16 );
405 bins->SetRange( 2, 255 );
406 bins->SetTicFreq( 10 );
408 m_wndBar.WriteParamsToControls( params );
411 wndWidth->SetRange( 10, 100 );
412 wndHeight->SetRange( 10, 100 );
413 wndWidth->SetPos( 100 );
414 wndHeight->SetPos( 100 );
419 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
421 if( !CFrameWnd::PreCreateWindow(cs) )
426 /////////////////////////////////////////////////////////////////////////////
427 // CMainFrame diagnostics
430 void CMainFrame::AssertValid() const
432 CFrameWnd::AssertValid();
435 void CMainFrame::Dump(CDumpContext& dc) const
442 /////////////////////////////////////////////////////////////////////////////
443 // CMainFrame message handlers
446 void CMainFrame::OnDestroy()
448 DestroyFilterGraph();
450 SafeRelease( m_FilterGraph );
451 SafeRelease( m_CamShift );
452 SafeRelease( m_CamShiftProp );
453 SafeRelease( m_SourceFilter );
456 CFrameWnd::OnDestroy();
459 void CMainFrame::StartGraph()
463 CWnd* av = GetActiveView();
465 m_VideoWindow->put_Owner((OAHWND)av->m_hWnd);
466 m_VideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
467 m_VideoWindow->put_MessageDrain((OAHWND)av->m_hWnd);
468 //m_CamShiftProp->StartTracking();
470 SetVideoWindowSize();
471 m_MediaControl->Run();
475 void CMainFrame::StopGraph()
477 if( m_CamShiftProp ) m_CamShiftProp->StopTracking();
480 m_MediaControl->Stop();
481 m_VideoWindow->put_Visible(OAFALSE);
482 m_VideoWindow->put_Owner(NULL);
483 m_VideoWindow->put_MessageDrain(0);
487 void CMainFrame::OnSize(UINT nType, int cx, int cy)
489 CFrameWnd::OnSize(nType, cx, cy);
490 SetVideoWindowSize();
494 CRect CMainFrame::StartTrackerInit()
496 CRect r( 0, 0, 320, 240 );
500 OAFilterState fs = State_Stopped;
501 m_MediaControl->GetState( 0, &fs );
503 if( fs == State_Running )
506 m_MediaControl->Pause();
508 m_MediaControl->Stop();
511 IPin* pCamShiftIn = get_pin( m_CamShift, PINDIR_INPUT );
512 pCamShiftIn->ConnectionMediaType( &am );
516 r.right = ((VIDEOINFOHEADER*)am.pbFormat)->bmiHeader.biWidth;
517 r.bottom = ((VIDEOINFOHEADER*)am.pbFormat)->bmiHeader.biHeight;
518 r.bottom = abs( r.bottom );
525 pCamShiftIn->Release();
534 void CMainFrame::EndTrackerInit( CRect r )
536 if( m_MediaControl && m_CamShiftProp &&
537 !r.IsRectEmpty() && !m_src_rect.IsRectEmpty())
539 CvCamShiftParams params;
540 m_wndBar.ReadParamsFromControls( params );
542 params.x = ((float)r.left)/max(m_src_rect.Width(),1);
543 params.y = ((float)r.top)/max(m_src_rect.Height(),1);
544 params.width = ((float)r.Width())/max(m_src_rect.Width(),1);
545 params.height = ((float)r.Height())/max(m_src_rect.Height(),1);
547 m_CamShiftProp->SetParams( ¶ms );
548 if( !r.IsRectEmpty() )
549 m_CamShiftProp->StartTracking();
551 m_CamShiftProp->StopTracking();
553 m_MediaControl->Run();
557 void CMainFrame::OnCamera()
563 void CMainFrame::OnUpdateCamera(CCmdUI* pCmdUI)
565 pCmdUI->SetCheck( m_input == 0 );
569 void CMainFrame::OnBall()
575 void CMainFrame::OnUpdateBall(CCmdUI* pCmdUI)
577 pCmdUI->SetCheck( m_input == 1 );
580 void CMainFrame::OnFile()
587 void CMainFrame::OnUpdateFile(CCmdUI* pCmdUI)
589 pCmdUI->SetCheck( m_input == 2 );
592 void CMainFrame::ChangeSource()
595 DestroyFilterGraph();
601 case 0: /* camera */ CreateCamera();
603 default: /* ball */ CreateBouncingBall();
607 if( m_SourceFilter == 0 )
614 if( !CreateFilterGraph() && m_input == 0 )
616 for( int i = 1; i <= 10; i++ )
619 if( CreateFilterGraph())
625 show_prop_page( m_SourceFilter, L"Video Source Properties" );
631 void CMainFrame::OnPlayPause()
635 OAFilterState fs = State_Stopped;
636 if( m_MediaControl->GetState( 0, &fs ) == S_OK )
638 if( fs == State_Running )
639 m_MediaControl->Pause();
640 else if( fs == State_Paused )
641 m_MediaControl->Run();
647 void CMainFrame::OnUpdatePlayPause(CCmdUI* pCmdUI)
649 OAFilterState fs = State_Stopped;
652 m_MediaControl->GetState( 0, &fs );
654 pCmdUI->SetCheck( fs == State_Running );
655 pCmdUI->Enable( fs == State_Running || fs == State_Paused );
659 void CMainFrame::GetScaleFactor( int& sx, int &sy )
661 sx = ((CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_WIDTH))->GetPos();
662 sy = ((CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_HEIGHT))->GetPos();
665 CRect CMainFrame::GetVideoWindowSize()
667 CWnd* av = GetActiveView();
672 GetScaleFactor( width, height );
674 av->GetClientRect( &rc );
676 rc.right = rc.right * width / 100;
677 rc.bottom = rc.bottom * height / 100;
684 void CMainFrame::SetVideoWindowSize()
686 CRect rc = GetVideoWindowSize();
689 m_VideoWindow->SetWindowPosition( rc.left, rc.top, rc.right, rc.bottom );
694 /////////////////////////////////////////////////////////////////////////////
698 CBar::CBar() : CDialogBar()
700 //{{AFX_DATA_INIT(CBar)
706 m_ShowPicture = TRUE;
707 m_ShowBackProject = FALSE;
708 m_ShowHistogram = FALSE;
713 void CBar::DoDataExchange(CDataExchange* pDX)
715 CDialogBar::DoDataExchange(pDX);
716 //{{AFX_DATA_MAP(CBar)
717 DDX_Check(pDX, IDC_PICTURE, m_ShowPicture );
718 DDX_Check(pDX, IDC_BACKPROJECT, m_ShowBackProject );
719 DDX_Check(pDX, IDC_HISTOGRAM, m_ShowHistogram );
720 DDX_Slider(pDX, IDC_SMIN, m_Smin);
721 DDX_Slider(pDX, IDC_THRESHOLD, m_Threshold);
722 DDX_Slider(pDX, IDC_VMAX, m_Vmax);
723 DDX_Slider(pDX, IDC_VMIN, m_Vmin);
724 DDX_Slider(pDX, IDC_BINS, m_Bins);
729 BEGIN_MESSAGE_MAP(CBar, CDialogBar)
730 //{{AFX_MSG_MAP(CBar)
732 ON_BN_CLICKED(IDC_PICTURE, OnPicture)
733 ON_BN_CLICKED(IDC_BACKPROJECT, OnBackProject)
734 ON_BN_CLICKED(IDC_HISTOGRAM, OnHistogram)
738 /////////////////////////////////////////////////////////////////////////////
739 // CBar message handlers
741 void CBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
743 int code = pScrollBar->GetDlgCtrlID();
744 CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
755 if( mainframe->m_CamShiftProp )
757 CvCamShiftParams params;
758 mainframe->m_CamShiftProp->GetParams( ¶ms );
759 int bins = params.bins;
760 ReadParamsFromControls( params );
761 mainframe->m_CamShiftProp->SetParams( ¶ms );
762 if( bins != params.bins )
764 mainframe->m_CamShiftProp->StartTracking();
770 mainframe->SetVideoWindowSize();
777 void CBar::OnPicture()
780 CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
781 if( mainframe->m_CamShiftProp )
783 CvCamShiftParams params;
784 mainframe->m_CamShiftProp->GetParams( ¶ms );
786 mainframe->m_CamShiftProp->SetParams( ¶ms );
790 void CBar::OnBackProject()
793 CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
794 if( mainframe->m_CamShiftProp )
796 CvCamShiftParams params;
797 mainframe->m_CamShiftProp->GetParams( ¶ms );
799 mainframe->m_CamShiftProp->SetParams( ¶ms );
803 void CBar::OnHistogram()
806 CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
807 if( mainframe->m_CamShiftProp )
809 CvCamShiftParams params;
810 mainframe->m_CamShiftProp->GetParams( ¶ms );
812 mainframe->m_CamShiftProp->SetParams( ¶ms );
817 CBar::ReadParamsFromControls( CvCamShiftParams& params )
819 CSliderCtrl* threshold = (CSliderCtrl*)GetDlgItem(IDC_THRESHOLD);
820 CSliderCtrl* bins = (CSliderCtrl*)GetDlgItem(IDC_BINS);
821 CSliderCtrl* smin = (CSliderCtrl*)GetDlgItem(IDC_SMIN);
822 CSliderCtrl* vmin = (CSliderCtrl*)GetDlgItem(IDC_VMIN);
823 CSliderCtrl* vmax = (CSliderCtrl*)GetDlgItem(IDC_VMAX);
824 params.view = ((CButton*)GetDlgItem(IDC_PICTURE))->GetCheck() ? 0 :
825 ((CButton*)GetDlgItem(IDC_BACKPROJECT))->GetCheck() ? 1 : 2;
827 params.Smin = smin->GetPos();
828 params.Vmin = vmin->GetPos();
829 params.Vmax = vmax->GetPos();
831 params.threshold = threshold->GetPos();
833 params.bins = bins->GetPos();
837 CBar::WriteParamsToControls( CvCamShiftParams& params )
839 CSliderCtrl* threshold = (CSliderCtrl*)GetDlgItem(IDC_THRESHOLD);
840 CSliderCtrl* bins = (CSliderCtrl*)GetDlgItem(IDC_BINS);
841 CSliderCtrl* smin = (CSliderCtrl*)GetDlgItem(IDC_SMIN);
842 CSliderCtrl* vmin = (CSliderCtrl*)GetDlgItem(IDC_VMIN);
843 CSliderCtrl* vmax = (CSliderCtrl*)GetDlgItem(IDC_VMAX);
845 smin->SetPos( params.Smin );
847 vmin->SetRange( 0, 255 );
848 vmin->SetPos( params.Vmin );
850 vmax->SetRange( 0, 255 );
851 vmax->SetPos( params.Vmax );
853 threshold->SetRange( 0, 255 );
854 threshold->SetPos( params.threshold );
855 threshold->SetTicFreq( 16 );
857 bins->SetRange( 2, 255 );
858 bins->SetPos( params.bins );
859 bins->SetTicFreq( 10 );
861 ((CButton*)GetDlgItem(IDC_PICTURE))->SetCheck( params.view == 0 );
862 ((CButton*)GetDlgItem(IDC_BACKPROJECT))->SetCheck( params.view == 1 );
863 ((CButton*)GetDlgItem(IDC_HISTOGRAM))->SetCheck( params.view == 2 );