#pragma once #include #include namespace fgc { // What a thermal camera reports about one frame besides its pixels. The pixels // themselves are counts (PixelLayout::Mono16): already calibrated apparent // temperature, T[K] = count * kelvin_per_count, with emissivity and path // transmission both taken as 1. The scale depends on the camera's active // calibration profile, so a count means nothing without `cal`. struct ThermalFrameInfo { int cal = 0; // active calibration profile index double kelvin_per_count = 0.01; // K per count under that profile uint16_t valid_count_max = 65280; // above this the camera's LUT wraps int missed_packets = 0; // GigE packets the SDK lost for this frame long long image_num = -1; // the camera's own frame counter }; // The per-frame figures that go into a thermal CamEvent. Temperatures are the // apparent temperature in tenths of a degree Celsius; the hot spot is the // pixel centre, normalised 0..1 across the image as stored. struct ThermalStats { bool valid = false; // false: no pixel in the valid range size_t valid_pixels = 0; uint16_t max_count = 0; uint16_t median_count = 0; int tmax_decic = 0; int tmed_decic = 0; double hotx = 0.0; double hoty = 0.0; }; // Tenths of a degree Celsius for a count, rounded to nearest. int countsToDeciC(uint32_t count, double kelvin_per_count); // Maximum (its first occurrence, row-major), median and hot spot of a // width x height image of counts. Only counts in 1..info.valid_count_max take // part: 0 is what the camera sends before its first real frame, and anything // above the limit has wrapped. ThermalStats thermalStats(const uint16_t* counts, uint32_t width, uint32_t height, const ThermalFrameInfo& info); } // namespace fgc