source: trunk/MagicSoft/AMC/activemirrorcontrol/activemirrorcontrol/videoframe.cpp@ 4174

Last change on this file since 4174 was 4174, checked in by merck, 21 years ago
Changes to accomodate Dislpay of Spots ot bigger search window.
File size: 11.3 KB
Line 
1/***************************************************************************
2 videoframe.cpp - description
3 -------------------
4 begin : Fri Nov 22 2002
5 copyright : (C) 2002 by
6 email :
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "amcdefs.h"
19#include "amcframegrabber.h"
20#include "calibratepaneldialog.h"
21#include "linearregression.h"
22#include "threadevent.h"
23#include "videoframe.h"
24#include "videospot.h"
25#include "videospotthread.h"
26#include "videothread.h"
27#include <math.h>
28#include <qframe.h>
29#include <qfile.h>
30#include <qpainter.h>
31#include <qdatetime.h>
32#include <qtextstream.h>
33#include <qtimer.h>
34#include <qimage.h>
35
36#define HEADERSIZE 15
37
38extern int g_iRefX, g_iRefY;
39
40
41VideoFrame::VideoFrame( QWidget *parent, const char *name, AMCFrameGrabber* p_pFG )
42 : QFrame( parent, name )
43{
44
45 qDebug("Thread for VideoFrame PID: %d - PPID: %d", getpid(), getppid() );
46
47 qDebug("Creating Image arrays");
48 m_pImage = new QImage( MY_WIDTH, MY_HEIGHT, MY_DEPTH*8 );
49 m_darkFrame = new QByteArray( BUFSIZE );
50
51 m_iFrame = 0;
52 m_iGoodFrame = 0;
53 m_iDarks = 0;
54 m_iFrameNum = 0;
55
56 m_ix = m_iy = -1;
57 m_iRefX = m_iRefY = -1;
58 m_iCenterX = m_iCenterY = 1;
59 m_pCalibDlg = 0;
60// m_qlSpots.setAutoDelete( true );
61
62 qDebug("Creating VideoThread");
63 m_pVideoThread = new VideoThread( this, p_pFG );
64 m_pVideoThread->init( BUFSIZE );
65 qDebug("Creating SpotThread");
66 m_pSpotThread = new VideoSpotThread( this, m_pImage, (uchar*) m_darkFrame->data() );
67 qDebug("Starting VideoThread");
68 qDebug("Thread for VideoFrame when starting VideoThread PID: %d - PPID: %d", getpid(), getppid() );
69 m_pVideoThread->start();
70}
71
72VideoFrame::~VideoFrame()
73{
74 qDebug("Stoping video thread");
75 m_pVideoThread->stop();
76 m_pVideoThread->wait( );
77 qDebug("deleting video thread");
78 delete m_pVideoThread;
79 qDebug("Stoping spot thread");
80 m_pSpotThread->wait();
81 qDebug("deleting spot thread");
82 delete m_pSpotThread;
83 delete m_darkFrame;
84 delete m_pImage;
85 m_qlSpots.clear();
86}
87
88/** overridden painter for the frame */
89void VideoFrame::drawContents( QPainter* windowPainter )
90{
91// qDebug("In drawContents");
92 // Draw image
93 QRect rect = contentsRect();
94 windowPainter->drawImage( 0,0, *m_pImage );
95
96 // Overlay camera center if it was determined from the LEDs
97 if( m_iCenterX > 1 )
98 {
99 windowPainter->setPen( Qt::white );
100 windowPainter->drawEllipse( m_iCenterX-2, m_iCenterY-2, 5, 5);
101 windowPainter->drawEllipse( m_iCenterX-4, m_iCenterY-4, 9, 9);
102 }
103
104 // Overlay Spots
105 windowPainter->setPen( Qt::red );
106 for( VideoSpot* pActualSpot = m_qlSpots.first();
107 pActualSpot; pActualSpot = m_qlSpots.next() )
108 {
109 if( pActualSpot->isValid() )
110 windowPainter->drawEllipse( pActualSpot->getX()-4, pActualSpot->getY()-4, 9, 9);
111 }
112
113 if( m_pCalibDlg != 0 )
114 {
115 QList<VideoSpot>* pLineList = m_pCalibDlg->getLineList();
116 windowPainter->setPen( Qt::magenta );
117 for( VideoSpot* pActualSpot = pLineList->first();
118 pActualSpot; pActualSpot = pLineList->next() )
119 {
120 if( pActualSpot->isValid() )
121 windowPainter->drawEllipse( pActualSpot->getX()-4, pActualSpot->getY()-4, 9, 9);
122 }
123
124 int iX1, iX2;
125 windowPainter->setPen( Qt::yellow );
126 LinearRegression* pRegression = m_pCalibDlg->getXRegression();
127 if( pRegression->isValid() )
128 {
129 iX1 = (int) (( 0. - pRegression->getAxis()) / pRegression->getSlope());
130 iX2 = (int) (( 479. - pRegression->getAxis()) / pRegression->getSlope());
131 windowPainter->drawLine( iX1, 0, iX2, 479 );
132 }
133
134 pRegression = m_pCalibDlg->getYRegression();
135 if( pRegression->isValid() )
136 {
137 iX1 = (int) (( 0. - pRegression->getAxis() ) / pRegression->getSlope());
138 iX2 = (int) (( 479. - pRegression->getAxis() ) / pRegression->getSlope());
139 windowPainter->drawLine( iX1, 0, iX2, 479 );
140 }
141
142 }
143
144 // Draw a blue cross for the global reference point
145 windowPainter->setPen( Qt::blue );
146 windowPainter->drawLine( g_iRefX-4, g_iRefY, g_iRefX+4, g_iRefY);
147 windowPainter->drawLine( g_iRefX, g_iRefY-4, g_iRefX, g_iRefY+4);
148
149 // Draw a green rectangle showing the reference point for this panel
150 if( m_iRefX > 0)
151 {
152 windowPainter->setPen( Qt::green );
153 if( m_iCenterX > 1 )
154 {
155 // Adapt spot for shift of camera center.
156 int iDx, iDy;
157 iDx = m_iCenterX - CAMERA_X;
158 iDy = m_iCenterY - CAMERA_Y;
159 windowPainter->drawRect( m_iRefX+iDx-4, m_iRefY+iDy-4, 9, 9 );
160 } else
161 windowPainter->drawRect( m_iRefX-4, m_iRefY-4, 9, 9 );
162 }
163
164 // Draw a blue rectangle showing the Region Of Interest (ROI)
165 // which is used to find the spot
166 if( ! m_qrROI.isEmpty() )
167 {
168 windowPainter->setPen( Qt::blue );
169 windowPainter->drawRect( m_qrROI );
170 }
171
172}
173
174/** No descriptions */
175void VideoFrame::saveFrame()
176{
177 QString fileName;
178 fileName.sprintf("Frame%02d.png",m_iFrameNum);
179 m_pImage->save( fileName, "PNG");
180
181 fileName.sprintf("Spots%02d.txt",m_iFrameNum++);
182 QFile file( fileName );
183 if( file.open( IO_WriteOnly ) )
184 {
185 QTextStream stream( &file );
186
187 QString str;
188
189 str.sprintf("LEDs\n" );
190 stream << str;
191 for( VideoSpot* pActualSpot = m_qlLEDs.first();
192 pActualSpot; pActualSpot = m_qlLEDs.next() )
193 {
194 if( pActualSpot->isValid() )
195 {
196 str.sprintf("%d %d\n", pActualSpot->getX(), pActualSpot->getY() );
197 stream << str;
198 }
199 }
200
201 str.sprintf("\nSpots\n" );
202 stream << str;
203 for( VideoSpot* pActualSpot = m_qlSpots.first();
204 pActualSpot; pActualSpot = m_qlSpots.next() )
205 {
206 if( pActualSpot->isValid() )
207 {
208 str.sprintf("%d %d\n", pActualSpot->getX(), pActualSpot->getY() );
209 stream << str;
210 }
211 }
212
213 }
214}
215
216/** Save a dark frame */
217void VideoFrame::takeDark()
218{
219 qDebug("Taking dark frame");
220 uchar* pFrame = m_pImage->bits();
221 m_pVideoThread->getLastFrame( pFrame );
222 uchar* pDark = m_darkFrame->data();
223
224 for(int ind=0; ind< (MY_HEIGHT * MY_WIDTH * MY_DEPTH); ind++, pDark++, pFrame++ )
225 {
226 int help = *pDark;
227 help = (help * m_iDarks) + (int) *pFrame;
228 *pDark = (uchar) (help / (m_iDarks+1));
229 }
230 m_iDarks++;
231}
232
233/** Clear dark frames */
234void VideoFrame::clearDarks()
235{
236 m_darkFrame->fill(0);
237 m_iDarks = 0;
238}
239
240/** No descriptions */
241void VideoFrame::timerDone()
242{
243// qDebug("Frames per second %d %d", m_iFrame, m_iGoodFrame);
244 emit framesGrabbed( m_iFrame );
245 emit framesProcessed( m_iGoodFrame );
246 m_iFrame = 0;
247 m_iGoodFrame=0;
248}
249
250/** No descriptions */
251void VideoFrame::mouseMoveEvent( QMouseEvent* event )
252{
253 if( (event->state() & LeftButton) == 0 )
254 return;
255
256 int x = event->x();
257 int y = event->y();
258 if( x > m_qrROI.left() )
259 m_qrROI.setRight( x );
260 else
261 {
262 if( x == m_qrROI.left() )
263 m_qrROI.setRight( event->x() -1 );
264 else
265 m_qrROI.setLeft( x );
266 }
267 if( y > m_qrROI.top() )
268 m_qrROI.setBottom( y );
269 else
270 {
271 if( y == m_qrROI.bottom() )
272 m_qrROI.setBottom( event->y() -1 );
273 else
274 m_qrROI.setTop( y );
275 }
276 if ( m_qrROI.isValid() );
277 m_pSpotThread->setROI( m_qrROI );
278}
279
280/** No descriptions */
281void VideoFrame::mousePressEvent( QMouseEvent* event )
282{
283 if( event->button() == LeftButton )
284 {
285 m_qrROI.setLeft( event->x() );
286 m_qrROI.setRight( event->x() -1 );
287 m_qrROI.setTop( event->y() );
288 m_qrROI.setBottom( event->y() -1 );
289 m_pSpotThread->setROI( m_qrROI );
290 }
291 if( event->button() == MidButton )
292 {
293 m_qrROI.setLeft( 0 );
294 m_qrROI.setRight( -1 );
295 m_qrROI.setTop( 0 );
296 m_qrROI.setBottom( -1 );
297 m_pSpotThread->setROI( m_qrROI );
298 }
299 if( event->button() == RightButton )
300 {
301 g_iRefX = event->x();
302 g_iRefY = event->y();
303 emit gref( g_iRefX, g_iRefY );
304 }
305}
306
307void VideoFrame::customEvent(QCustomEvent *e)
308{
309 if ( e->type() == THREAD_END_EVENT )
310 {
311 repaint( FALSE );
312 calcCenter();
313 if( m_qlSpots.count() == 1)
314 {
315 VideoSpot* pSpot = m_qlSpots.first();
316 emit spot( pSpot->getX(), pSpot->getY() );
317 }
318 else
319 emit spot( -1, -1 );
320 }
321 if ( e->type() == THREAD_FRAME_EVENT )
322 {
323 m_iFrame++;
324 if( ! m_pSpotThread->running() )
325 {
326 m_iGoodFrame++;
327 m_pVideoThread->getLastFrame( m_pImage->bits() );
328 m_pSpotThread->start();
329 }
330// else
331// qDebug("Dropping Frame");
332 }
333}
334
335/** No descriptions */
336void VideoFrame::threshold( int p_iValue )
337{
338 m_pSpotThread->setSigmas( p_iValue );
339}
340
341/** No descriptions */
342void VideoFrame::scaleValue( int p_iValue )
343{
344 m_pSpotThread->setScalingMax( p_iValue );
345}
346
347void VideoFrame::halt( bool p_zStop )
348{
349 if ( p_zStop == true )
350 {
351 m_pVideoThread->stop();
352 m_pVideoThread->wait(); // Wait for video thread to finish
353 m_pSpotThread->wait(); // Wait for spot thread to finish
354 }
355 else
356 m_pVideoThread->start();
357}
358
359/** Calculate the location of the central pixel. We do this by identifiying the
360 position of the camera LEDs and getting the relative offsets. */
361void VideoFrame::calcCenter()
362{
363 double dX = 0.0, dX1 = 0.0, dX2 = 0.0, dX3 = 0.0, dX4 = 0.0;
364 double dY = 0.0, dY1 = 0.0, dY2 = 0.0, dY3 = 0.0, dY4 = 0.0;
365 int iNumLEDs = 0;
366
367 m_iCenterX = m_iCenterY = 1;
368 m_qlLEDs.clear();
369 m_qlSpots.clear();
370
371 QList<VideoSpot>& qlSpotList = m_pSpotThread->getSpotList();
372 for( VideoSpot* pActualSpot = qlSpotList.first();
373 pActualSpot; pActualSpot = qlSpotList.next() )
374 {
375 // Check if this spot is compatible with the spot of the
376 // upper left LED
377 if ( pActualSpot->contains2( LED1_X, LED1_Y ) )
378 {
379 dX1 = pActualSpot->getX() + (CAMERA_X - LED1_X);
380 dY1 = pActualSpot->getY() + (CAMERA_Y - LED1_Y);
381 dX += dX1; dY += dY1;
382 m_qlLEDs.append( new VideoSpot( pActualSpot->getX(), pActualSpot->getY()) );
383 iNumLEDs++;
384 }
385 // Check if this spot is compatible with the spot of the
386 // upper right LED
387 else if ( pActualSpot->contains2( LED2_X, LED2_Y ) )
388 {
389 dX2 = pActualSpot->getX() + (CAMERA_X - LED2_X);
390 dY2 = pActualSpot->getY() + (CAMERA_Y - LED2_Y);
391 dX += dX2; dY += dY2;
392 m_qlLEDs.append( new VideoSpot( pActualSpot->getX(), pActualSpot->getY()) );
393 iNumLEDs++;
394 }
395 // Check if this spot is compatible with the spot of the
396 // lower left LED
397 else if ( pActualSpot->contains2( LED3_X, LED3_Y ) )
398 {
399 dX3 = pActualSpot->getX() + (CAMERA_X - LED3_X);
400 dY3 = pActualSpot->getY() + (CAMERA_Y - LED3_Y);
401 dX += dX3; dY += dY3;
402 m_qlLEDs.append( new VideoSpot( pActualSpot->getX(), pActualSpot->getY()) );
403 iNumLEDs++;
404 }
405 // Check if this spot is compatible with the spot of the
406 // lower right LED
407 else if ( pActualSpot->contains2( LED4_X, LED4_Y ) )
408 {
409 dX4 = pActualSpot->getX() + (CAMERA_X - LED4_X);
410 dY4 = pActualSpot->getY() + (CAMERA_Y - LED4_Y);
411 dX += dX4; dY += dY4;
412 m_qlLEDs.append( new VideoSpot( pActualSpot->getX(), pActualSpot->getY()) );
413 iNumLEDs++;
414 }
415 else
416 m_qlSpots.append( new VideoSpot( pActualSpot->getX(), pActualSpot->getY()) );
417 }
418 if( iNumLEDs != 0)
419 {
420 m_iCenterX = (int) rint(dX / iNumLEDs);
421 m_iCenterY = (int) rint(dY / iNumLEDs);
422// qDebug("Center %d %d", m_iCenterX, m_iCenterY);
423 }
424 qDebug("Center at: %d %d -- with %d LEDs",m_iCenterX, m_iCenterY, iNumLEDs );
425}
Note: See TracBrowser for help on using the repository browser.