Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make undistort algorithm configurable #3

Merged
merged 3 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions camera_base.orogen
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ task_context "Preprocess", subclasses: "Base" do
input_port('iframe', ro_ptr('base::samples::frame::Frame'))
output_port 'oframe', ro_ptr('base::samples::frame::Frame')

property("undistort_algorithm","/frame_helper/UndistortAlgorithm",:UNDISTORT_LINEAR).
doc "interpolation algorithm which is used to undistort the frame before it is written to the output port. "
Comment on lines +211 to +212
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking the interpolation isn't the undirstor algorithm, it is a piece of it

Suggested change
property("undistort_algorithm","/frame_helper/UndistortAlgorithm",:UNDISTORT_LINEAR).
doc "interpolation algorithm which is used to undistort the frame before it is written to the output port. "
property("undistort_interpolation","/frame_helper/UndistortAlgorithm",:UNDISTORT_LINEAR).
doc "interpolation used by the undistort algorithm "

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right ... but then undistort_algorithm is what it's called in the frame helper implementation ... Is this worth having to change all of it ? Not sure personally.

"allowed values are INTER_LINEAR, INTER_NEAREST, INTER_AREA, INTER_CUBIC, INTER_LANCZOS4"

property("undistort","bool",false).
doc 'true => undistort the image before it is written to the output port'

Expand Down
42 changes: 23 additions & 19 deletions tasks/Preprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ using namespace camera_base;
using namespace base::samples::frame;

Preprocess::Preprocess(std::string const& name)
: PreprocessBase(name),
oframe(new Frame())
: PreprocessBase(name)
, oframe(new Frame())
{
}

Preprocess::Preprocess(std::string const& name, RTT::ExecutionEngine* engine)
: PreprocessBase(name, engine),
oframe(new Frame())
: PreprocessBase(name, engine)
, oframe(new Frame())
{
}

Expand All @@ -26,38 +26,42 @@ Preprocess::~Preprocess()
// documentation about them.
bool Preprocess::configureHook()
{
if (! PreprocessBase::configureHook())
if (!PreprocessBase::configureHook())
return false;
if(_undistort.value())
if (_undistort.value())
frame_helper.setCalibrationParameter(_calibration_parameters.value());
return true;
}

bool Preprocess::startHook()
{
if (! PreprocessBase::startHook())
if (!PreprocessBase::startHook())
return false;
return true;
}

void Preprocess::updateHook()
{
PreprocessBase::updateHook();
RTT::extras::ReadOnlyPointer<base::samples::frame::Frame> iframe;
if(_iframe.read(iframe) != RTT::NewData)
RTT::extras::ReadOnlyPointer<base::samples::frame::Frame> iframe;
if (_iframe.read(iframe) != RTT::NewData)
return;

Frame *frame_ptr = oframe.write_access();
frame_ptr->init(iframe->size.width*_scale_x-_offset_x,
iframe->size.height*_scale_y-_offset_y,
iframe->getDataDepth(),_format);
try
{
frame_helper.convert(*iframe,*frame_ptr,_offset_x.value(),
_offset_y.value(),_resize_algorithm.value(),_undistort.value());
Frame* frame_ptr = oframe.write_access();
frame_ptr->init(iframe->size.width * _scale_x - _offset_x,
iframe->size.height * _scale_y - _offset_y,
iframe->getDataDepth(),
_format);
try {
frame_helper.convert(*iframe,
*frame_ptr,
_offset_x.value(),
_offset_y.value(),
_resize_algorithm.value(),
_undistort.value(),
_undistort_algorithm.value());
}
catch(std::runtime_error e)
{
catch (std::runtime_error const& e) {
RTT::log(RTT::Error) << "processing error: " << e.what() << RTT::endlog();
if (state() != PROCESSING_ERROR) {
state(PROCESSING_ERROR);
Expand Down
49 changes: 29 additions & 20 deletions tasks/Preprocess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,57 @@

#include "camera_base/PreprocessBase.hpp"
#include "frame_helper/FrameHelper.h"
#include "frame_helper/FrameHelperTypes.h"

namespace camera_base {

/*! \class Preprocess
* \brief The task context provides and requires services. It uses an ExecutionEngine to perform its functions.
* Essential interfaces are operations, data flow ports and properties. These interfaces have been defined using the oroGen specification.
* In order to modify the interfaces you should (re)use oroGen and rely on the associated workflow.
*
/*! \class Preprocess
* \brief The task context provides and requires services. It uses an ExecutionEngine
to perform its functions.
* Essential interfaces are operations, data flow ports and properties. These
interfaces have been defined using the oroGen specification.
* In order to modify the interfaces you should (re)use oroGen and rely on the
associated workflow.
*
* \details
* The name of a TaskContext is primarily defined via:
\verbatim
deployment 'deployment_name'
task('custom_task_name','camera_base::Preprocess')
end
\endverbatim
* It can be dynamically adapted when the deployment is called with a prefix argument.
* It can be dynamically adapted when the deployment is called with a prefix
argument.
*/
class Preprocess : public PreprocessBase
{
friend class PreprocessBase;
class Preprocess : public PreprocessBase {
friend class PreprocessBase;

protected:
RTT::extras::ReadOnlyPointer<base::samples::frame::Frame> oframe;
frame_helper::FrameHelper frame_helper; //helper for image processing
RTT::extras::ReadOnlyPointer<base::samples::frame::Frame> oframe;
frame_helper::FrameHelper frame_helper; // helper for image processing

public:
/** TaskContext constructor for Preprocess
* \param name Name of the task. This name needs to be unique to make it identifiable via nameservices.
* \param initial_state The initial TaskState of the TaskContext. Default is Stopped state.
* \param name Name of the task. This name needs to be unique to make it
* identifiable via nameservices.
* \param initial_state The initial TaskState of
* the TaskContext. Default is Stopped state.
*/
Preprocess(std::string const& name = "camera_base::Preprocess");

/** TaskContext constructor for Preprocess
* \param name Name of the task. This name needs to be unique to make it identifiable for nameservices.
* \param engine The RTT Execution engine to be used for this task, which serialises the execution of all commands, programs, state machines and incoming events for a task.
*
/** TaskContext constructor for Preprocess
* \param name Name of the task. This name needs to be unique to make it
* identifiable for nameservices.
* \param engine The RTT Execution engine to be
* used for this task, which serialises the execution of all commands, programs,
* state machines and incoming events for a task.
*
*/
Preprocess(std::string const& name, RTT::ExecutionEngine* engine);

/** Default deconstructor of Preprocess
*/
~Preprocess();
~Preprocess();

/** This hook is called by Orocos when the state machine transitions
* from PreOperational to Stopped. If it returns false, then the
Expand Down Expand Up @@ -76,7 +86,7 @@ namespace camera_base {
*
* The error(), exception() and fatal() calls, when called in this hook,
* allow to get into the associated RunTimeError, Exception and
* FatalError states.
* FatalError states.
*
* In the first case, updateHook() is still called, and recover() allows
* you to go back into the Running state. In the second case, the
Expand Down Expand Up @@ -108,4 +118,3 @@ namespace camera_base {
}

#endif