This is the code we showed at Uncraftivism

Dependencies:   mbed

Committer:
jarkman
Date:
Thu Dec 10 21:16:57 2009 +0000
Revision:
1:70d90598d2e7
Parent:
0:57f4fdadc97f
Child:
2:01115080f6da

        

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