Richard Sewell
/
ucam
This is the code we showed at Uncraftivism
MotionFinder.cpp@2:01115080f6da, 2009-12-14 (annotated)
- Committer:
- jarkman
- Date:
- Mon Dec 14 08:28:21 2009 +0000
- Revision:
- 2:01115080f6da
- Parent:
- 1:70d90598d2e7
Who changed what in which revision?
User | Revision | Line number | New 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 | 2:01115080f6da | 10 | #include "Blinker.h" |
jarkman | 0:57f4fdadc97f | 11 | |
jarkman | 0:57f4fdadc97f | 12 | |
jarkman | 0:57f4fdadc97f | 13 | |
jarkman | 0:57f4fdadc97f | 14 | extern Logger pcSerial; |
jarkman | 2:01115080f6da | 15 | extern Blinker *blinker; |
jarkman | 0:57f4fdadc97f | 16 | |
jarkman | 0:57f4fdadc97f | 17 | // Motion detection for the mbed |
jarkman | 0:57f4fdadc97f | 18 | |
jarkman | 0:57f4fdadc97f | 19 | |
jarkman | 0:57f4fdadc97f | 20 | MotionFinder::MotionFinder( ServoMinder *xServoMinder, ServoMinder *yServoMinder ) |
jarkman | 0:57f4fdadc97f | 21 | { |
jarkman | 0:57f4fdadc97f | 22 | m_backgroundFrame = NULL; |
jarkman | 0:57f4fdadc97f | 23 | m_resultFrame = NULL; |
jarkman | 0:57f4fdadc97f | 24 | m_attentionX = 0.5; |
jarkman | 0:57f4fdadc97f | 25 | m_attentionY = 0.5; |
jarkman | 0:57f4fdadc97f | 26 | |
jarkman | 0:57f4fdadc97f | 27 | |
jarkman | 0:57f4fdadc97f | 28 | |
jarkman | 0:57f4fdadc97f | 29 | m_xServoMinder = xServoMinder; |
jarkman | 0:57f4fdadc97f | 30 | m_yServoMinder = yServoMinder; |
jarkman | 0:57f4fdadc97f | 31 | |
jarkman | 1:70d90598d2e7 | 32 | |
jarkman | 1:70d90598d2e7 | 33 | |
jarkman | 2:01115080f6da | 34 | /* |
jarkman | 0:57f4fdadc97f | 35 | m_xServoMinder->moveTo( 1.0 ); |
jarkman | 0:57f4fdadc97f | 36 | wait( 1 ); |
jarkman | 0:57f4fdadc97f | 37 | m_xServoMinder->moveTo( 0.0 ); |
jarkman | 0:57f4fdadc97f | 38 | wait( 1 ); |
jarkman | 0:57f4fdadc97f | 39 | m_xServoMinder->moveTo( 0.5 ); |
jarkman | 0:57f4fdadc97f | 40 | wait( 1 ); |
jarkman | 0:57f4fdadc97f | 41 | |
jarkman | 1:70d90598d2e7 | 42 | |
jarkman | 2:01115080f6da | 43 | m_yServoMinder->moveTo( 0.7 ); |
jarkman | 0:57f4fdadc97f | 44 | wait( 1 ); |
jarkman | 0:57f4fdadc97f | 45 | m_yServoMinder->moveTo( 0.0 ); |
jarkman | 2:01115080f6da | 46 | wait( 2 ); |
jarkman | 0:57f4fdadc97f | 47 | m_yServoMinder->moveTo( 0.5 ); |
jarkman | 2:01115080f6da | 48 | wait( 2 ); |
jarkman | 2:01115080f6da | 49 | */ |
jarkman | 0:57f4fdadc97f | 50 | } |
jarkman | 0:57f4fdadc97f | 51 | |
jarkman | 0:57f4fdadc97f | 52 | |
jarkman | 0:57f4fdadc97f | 53 | |
jarkman | 0:57f4fdadc97f | 54 | MotionFinder::~MotionFinder() |
jarkman | 0:57f4fdadc97f | 55 | { |
jarkman | 0:57f4fdadc97f | 56 | if( m_backgroundFrame != NULL ) |
jarkman | 0:57f4fdadc97f | 57 | Frame::releaseFrame( & m_backgroundFrame ); |
jarkman | 0:57f4fdadc97f | 58 | |
jarkman | 0:57f4fdadc97f | 59 | if( m_resultFrame != NULL ) |
jarkman | 0:57f4fdadc97f | 60 | Frame::releaseFrame( & m_resultFrame ); |
jarkman | 0:57f4fdadc97f | 61 | |
jarkman | 0:57f4fdadc97f | 62 | } |
jarkman | 0:57f4fdadc97f | 63 | |
jarkman | 0:57f4fdadc97f | 64 | void MotionFinder::newBackground( Frame *frame ) |
jarkman | 0:57f4fdadc97f | 65 | { |
jarkman | 0:57f4fdadc97f | 66 | Frame::releaseFrame( & m_backgroundFrame ); |
jarkman | 0:57f4fdadc97f | 67 | return processFrame( frame ); |
jarkman | 0:57f4fdadc97f | 68 | } |
jarkman | 0:57f4fdadc97f | 69 | |
jarkman | 0:57f4fdadc97f | 70 | void MotionFinder::processFrame( Frame *frame ) |
jarkman | 0:57f4fdadc97f | 71 | { |
jarkman | 0:57f4fdadc97f | 72 | if( frame == NULL || frame->m_bad ) |
jarkman | 0:57f4fdadc97f | 73 | { |
jarkman | 0:57f4fdadc97f | 74 | if( m_resultFrame != NULL ) |
jarkman | 1:70d90598d2e7 | 75 | m_resultFrame->m_bad = false; |
jarkman | 0:57f4fdadc97f | 76 | return; |
jarkman | 0:57f4fdadc97f | 77 | } |
jarkman | 0:57f4fdadc97f | 78 | |
jarkman | 0:57f4fdadc97f | 79 | |
jarkman | 0:57f4fdadc97f | 80 | if( m_backgroundFrame == NULL ) |
jarkman | 0:57f4fdadc97f | 81 | { |
jarkman | 0:57f4fdadc97f | 82 | m_backgroundFrame = frame; |
jarkman | 0:57f4fdadc97f | 83 | |
jarkman | 0:57f4fdadc97f | 84 | m_delta = 1 << (m_backgroundFrame->m_bitsPerPixel - 4); // smallest interesting change - make sure this is nonzero for 4-bit iamges! |
jarkman | 0:57f4fdadc97f | 85 | |
jarkman | 0:57f4fdadc97f | 86 | if( m_delta < 2 ) |
jarkman | 0:57f4fdadc97f | 87 | m_delta = 2; |
jarkman | 0:57f4fdadc97f | 88 | |
jarkman | 0:57f4fdadc97f | 89 | Frame::cloneFrame( &m_resultFrame, m_backgroundFrame ); |
jarkman | 0:57f4fdadc97f | 90 | m_resultFrame->m_bad = false; |
jarkman | 0:57f4fdadc97f | 91 | return; |
jarkman | 0:57f4fdadc97f | 92 | } |
jarkman | 0:57f4fdadc97f | 93 | |
jarkman | 0:57f4fdadc97f | 94 | if( frame->m_numPixels != m_backgroundFrame->m_numPixels ) |
jarkman | 0:57f4fdadc97f | 95 | { |
jarkman | 0:57f4fdadc97f | 96 | m_resultFrame->m_bad = false; |
jarkman | 0:57f4fdadc97f | 97 | return; |
jarkman | 0:57f4fdadc97f | 98 | } |
jarkman | 0:57f4fdadc97f | 99 | |
jarkman | 0:57f4fdadc97f | 100 | |
jarkman | 0:57f4fdadc97f | 101 | uint32_t sumX = 0; |
jarkman | 0:57f4fdadc97f | 102 | uint32_t sumY = 0; |
jarkman | 0:57f4fdadc97f | 103 | uint32_t sumN = 0; |
jarkman | 0:57f4fdadc97f | 104 | uint16_t x = 0, y = 0; |
jarkman | 0:57f4fdadc97f | 105 | |
jarkman | 0:57f4fdadc97f | 106 | for( uint32_t i = 0; i < frame->m_numPixels; i += 1 ) |
jarkman | 0:57f4fdadc97f | 107 | { |
jarkman | 0:57f4fdadc97f | 108 | x ++; |
jarkman | 0:57f4fdadc97f | 109 | if( x >= frame->m_width ) |
jarkman | 0:57f4fdadc97f | 110 | { |
jarkman | 0:57f4fdadc97f | 111 | y++; |
jarkman | 0:57f4fdadc97f | 112 | x = 0; |
jarkman | 0:57f4fdadc97f | 113 | } |
jarkman | 0:57f4fdadc97f | 114 | |
jarkman | 0:57f4fdadc97f | 115 | uint16_t pb = m_backgroundFrame->getPixel( i ); |
jarkman | 0:57f4fdadc97f | 116 | uint16_t pf = frame->getPixel( i ); |
jarkman | 0:57f4fdadc97f | 117 | |
jarkman | 0:57f4fdadc97f | 118 | if( ( pf > pb && pf - pb > m_delta ) || ( pf < pb && pb - pf > m_delta )) |
jarkman | 0:57f4fdadc97f | 119 | { |
jarkman | 0:57f4fdadc97f | 120 | // different from background |
jarkman | 0:57f4fdadc97f | 121 | m_resultFrame->setPixel( i, pf ); |
jarkman | 0:57f4fdadc97f | 122 | sumX += x; |
jarkman | 0:57f4fdadc97f | 123 | sumY += y; |
jarkman | 0:57f4fdadc97f | 124 | sumN ++; |
jarkman | 0:57f4fdadc97f | 125 | |
jarkman | 0:57f4fdadc97f | 126 | } |
jarkman | 0:57f4fdadc97f | 127 | else |
jarkman | 0:57f4fdadc97f | 128 | { |
jarkman | 0:57f4fdadc97f | 129 | // same-ish as background |
jarkman | 0:57f4fdadc97f | 130 | m_resultFrame->setPixel( i, 0 ); |
jarkman | 0:57f4fdadc97f | 131 | |
jarkman | 0:57f4fdadc97f | 132 | |
jarkman | 0:57f4fdadc97f | 133 | } |
jarkman | 0:57f4fdadc97f | 134 | |
jarkman | 0:57f4fdadc97f | 135 | //and make the background a little bit more like this pixel, to adjust to slow changes in lighting |
jarkman | 0:57f4fdadc97f | 136 | if( pf > pb ) |
jarkman | 0:57f4fdadc97f | 137 | m_backgroundFrame->setPixel( i, pb +1 ); |
jarkman | 0:57f4fdadc97f | 138 | |
jarkman | 0:57f4fdadc97f | 139 | if( pf < pb ) |
jarkman | 0:57f4fdadc97f | 140 | m_backgroundFrame->setPixel( i, pb - 1 ); |
jarkman | 0:57f4fdadc97f | 141 | |
jarkman | 0:57f4fdadc97f | 142 | } |
jarkman | 0:57f4fdadc97f | 143 | |
jarkman | 0:57f4fdadc97f | 144 | uint32_t cogX = 0; |
jarkman | 0:57f4fdadc97f | 145 | uint32_t cogY = 0; |
jarkman | 0:57f4fdadc97f | 146 | |
jarkman | 0:57f4fdadc97f | 147 | if( frame->m_numPixels < 1 ) |
jarkman | 0:57f4fdadc97f | 148 | frame->m_numPixels = 1; |
jarkman | 0:57f4fdadc97f | 149 | |
jarkman | 0:57f4fdadc97f | 150 | uint32_t percentage = (sumN * 100) / frame->m_numPixels; |
jarkman | 0:57f4fdadc97f | 151 | |
jarkman | 0:57f4fdadc97f | 152 | pcSerial.printf("\r\n%d percent changed pixels\r\n", (int) percentage); |
jarkman | 0:57f4fdadc97f | 153 | |
jarkman | 0:57f4fdadc97f | 154 | if( percentage < 3 ) // no real target, no COG |
jarkman | 0:57f4fdadc97f | 155 | { |
jarkman | 0:57f4fdadc97f | 156 | pcSerial.printf("No COG\r\n"); |
jarkman | 2:01115080f6da | 157 | |
jarkman | 2:01115080f6da | 158 | m_xServoMinder->setSpeed( 0.02 ); |
jarkman | 2:01115080f6da | 159 | m_yServoMinder->setSpeed( 0.02 ); |
jarkman | 2:01115080f6da | 160 | |
jarkman | 2:01115080f6da | 161 | blinker->setBoredom( 1 ); |
jarkman | 0:57f4fdadc97f | 162 | |
jarkman | 2:01115080f6da | 163 | m_attentionX = m_attentionX + (((0.5 - m_attentionX))/20); |
jarkman | 2:01115080f6da | 164 | m_attentionY = m_attentionY + (((0.7 - m_attentionY))/20); |
jarkman | 0:57f4fdadc97f | 165 | // could implement some looking-around in this state |
jarkman | 2:01115080f6da | 166 | |
jarkman | 2:01115080f6da | 167 | |
jarkman | 0:57f4fdadc97f | 168 | |
jarkman | 0:57f4fdadc97f | 169 | } |
jarkman | 0:57f4fdadc97f | 170 | else if( sumN > 0 ) |
jarkman | 0:57f4fdadc97f | 171 | { |
jarkman | 2:01115080f6da | 172 | m_xServoMinder->setSpeed( 0.25 ); |
jarkman | 2:01115080f6da | 173 | m_yServoMinder->setSpeed( 0.25 ); |
jarkman | 2:01115080f6da | 174 | |
jarkman | 0:57f4fdadc97f | 175 | cogX = sumX / sumN; |
jarkman | 0:57f4fdadc97f | 176 | cogY = sumY / sumN; |
jarkman | 0:57f4fdadc97f | 177 | |
jarkman | 0:57f4fdadc97f | 178 | m_attentionX = ((float)cogX / frame->m_width); |
jarkman | 0:57f4fdadc97f | 179 | m_attentionY = ((float)cogY / frame->m_width); // use the larger dimension so x & y get the same scaling |
jarkman | 0:57f4fdadc97f | 180 | |
jarkman | 2:01115080f6da | 181 | //blinker->setBoredom( 0 ); |
jarkman | 2:01115080f6da | 182 | float boredom = (2*percentage)/100.0; |
jarkman | 2:01115080f6da | 183 | if(boredom > 1) boredom = 1; |
jarkman | 2:01115080f6da | 184 | blinker->setBoredom( boredom ); |
jarkman | 2:01115080f6da | 185 | |
jarkman | 2:01115080f6da | 186 | |
jarkman | 0:57f4fdadc97f | 187 | pcSerial.printf("COG is %d, %d\r\n", (int) cogX, (int) cogY); |
jarkman | 0:57f4fdadc97f | 188 | |
jarkman | 0:57f4fdadc97f | 189 | } |
jarkman | 0:57f4fdadc97f | 190 | |
jarkman | 0:57f4fdadc97f | 191 | m_xServoMinder->moveTo( 1 - m_attentionX ); |
jarkman | 1:70d90598d2e7 | 192 | m_yServoMinder->moveTo( m_attentionY ); |
jarkman | 0:57f4fdadc97f | 193 | |
jarkman | 0:57f4fdadc97f | 194 | |
jarkman | 0:57f4fdadc97f | 195 | Frame::releaseFrame( &frame ); |
jarkman | 0:57f4fdadc97f | 196 | |
jarkman | 0:57f4fdadc97f | 197 | m_resultFrame->m_bad = false; |
jarkman | 0:57f4fdadc97f | 198 | return; |
jarkman | 0:57f4fdadc97f | 199 | } |
jarkman | 0:57f4fdadc97f | 200 | |
jarkman | 0:57f4fdadc97f | 201 | |
jarkman | 0:57f4fdadc97f | 202 |