Move the sources to trunk
[opencv] / apps / LkDemo / LkDemoView.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
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.
25 //
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.
28 //
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.
39 //
40 //M*/
41
42 // LkDemoView.cpp : implementation of the CLkDemoView class
43
44 #include "stdafx.h"
45 #include "LkDemo.h"
46 #include <math.h>
47
48 #include "LkDemoDoc.h"
49 #include "LkDemoView.h"
50
51 #ifdef _DEBUG
52 #define new DEBUG_NEW
53 #undef THIS_FILE
54 static char THIS_FILE[] = __FILE__;
55 #endif
56
57 /////////////////////////////////////////////////////////////////////////////
58 // CLkDemoView
59
60 IMPLEMENT_DYNCREATE(CLkDemoView, CView)
61
62 BEGIN_MESSAGE_MAP(CLkDemoView, CView)
63         //{{AFX_MSG_MAP(CLkDemoView)
64         ON_WM_DESTROY()
65         ON_WM_LBUTTONDOWN()
66         ON_WM_RBUTTONDOWN()
67         ON_WM_LBUTTONUP()
68         ON_WM_MOUSEMOVE()
69         ON_WM_ERASEBKGND()
70         //}}AFX_MSG_MAP
71 END_MESSAGE_MAP()
72
73 /////////////////////////////////////////////////////////////////////////////
74 // CLkDemoView construction/destruction
75
76 CLkDemoView::CLkDemoView()
77 {
78     m_canvas.Create( GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 24 );
79     m_track = false;
80     m_night_mode = false;
81     m_moved_idx = -1;
82 }
83
84 CLkDemoView::~CLkDemoView()
85 {
86 }
87
88 BOOL CLkDemoView::PreCreateWindow(CREATESTRUCT& cs)
89 {
90     return CView::PreCreateWindow(cs);
91 }
92
93 /////////////////////////////////////////////////////////////////////////////
94 // CLkDemoView drawing
95
96 void CLkDemoView::OnDraw(CDC* pDC)
97 {
98     CLkDemoDoc* pDoc = GetDocument();
99     ASSERT_VALID(pDoc);
100
101     IplImage* img = m_camera.GetFrame().GetImage();
102     if( img )
103     {
104         HDC dstDC = ::GetDC( m_hWnd );
105         CRect sr, dr;
106         GetClientRect( &dr );
107
108         m_canvas.Create( img->width, img->height, 24 );
109         IplImage* dst_img = m_canvas.GetImage();
110
111         TrackFeatures();
112
113         if( !m_night_mode )
114             cvCopy( img, dst_img );
115         else
116             cvZero( dst_img );
117
118         int i, count = m_tracker.GetCount();
119         const CPointArray& array = m_tracker.GetPoints();
120
121         for( i = 0; i < count; i++ )
122         {
123             CvPoint pt;
124             CvScalar color;
125             if( i != m_moved_idx )
126             {
127                 pt = cvPoint( cvRound(array[i].x), cvRound(array[i].y));
128                 color = CV_RGB(0,255,0);
129             }
130             else
131             {
132                 pt = cvPoint( cvRound(m_moved_point.x),
133                               cvRound(m_moved_point.y));
134                 color = CV_RGB(0,0,255);
135             }
136             cvCircle( dst_img, pt, 3, color, CV_FILLED );
137         }
138         
139         if( m_track )
140             m_track = count > 0;
141
142         m_canvas.DrawToHDC( dstDC, &dr );
143         ::ReleaseDC( m_hWnd, dstDC );
144     }
145     else
146     {
147         CRect r;
148         pDC->GetClipBox(&r);
149         pDC->FillSolidRect( r.left, r.top, r.Width(), r.Height(), RGB(0,0,0));
150     }
151 }
152
153 /////////////////////////////////////////////////////////////////////////////
154 // CLkDemoView message handlers
155
156 void CLkDemoView::OnInitialUpdate() 
157 {
158     CView::OnInitialUpdate();
159
160     if( m_camera.Initialize( 320, 240, -1, m_hWnd ) == 0 )
161     {
162         MessageBox("Can't initialize camera. Try to change format","Error", MB_OK|MB_ICONERROR );
163     }
164     Camera().Start();
165 }
166
167 void CLkDemoView::OnDestroy() 
168 {
169     m_camera.Uninitialize();
170     CView::OnDestroy();
171 }
172
173 void CLkDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
174 {
175     CView::OnLButtonDown(nFlags, point);
176     {
177         point = ConvertScreenToImage(point);
178         int index = FindPoint(point);
179         if( index > 0 )
180         {
181             m_moved_idx = index;
182             m_moved_point = point;
183             CheckUpdate();
184         }
185         else if( m_gray.GetImage() )
186         {
187             m_tracker.AddPoint( point, m_gray );
188         }
189     }
190 }
191
192
193 void CLkDemoView::OnRButtonDown(UINT nFlags, CPoint point) 
194 {
195     CView::OnRButtonDown(nFlags, point);
196     {
197         point = ConvertScreenToImage(point);
198         int index = FindPoint(point);
199         if( index > 0 )
200         {
201             m_tracker.RemovePoint( index );
202             CheckUpdate();
203         }
204     }
205 }
206
207
208 void CLkDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
209 {
210     CView::OnLButtonUp(nFlags, point);
211     {
212         if( m_moved_idx > 0 && m_gray.GetImage() )
213         {
214             m_tracker.MovePoint( m_moved_idx, m_moved_point, m_gray );
215             m_moved_idx = -1;
216             CheckUpdate();
217         }
218     }
219 }
220
221
222 void CLkDemoView::OnMouseMove(UINT nFlags, CPoint point) 
223 {
224     CView::OnMouseMove(nFlags, point);
225     if( nFlags & MK_LBUTTON )
226     {
227         if( m_moved_idx > 0 && m_gray.GetImage() )
228         {
229             m_moved_point = ConvertScreenToImage(point);
230             CheckUpdate();
231         }
232     }
233 }
234
235
236 void CLkDemoView::CheckUpdate()
237 {
238     InvalidateRect( 0, FALSE);
239 }
240
241 BOOL CLkDemoView::OnEraseBkgnd(CDC* pDC) 
242 {
243     return TRUE;
244 }
245
246
247 void  CLkDemoView::StartTracking()
248 {
249     double quality = 0.01;
250     double min_distance = 10;
251     int max_features = 300;
252     if( m_camera.IsInitialized())
253     {
254         m_track = true;
255         m_tracker.Initialize( m_camera.GetFrame(), max_features, quality, min_distance );
256     }
257 }
258
259
260 void  CLkDemoView::StopTracking()
261 {
262     m_track = false;
263 }
264
265
266 void  CLkDemoView::TrackFeatures()
267 {
268     if( m_track && m_camera.IsInitialized() && m_camera.IsRunning() )
269     {
270         CImage& src = m_camera.GetFrame();
271         m_gray.Create( src.Width(), src.Height(), 8 );
272         m_gray.CopyOf( src, 0 );
273         m_tracker.PushFrame( m_gray );
274     }
275 }
276
277
278 int  CLkDemoView::FindPoint( CPoint pt )
279 {
280     int i, count = m_tracker.GetCount();
281     double min_dist = 6;
282     int min_idx = -1;
283     const CPointArray& array = m_tracker.GetPoints();
284
285     for( i = 0; i < count; i++ )
286     {
287         CvPoint2D32f p1 = array[i];
288         double d = fabs(pt.x - p1.x) + fabs(pt.y - p1.y); 
289         if( d < min_dist )
290         {
291             min_dist = d;
292             min_idx = i;
293         }
294     }
295
296     return min_idx;
297 }
298
299
300 CPoint CLkDemoView::ConvertScreenToImage( CPoint point )
301 {
302     CRect rect;
303     GetClientRect( &rect );
304
305     point.x = point.x * m_gray.Width()/MAX(rect.Width(),1);
306     point.y = point.y * m_gray.Height()/MAX(rect.Height(),1);
307
308     return point;
309 }
310
311 /*void CLkDemoView::OnLButtonDblClk(UINT nFlags, CPoint point) 
312 {
313     CView::OnLButtonDblClk(nFlags, point);
314
315     point = ConvertScreenToImage(point);
316     int index = FindPoint( point );
317     if( index >= 0 )
318     {
319         m_tracker.RemovePoint( index );
320     }
321     else if( m_gray.GetImage() )
322     {
323         m_tracker.AddPoint( point, m_gray );
324     }
325     CheckUpdate();
326 }*/