I've been messing around over the last few days creating a machine learning model for small thermal imager.
In my code I create the model and then have the model compare against live images. Every 6 minutes the learned model self updates to compensate for the background getting warmer as the day heats up.
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#include <LinearRegression.h>
////
Adafruit_AMG88xx amg;
LinearRegression lr;
////
const int pixels = 64;
float CurrentFrame[pixels] = { 0 };
int sensorDelay = 125;
float dpAtom = 1.0f / 80.0f; // low/high from data sheet
float tsAtom = 1.0f / 64.0f; // 64 data points 64 time stamps.
double valuesModel[2];
double values[2];
////
void setup() {
Serial.begin(115200);
//Serial.println("AMG88xx thermal camera!");
bool status;
// default settings
status = amg.begin();
if (!status) {
Serial.println("Could not find a valid AMG88xx sensor, check wiring!");
while (1);
}
delay(sensorDelay);
BackgroundImage();
} // setup()
//
int count = 0;
float daChange = 0.0f;
float avg = 0.0f;
float stdD = 0.0f; //standard deviation
void loop()
{
lr.reset();
amg.readPixels( CurrentFrame );
for (int i = 0; i < pixels; i++)
{
lr.learn( ((float)i + 1.0f) * tsAtom, (float(CurrentFrame[i]) * dpAtom) );
avg += (float(CurrentFrame[i]));
}
avg /= pixels; // an average of all the readings
// calculate the standard deviation
for (int i = 0; i < pixels; i++) {
stdD += pow(CurrentFrame[i] - avg, 2);
}
stdD = sqrt(stdD / pixels);
stdD *= 10;
/*
// if the current value is more than a standard deviation above the mean,
// then that counts as a peak. also make sure that the current value is
// more than 25 above the mean, in case there is just some noise in a
// pretty flat signal
// if (sensorFiltered[0] - avg > std && sensorFiltered[0] - avg > 50 )
// {
// return true;
// } else {
// return false;
// }
*/
lr.parameters(values);
daChange = 100 * ((valuesModel[1] - values[1]) / valuesModel[1]);
//Serial.print("ValuesModel: ");
//Serial.print(" *X + ");
//Serial.print(valuesModel[1], 6);
//Serial.print(" Values: ");
//Serial.print(" *X + ");
//Serial.print(values[1], 6);
//Serial.print(" %ofChange ");
Serial.print( daChange, 6 );
Serial.print( "," );
Serial.print( stdD );
Serial.println();
delay(sensorDelay);
count++;
//6(150 times 60 seconds) 6 minutes
if ( count == 54000 )
{
BackgroundImage();
}
}
//
void BackgroundImage()
{
// gather a background image
// load model
for (int i = 0; i < 2; i++)
{
lr.reset();
amg.readPixels( CurrentFrame ); // discard several readings
delay(sensorDelay);
}
lr.reset();
amg.readPixels( CurrentFrame );
for (int i = 0; i < pixels; i++)
{
lr.learn( ((float)i + 1.0f) * tsAtom, (CurrentFrame[i] * dpAtom) );
}
//Serial.print("Values: ");
lr.parameters(valuesModel);
//Serial.print(" *X + ");
//Serial.println(valuesModel[1], 6);
}
I am also using standard deviation to see how it stacks up against Liner Regression, not so well.