isp Namespace Reference
|
Space-ng SDK
|
Classes | |
| struct | AutoWhiteBalanceConfig |
Functions | |
| std::optional< msg::WhiteBalanceGains > | estimateWhiteBalance (cv::Mat const &bgr_image, cv::Rect const &roi, AutoWhiteBalanceConfig const &config={}) |
| void | yuvToBgr (void const *data, size_t size, core::msg::BufferInfo const &info, cv::Mat &bgr) |
| void | yuvToBgr (core::IBufferConst const &buffer, cv::Mat &bgr) |
Function Documentation
◆ estimateWhiteBalance()
| std::optional<msg::WhiteBalanceGains> sol3::isp::estimateWhiteBalance | ( | cv::Mat const & | bgr_image, |
| cv::Rect const & | roi, | ||
| AutoWhiteBalanceConfig const & | config = {} |
||
| ) |
Estimate white balance gains from a BGR image, scoped to roi (clipped to the image bounds).
The estimator assumes the gray-world hypothesis: averaged over a "natural" scene under truly white illumination, the mean of every channel is equal. Any inequality is treated as an illuminant color cast (or sensor-response mismatch) and corrected by per-channel scaling. Computed as: r_gain = mean_g / mean_r g_gain = 1.0 b_gain = mean_g / mean_b
Green is pinned at 1 because:
- White balance only constrains channel ratios, so the absolute scale is a free parameter that must be normalized somehow.
- Bayer sensors have twice the green photosites of R/B, making G the lowest-noise channel; using it as the reference avoids amplifying noise.
- BT.601 luminance weights green at ~0.587, so an unmodified G approximately preserves apparent brightness through the WB pass.
- It is the de-facto convention for camera ISPs.
Limitations: the gray-world hypothesis fails on scenes dominated by a single hue (e.g. a green field), which would otherwise produce huge gains on the under-represented channels. The two config knobs guard against this:
config.min_channel_meanrejects ROIs where any channel mean drops below the threshold.config.max_gainclamps R and B to a finite ceiling.
The returned gains satisfy G == 1.0 and 0 <= R, B <= config.max_gain. Returns std::nullopt for an empty image, an empty/out-of-bounds ROI, or insufficient signal in any channel.
◆ yuvToBgr() [1/2]
| void sol3::isp::yuvToBgr | ( | core::IBufferConst const & | buffer, |
| cv::Mat & | bgr | ||
| ) |
Convenience overload that pulls data, size, and info from the buffer.
◆ yuvToBgr() [2/2]
| void sol3::isp::yuvToBgr | ( | void const * | data, |
| size_t | size, | ||
| core::msg::BufferInfo const & | info, | ||
| cv::Mat & | bgr | ||
| ) |
Decode a YUV buffer into bgr, sized to the active image extent (not the padded stride). Format and dimensions come from info; only BufferFormat_YUV_NV12 is currently supported.
bgr is reused across calls. Pass a persistent cv::Mat to avoid the per-call allocation that cv::cvtColor's allocator would otherwise do.
Preconditions (asserted via SOL3_EXPECT):
- info.format() is a supported YUV format
- width and height are non-zero, height is even
- stride_w >= width, stride_h >= height
- size is large enough for the layout
Generated by