This is the code we showed at Uncraftivism

Dependencies:   mbed

Committer:
jarkman
Date:
Fri Nov 20 14:40:48 2009 +0000
Revision:
0:57f4fdadc97f
Child:
1:70d90598d2e7

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jarkman 0:57f4fdadc97f 1 #include "stdafx.h"
jarkman 0:57f4fdadc97f 2
jarkman 0:57f4fdadc97f 3 #include "mbed.h"
jarkman 0:57f4fdadc97f 4 #include "Frame.h"
jarkman 0:57f4fdadc97f 5 #include "ServoMinder.h"
jarkman 0:57f4fdadc97f 6 #include "MotionFinder.h"
jarkman 0:57f4fdadc97f 7
jarkman 0:57f4fdadc97f 8
jarkman 0:57f4fdadc97f 9 #include "ServoMinder.h"
jarkman 0:57f4fdadc97f 10
jarkman 0:57f4fdadc97f 11
jarkman 0:57f4fdadc97f 12
jarkman 0:57f4fdadc97f 13 extern Logger pcSerial;
jarkman 0:57f4fdadc97f 14
jarkman 0:57f4fdadc97f 15 // Motion detection for the mbed
jarkman 0:57f4fdadc97f 16
jarkman 0:57f4fdadc97f 17
jarkman 0:57f4fdadc97f 18 MotionFinder::MotionFinder( ServoMinder *xServoMinder, ServoMinder *yServoMinder )
jarkman 0:57f4fdadc97f 19 {
jarkman 0:57f4fdadc97f 20 m_backgroundFrame = NULL;
jarkman 0:57f4fdadc97f 21 m_resultFrame = NULL;
jarkman 0:57f4fdadc97f 22 m_attentionX = 0.5;
jarkman 0:57f4fdadc97f 23 m_attentionY = 0.5;
jarkman 0:57f4fdadc97f 24
jarkman 0:57f4fdadc97f 25
jarkman 0:57f4fdadc97f 26
jarkman 0:57f4fdadc97f 27 m_xServoMinder = xServoMinder;
jarkman 0:57f4fdadc97f 28 m_yServoMinder = yServoMinder;
jarkman 0:57f4fdadc97f 29
jarkman 0:57f4fdadc97f 30 m_xServoMinder->moveTo( 1.0 );
jarkman 0:57f4fdadc97f 31 wait( 1 );
jarkman 0:57f4fdadc97f 32 m_xServoMinder->moveTo( 0.0 );
jarkman 0:57f4fdadc97f 33 wait( 1 );
jarkman 0:57f4fdadc97f 34 m_xServoMinder->moveTo( 0.5 );
jarkman 0:57f4fdadc97f 35 wait( 1 );
jarkman 0:57f4fdadc97f 36
jarkman 0:57f4fdadc97f 37 m_yServoMinder->moveTo( 1.0 );
jarkman 0:57f4fdadc97f 38 wait( 1 );
jarkman 0:57f4fdadc97f 39 m_yServoMinder->moveTo( 0.0 );
jarkman 0:57f4fdadc97f 40 wait( 1 );
jarkman 0:57f4fdadc97f 41 m_yServoMinder->moveTo( 0.5 );
jarkman 0:57f4fdadc97f 42 wait( 1 );
jarkman 0:57f4fdadc97f 43 }
jarkman 0:57f4fdadc97f 44
jarkman 0:57f4fdadc97f 45
jarkman 0:57f4fdadc97f 46
jarkman 0:57f4fdadc97f 47 MotionFinder::~MotionFinder()
jarkman 0:57f4fdadc97f 48 {
jarkman 0:57f4fdadc97f 49 if( m_backgroundFrame != NULL )
jarkman 0:57f4fdadc97f 50 Frame::releaseFrame( & m_backgroundFrame );
jarkman 0:57f4fdadc97f 51
jarkman 0:57f4fdadc97f 52 if( m_resultFrame != NULL )
jarkman 0:57f4fdadc97f 53 Frame::releaseFrame( & m_resultFrame );
jarkman 0:57f4fdadc97f 54
jarkman 0:57f4fdadc97f 55 }
jarkman 0:57f4fdadc97f 56
jarkman 0:57f4fdadc97f 57 void MotionFinder::newBackground( Frame *frame )
jarkman 0:57f4fdadc97f 58 {
jarkman 0:57f4fdadc97f 59 Frame::releaseFrame( & m_backgroundFrame );
jarkman 0:57f4fdadc97f 60 return processFrame( frame );
jarkman 0:57f4fdadc97f 61 }
jarkman 0:57f4fdadc97f 62
jarkman 0:57f4fdadc97f 63 void MotionFinder::processFrame( Frame *frame )
jarkman 0:57f4fdadc97f 64 {
jarkman 0:57f4fdadc97f 65 if( frame == NULL || frame->m_bad )
jarkman 0:57f4fdadc97f 66 {
jarkman 0:57f4fdadc97f 67 if( m_resultFrame != NULL )
jarkman 0:57f4fdadc97f 68 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 69 return;
jarkman 0:57f4fdadc97f 70 }
jarkman 0:57f4fdadc97f 71
jarkman 0:57f4fdadc97f 72
jarkman 0:57f4fdadc97f 73 if( m_backgroundFrame == NULL )
jarkman 0:57f4fdadc97f 74 {
jarkman 0:57f4fdadc97f 75 m_backgroundFrame = frame;
jarkman 0:57f4fdadc97f 76
jarkman 0:57f4fdadc97f 77 m_delta = 1 << (m_backgroundFrame->m_bitsPerPixel - 4); // smallest interesting change - make sure this is nonzero for 4-bit iamges!
jarkman 0:57f4fdadc97f 78
jarkman 0:57f4fdadc97f 79 if( m_delta < 2 )
jarkman 0:57f4fdadc97f 80 m_delta = 2;
jarkman 0:57f4fdadc97f 81
jarkman 0:57f4fdadc97f 82 Frame::cloneFrame( &m_resultFrame, m_backgroundFrame );
jarkman 0:57f4fdadc97f 83 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 84 return;
jarkman 0:57f4fdadc97f 85 }
jarkman 0:57f4fdadc97f 86
jarkman 0:57f4fdadc97f 87 if( frame->m_numPixels != m_backgroundFrame->m_numPixels )
jarkman 0:57f4fdadc97f 88 {
jarkman 0:57f4fdadc97f 89 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 90 return;
jarkman 0:57f4fdadc97f 91 }
jarkman 0:57f4fdadc97f 92
jarkman 0:57f4fdadc97f 93
jarkman 0:57f4fdadc97f 94 uint32_t sumX = 0;
jarkman 0:57f4fdadc97f 95 uint32_t sumY = 0;
jarkman 0:57f4fdadc97f 96 uint32_t sumN = 0;
jarkman 0:57f4fdadc97f 97 uint16_t x = 0, y = 0;
jarkman 0:57f4fdadc97f 98
jarkman 0:57f4fdadc97f 99 for( uint32_t i = 0; i < frame->m_numPixels; i += 1 )
jarkman 0:57f4fdadc97f 100 {
jarkman 0:57f4fdadc97f 101 x ++;
jarkman 0:57f4fdadc97f 102 if( x >= frame->m_width )
jarkman 0:57f4fdadc97f 103 {
jarkman 0:57f4fdadc97f 104 y++;
jarkman 0:57f4fdadc97f 105 x = 0;
jarkman 0:57f4fdadc97f 106 }
jarkman 0:57f4fdadc97f 107
jarkman 0:57f4fdadc97f 108 uint16_t pb = m_backgroundFrame->getPixel( i );
jarkman 0:57f4fdadc97f 109 uint16_t pf = frame->getPixel( i );
jarkman 0:57f4fdadc97f 110
jarkman 0:57f4fdadc97f 111 if( ( pf > pb && pf - pb > m_delta ) || ( pf < pb && pb - pf > m_delta ))
jarkman 0:57f4fdadc97f 112 {
jarkman 0:57f4fdadc97f 113 // different from background
jarkman 0:57f4fdadc97f 114 m_resultFrame->setPixel( i, pf );
jarkman 0:57f4fdadc97f 115 sumX += x;
jarkman 0:57f4fdadc97f 116 sumY += y;
jarkman 0:57f4fdadc97f 117 sumN ++;
jarkman 0:57f4fdadc97f 118
jarkman 0:57f4fdadc97f 119 }
jarkman 0:57f4fdadc97f 120 else
jarkman 0:57f4fdadc97f 121 {
jarkman 0:57f4fdadc97f 122 // same-ish as background
jarkman 0:57f4fdadc97f 123 m_resultFrame->setPixel( i, 0 );
jarkman 0:57f4fdadc97f 124
jarkman 0:57f4fdadc97f 125
jarkman 0:57f4fdadc97f 126 }
jarkman 0:57f4fdadc97f 127
jarkman 0:57f4fdadc97f 128 //and make the background a little bit more like this pixel, to adjust to slow changes in lighting
jarkman 0:57f4fdadc97f 129 if( pf > pb )
jarkman 0:57f4fdadc97f 130 m_backgroundFrame->setPixel( i, pb +1 );
jarkman 0:57f4fdadc97f 131
jarkman 0:57f4fdadc97f 132 if( pf < pb )
jarkman 0:57f4fdadc97f 133 m_backgroundFrame->setPixel( i, pb - 1 );
jarkman 0:57f4fdadc97f 134
jarkman 0:57f4fdadc97f 135 }
jarkman 0:57f4fdadc97f 136
jarkman 0:57f4fdadc97f 137 uint32_t cogX = 0;
jarkman 0:57f4fdadc97f 138 uint32_t cogY = 0;
jarkman 0:57f4fdadc97f 139
jarkman 0:57f4fdadc97f 140 if( frame->m_numPixels < 1 )
jarkman 0:57f4fdadc97f 141 frame->m_numPixels = 1;
jarkman 0:57f4fdadc97f 142
jarkman 0:57f4fdadc97f 143 uint32_t percentage = (sumN * 100) / frame->m_numPixels;
jarkman 0:57f4fdadc97f 144
jarkman 0:57f4fdadc97f 145 pcSerial.printf("\r\n%d percent changed pixels\r\n", (int) percentage);
jarkman 0:57f4fdadc97f 146
jarkman 0:57f4fdadc97f 147 if( percentage < 3 ) // no real target, no COG
jarkman 0:57f4fdadc97f 148 {
jarkman 0:57f4fdadc97f 149 pcSerial.printf("No COG\r\n");
jarkman 0:57f4fdadc97f 150
jarkman 0:57f4fdadc97f 151 // could implement some looking-around in this state
jarkman 0:57f4fdadc97f 152
jarkman 0:57f4fdadc97f 153 }
jarkman 0:57f4fdadc97f 154 else if( sumN > 0 )
jarkman 0:57f4fdadc97f 155 {
jarkman 0:57f4fdadc97f 156 cogX = sumX / sumN;
jarkman 0:57f4fdadc97f 157 cogY = sumY / sumN;
jarkman 0:57f4fdadc97f 158
jarkman 0:57f4fdadc97f 159 m_attentionX = ((float)cogX / frame->m_width);
jarkman 0:57f4fdadc97f 160 m_attentionY = ((float)cogY / frame->m_width); // use the larger dimension so x & y get the same scaling
jarkman 0:57f4fdadc97f 161
jarkman 0:57f4fdadc97f 162 pcSerial.printf("COG is %d, %d\r\n", (int) cogX, (int) cogY);
jarkman 0:57f4fdadc97f 163
jarkman 0:57f4fdadc97f 164 }
jarkman 0:57f4fdadc97f 165
jarkman 0:57f4fdadc97f 166 m_xServoMinder->moveTo( 1 - m_attentionX );
jarkman 0:57f4fdadc97f 167 m_yServoMinder->moveTo( 1 - m_attentionY );
jarkman 0:57f4fdadc97f 168
jarkman 0:57f4fdadc97f 169
jarkman 0:57f4fdadc97f 170 Frame::releaseFrame( &frame );
jarkman 0:57f4fdadc97f 171
jarkman 0:57f4fdadc97f 172 m_resultFrame->m_bad = false;
jarkman 0:57f4fdadc97f 173 return;
jarkman 0:57f4fdadc97f 174 }
jarkman 0:57f4fdadc97f 175
jarkman 0:57f4fdadc97f 176
jarkman 0:57f4fdadc97f 177