libcamera/src/ipa/raspberrypi/controller/rpi/sharpen.cpp
Kieran Bingham 27aff949fb libcamera/base: Move extended base functionality
Move the functionality for the following components to the new
base support library:

 - BoundMethod
 - EventDispatcher
 - EventDispatcherPoll
 - Log
 - Message
 - Object
 - Signal
 - Semaphore
 - Thread
 - Timer

While it would be preferable to see these split to move one component
per commit, these components are all interdependent upon each other,
which leaves us with one big change performing the move for all of them.

Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-06-25 16:11:08 +01:00

85 lines
2.5 KiB
C++

/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2019, Raspberry Pi (Trading) Limited
*
* sharpen.cpp - sharpening control algorithm
*/
#include <math.h>
#include <libcamera/base/log.h>
#include "../sharpen_status.h"
#include "sharpen.hpp"
using namespace RPiController;
using namespace libcamera;
LOG_DEFINE_CATEGORY(RPiSharpen)
#define NAME "rpi.sharpen"
Sharpen::Sharpen(Controller *controller)
: SharpenAlgorithm(controller), user_strength_(1.0)
{
}
char const *Sharpen::Name() const
{
return NAME;
}
void Sharpen::SwitchMode(CameraMode const &camera_mode,
[[maybe_unused]] Metadata *metadata)
{
// can't be less than one, right?
mode_factor_ = std::max(1.0, camera_mode.noise_factor);
}
void Sharpen::Read(boost::property_tree::ptree const &params)
{
threshold_ = params.get<double>("threshold", 1.0);
strength_ = params.get<double>("strength", 1.0);
limit_ = params.get<double>("limit", 1.0);
LOG(RPiSharpen, Debug)
<< "Read threshold " << threshold_
<< " strength " << strength_
<< " limit " << limit_;
}
void Sharpen::SetStrength(double strength)
{
// Note that this method is how an application sets the overall
// sharpening "strength". We call this the "user strength" field
// as there already is a strength_ field - being an internal gain
// parameter that gets passed to the ISP control code. Negative
// values are not allowed - coerce them to zero (no sharpening).
user_strength_ = std::max(0.0, strength);
}
void Sharpen::Prepare(Metadata *image_metadata)
{
// The user_strength_ affects the algorithm's internal gain directly, but
// we adjust the limit and threshold less aggressively. Using a sqrt
// function is an arbitrary but gentle way of accomplishing this.
double user_strength_sqrt = sqrt(user_strength_);
struct SharpenStatus status;
// Binned modes seem to need the sharpening toned down with this
// pipeline, thus we use the mode_factor here. Also avoid
// divide-by-zero with the user_strength_sqrt.
status.threshold = threshold_ * mode_factor_ /
std::max(0.01, user_strength_sqrt);
status.strength = strength_ / mode_factor_ * user_strength_;
status.limit = limit_ / mode_factor_ * user_strength_sqrt;
// Finally, report any application-supplied parameters that were used.
status.user_strength = user_strength_;
image_metadata->Set("sharpen.status", status);
}
// Register algorithm with the system.
static Algorithm *Create(Controller *controller)
{
return new Sharpen(controller);
}
static RegisterAlgorithm reg(NAME, &Create);