#pragma once #include #include #include namespace fgc { // How a camera frame's bytes are laid out. The camera profile decides which one // arrives (PixelFormat in the XML); the program accepts these and refuses others. // // Mono8 one byte per pixel, grey // RGB8 three bytes per pixel, R G B - de-Bayered on the camera // BayerRG8 one byte per pixel, the raw sensor mosaic: // R G R G ... // G B G B ... // BayerRG12p the same mosaic at 12 bits, packed: two pixels in three bytes // (GenICam "12p": p0 = b0 | (b1 & 0x0F) << 8, // p1 = b1 >> 4 | b2 << 4) // // OpenCV names Bayer patterns by the second row, so the camera's BayerRG is // OpenCV's COLOR_BayerBG2* (measured 2026-09-30 against the camera's own RGB8). enum class PixelLayout { Unknown, Mono8, RGB8, BayerRG8, BayerRG12p }; // The GenICam name ("BayerRG12p"), or "Unknown". const char* layoutName(PixelLayout layout); // From a GenICam name; Unknown for anything the program does not handle. PixelLayout layoutFromName(const std::string& name); // True for the raw mosaic layouts, which need de-Bayering before saving as colour. bool layoutIsBayer(PixelLayout layout); // Bits per value as delivered: 8, or 12 for BayerRG12p. 0 for Unknown. int layoutBits(PixelLayout layout); // Bytes one frame of width x height takes in this layout (0 for Unknown). size_t layoutFrameBytes(PixelLayout layout, uint32_t width, uint32_t height); // Unpack `pixels` BayerRG12p values from `in` into one 16-bit word each // (0..4095). `in` holds ceil(pixels * 3 / 2) bytes; an odd last pixel uses the // low half of its pair, as GenICam specifies. void unpack12p(const uint8_t* in, uint16_t* out, size_t pixels); // Brightness of a frame from a sparse sample of its pixels: every `stride`-th // pixel, so all colour sites of a mosaic are visited. Cheap enough to run on // every frame the camera delivers (a few thousand samples). // mean on a 0..255 scale whatever the bit depth (12-bit values / 16) // clipped share of samples at or near white (>= 250 on that scale) struct BrightnessSample { double mean = -1.0; double clipped = -1.0; size_t samples = 0; bool valid() const { return samples > 0; } }; BrightnessSample sampleBrightness(const uint8_t* frame, size_t bytes, PixelLayout layout, uint32_t width, uint32_t height, size_t stride = 997); } // namespace fgc