diff options
Diffstat (limited to 'src/ipa')
-rw-r--r-- | src/ipa/raspberrypi/controller/rpi/awb.cpp | 86 | ||||
-rw-r--r-- | src/ipa/raspberrypi/controller/rpi/awb.hpp | 1 |
2 files changed, 44 insertions, 43 deletions
diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp index 1c65eda8..bb637f10 100644 --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp @@ -175,9 +175,9 @@ void Awb::Initialise() unsigned int Awb::GetConvergenceFrames() const { - // If colour gains have been explicitly set, there is no convergence + // If not in auto mode, there is no convergence // to happen, so no need to drop any frames - return zero. - if (manual_r_ && manual_b_) + if (!isAutoEnabled()) return 0; else return config_.convergence_frames; @@ -193,38 +193,47 @@ void Awb::SetManualGains(double manual_r, double manual_b) // If any of these are 0.0, we swich back to auto. manual_r_ = manual_r; manual_b_ = manual_b; + // If not in auto mode, set these values into the sync_results which + // means that Prepare() will adopt them immediately. + if (!isAutoEnabled()) { + sync_results_.gain_r = prev_sync_results_.gain_r = manual_r_; + sync_results_.gain_g = prev_sync_results_.gain_g = 1.0; + sync_results_.gain_b = prev_sync_results_.gain_b = manual_b_; + } } void Awb::SwitchMode([[maybe_unused]] CameraMode const &camera_mode, Metadata *metadata) { - // If fixed colour gains have been set, we should let other algorithms - // know by writing it into the image metadata. - if (manual_r_ != 0.0 && manual_b_ != 0.0) { - prev_sync_results_.gain_r = manual_r_; - prev_sync_results_.gain_g = 1.0; - prev_sync_results_.gain_b = manual_b_; - // If we're starting up for the first time, try and - // "dead reckon" the corresponding colour temperature. - if (first_switch_mode_ && config_.bayes) { - Pwl ct_r_inverse = config_.ct_r.Inverse(); - Pwl ct_b_inverse = config_.ct_b.Inverse(); - double ct_r = ct_r_inverse.Eval(ct_r_inverse.Domain().Clip(1 / manual_r_)); - double ct_b = ct_b_inverse.Eval(ct_b_inverse.Domain().Clip(1 / manual_b_)); - prev_sync_results_.temperature_K = (ct_r + ct_b) / 2; - } - sync_results_ = prev_sync_results_; + // On the first mode switch we'll have no meaningful colour + // temperature, so try to dead reckon one if in manual mode. + if (!isAutoEnabled() && first_switch_mode_ && config_.bayes) { + Pwl ct_r_inverse = config_.ct_r.Inverse(); + Pwl ct_b_inverse = config_.ct_b.Inverse(); + double ct_r = ct_r_inverse.Eval(ct_r_inverse.Domain().Clip(1 / manual_r_)); + double ct_b = ct_b_inverse.Eval(ct_b_inverse.Domain().Clip(1 / manual_b_)); + prev_sync_results_.temperature_K = (ct_r + ct_b) / 2; + sync_results_.temperature_K = prev_sync_results_.temperature_K; } + // Let other algorithms know the current white balance values. metadata->Set("awb.status", prev_sync_results_); first_switch_mode_ = false; } +bool Awb::isAutoEnabled() const +{ + return manual_r_ == 0.0 || manual_b_ == 0.0; +} + void Awb::fetchAsyncResults() { LOG(RPiAwb, Debug) << "Fetch AWB results"; async_finished_ = false; async_started_ = false; - sync_results_ = async_results_; + // It's possible manual gains could be set even while the async + // thread was running, so only copy the results if still in auto mode. + if (isAutoEnabled()) + sync_results_ = async_results_; } void Awb::restartAsync(StatisticsPtr &stats, double lux) @@ -289,8 +298,10 @@ void Awb::Process(StatisticsPtr &stats, Metadata *image_metadata) if (frame_phase_ < (int)config_.frame_period) frame_phase_++; LOG(RPiAwb, Debug) << "frame_phase " << frame_phase_; - if (frame_phase_ >= (int)config_.frame_period || - frame_count_ < (int)config_.startup_frames) { + // We do not restart the async thread if we're not in auto mode. + if (isAutoEnabled() && + (frame_phase_ >= (int)config_.frame_period || + frame_count_ < (int)config_.startup_frames)) { // Update any settings and any image metadata that we need. struct LuxStatus lux_status = {}; lux_status.lux = 400; // in case no metadata @@ -614,29 +625,18 @@ void Awb::awbGrey() void Awb::doAwb() { - if (manual_r_ != 0.0 && manual_b_ != 0.0) { - async_results_.temperature_K = 4500; // don't know what it is - async_results_.gain_r = manual_r_; - async_results_.gain_g = 1.0; - async_results_.gain_b = manual_b_; + prepareStats(); + LOG(RPiAwb, Debug) << "Valid zones: " << zones_.size(); + if (zones_.size() > config_.min_regions) { + if (config_.bayes) + awbBayes(); + else + awbGrey(); LOG(RPiAwb, Debug) - << "Using manual white balance: gain_r " - << async_results_.gain_r << " gain_b " - << async_results_.gain_b; - } else { - prepareStats(); - LOG(RPiAwb, Debug) << "Valid zones: " << zones_.size(); - if (zones_.size() > config_.min_regions) { - if (config_.bayes) - awbBayes(); - else - awbGrey(); - LOG(RPiAwb, Debug) - << "CT found is " - << async_results_.temperature_K - << " with gains r " << async_results_.gain_r - << " and b " << async_results_.gain_b; - } + << "CT found is " + << async_results_.temperature_K + << " with gains r " << async_results_.gain_r + << " and b " << async_results_.gain_b; } } diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp index f113c642..45ba9e25 100644 --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp @@ -108,6 +108,7 @@ public: }; private: + bool isAutoEnabled() const; // configuration is read-only, and available to both threads AwbConfig config_; std::thread async_thread_; |