Skip to content

Commit

Permalink
Added OpenCVGrabber paramparser + test
Browse files Browse the repository at this point in the history
  • Loading branch information
randaz81 committed Aug 30, 2024
1 parent ad79aef commit 049f156
Show file tree
Hide file tree
Showing 10 changed files with 456 additions and 88 deletions.
8 changes: 8 additions & 0 deletions src/devices/opencvGrabber/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ yarp_prepare_plugin(opencv_grabber
CATEGORY device
TYPE OpenCVGrabber
INCLUDE OpenCVGrabber.h
GENERATE_PARSER
EXTRA_CONFIG
WRAPPER=frameGrabber_nws_yarp
DEPENDS "YARP_HAS_OpenCV"
Expand All @@ -18,6 +19,8 @@ if(NOT SKIP_opencv_grabber)
PRIVATE
OpenCVGrabber.cpp
OpenCVGrabber.h
OpenCVGrabber_ParamsParser.cpp
OpenCVGrabber_ParamsParser.h
)

target_link_libraries(yarp_opencv
Expand Down Expand Up @@ -52,6 +55,11 @@ if(NOT SKIP_opencv_grabber)
set(YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ${YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS} PARENT_SCOPE)

set_property(TARGET yarp_opencv PROPERTY FOLDER "Plugins/Device")

if(YARP_COMPILE_TESTS)
add_subdirectory(tests)
endif()

endif()

include(YarpRemoveFile)
Expand Down
96 changes: 34 additions & 62 deletions src/devices/opencvGrabber/OpenCVGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,36 +53,25 @@ YARP_LOG_COMPONENT(OPENCVGRABBER, "yarp.device.opencv_grabber")
}


bool OpenCVGrabber::open(Searchable & config) {
m_saidSize = false;
m_saidResize = false;
m_transpose = false;
m_flip_x = false;
m_flip_y = false;
bool OpenCVGrabber::open(Searchable & config)
{
if (!parseParams(config)) {
return false;
}

// Are we capturing from a file or a camera ?
std::string file = config.check("movie", Value(""),
"if present, read from specified file rather than camera").asString();
fromFile = (file!="");
if (fromFile) {

fromFile = (m_movie != "");
if (fromFile)
{
// Try to open a capture object for the file
m_cap.open(file.c_str());
m_cap.open(m_movie.c_str());
if (!m_cap.isOpened()) {
yCError(OPENCVGRABBER, "Unable to open file '%s' for capture!", file.c_str());
yCError(OPENCVGRABBER, "Unable to open file '%s' for capture!", m_movie.c_str());
return false;
}

// Should we loop?
m_loop = config.check("loop","if present, loop movie");

} else {

m_loop = false;
int camera_idx =
config.check("camera",
Value(cv::VideoCaptureAPIs::CAP_ANY),
"if present, read from camera identified by this index").asInt32();
} else
{
int camera_idx = m_camera;
// Try to open a capture object for the first camera
m_cap.open(camera_idx);
if (!m_cap.isOpened()) {
Expand All @@ -94,42 +83,25 @@ bool OpenCVGrabber::open(Searchable & config) {
yCInfo(OPENCVGRABBER, "Capturing from camera: %d",camera_idx);
}

if ( config.check("framerate","if present, specifies desired camera device framerate") ) {
double m_fps = config.check("framerate", Value(-1)).asFloat64();
m_cap.set(cv::VideoCaptureProperties::CAP_PROP_FPS, m_fps);
if ( m_framerate != -1 ) {
m_cap.set(cv::VideoCaptureProperties::CAP_PROP_FPS, m_framerate);
}
}

if (config.check("flip_x", "if present, flip the image along the x-axis")) {
m_flip_x = true;
}

if (config.check("flip_y", "if present, flip the image along the y-axis")) {
m_flip_y = true;
}

if (config.check("transpose", "if present, rotate the image along of 90 degrees")) {
m_transpose = true;
}

// Extract the desired image size from the configuration if
// present, otherwise query the capture device
if (config.check("width","if present, specifies desired image width")) {
m_w = config.check("width", Value(0)).asInt32();
if (!fromFile && m_w>0) {
m_cap.set(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH, m_w);
}
} else {
m_w = m_cap.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH);
if (!fromFile && m_width > 0) {
m_cap.set(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH, m_width);
}
else {
m_width = m_cap.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH);
}

if (config.check("height","if present, specifies desired image height")) {
m_h = config.check("height", Value(0)).asInt32();
if (!fromFile && m_h>0) {
m_cap.set(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT, m_h);
}
} else {
m_h = m_cap.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT);
if (!fromFile && m_height> 0) {
m_cap.set(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT, m_height);
}
else {
m_height = m_cap.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT);
}

// Ignore capture properties - they are unreliable
Expand Down Expand Up @@ -179,8 +151,8 @@ bool OpenCVGrabber::getImage(ImageOf<PixelRgb> & image) {
}

// Callers may have not initialized the image dimensions (may happen if this device is not wrapped)
if (static_cast<int>(image.width()) != m_w || static_cast<int>(image.height()) != m_h) {
image.resize(m_w, m_h);
if (static_cast<int>(image.width()) != m_width || static_cast<int>(image.height()) != m_height) {
image.resize(m_width, m_height);
}

// Grab and retrieve a frame,
Expand Down Expand Up @@ -230,22 +202,22 @@ bool OpenCVGrabber::getImage(ImageOf<PixelRgb> & image) {
// create the timestamp
m_laststamp.update();

if (m_w == 0) {
m_w = frame.cols;
if (m_width == 0) {
m_width = frame.cols;
}

if (m_h == 0) {
m_h = frame.rows;
if (m_height == 0) {
m_height = frame.rows;
}

if (fromFile && (frame.cols != (!m_transpose ? m_w : m_h) || frame.rows != (!m_transpose ? m_h : m_w))) {
if (fromFile && (frame.cols != (!m_transpose ? m_width : m_height) || frame.rows != (!m_transpose ? m_height : m_width))) {
if (!m_saidResize) {
yCDebug(OPENCVGRABBER, "Software scaling from %dx%d to %dx%d", frame.cols, frame.rows, m_w, m_h);
yCDebug(OPENCVGRABBER, "Software scaling from %dx%d to %dx%d", frame.cols, frame.rows, m_width, m_height);
m_saidResize = true;
}

cv::Mat resized;
cv::resize(frame, resized, {m_w, m_h});
cv::resize(frame, resized, {m_width, m_height});
image.resize(resized.cols, resized.rows); // erases previous content
frame = cv::Mat(image.height(), image.width(), CV_8UC3, image.getRawImage(), image.getRowSize());
resized.copyTo(frame);
Expand Down
35 changes: 9 additions & 26 deletions src/devices/opencvGrabber/OpenCVGrabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <yarp/dev/DeviceDriver.h>
#include <yarp/os/Stamp.h>
#include <yarp/dev/IPreciselyTimed.h>
#include "OpenCVGrabber_ParamsParser.h"

#include <opencv2/videoio.hpp>

Expand All @@ -31,7 +32,8 @@
class OpenCVGrabber :
public yarp::dev::IFrameGrabberImage,
public yarp::dev::DeviceDriver,
public yarp::dev::IPreciselyTimed
public yarp::dev::IPreciselyTimed,
public OpenCVGrabber_ParamsParser
{
public:

Expand All @@ -41,16 +43,10 @@ class OpenCVGrabber :
* open().
*/
OpenCVGrabber() :
m_w(0),
m_h(0),
m_loop(false),
m_saidSize(false),
m_saidResize(false),
fromFile(false),
m_cap(),
m_transpose(false),
m_flip_x(false),
m_flip_y(false)
m_cap()
{}

/** Destroy an OpenCV image grabber. */
Expand All @@ -67,11 +63,11 @@ class OpenCVGrabber :

/** Get the height of images a grabber produces.
* @return The image height. */
inline int height() const override { return m_h; }
inline int height() const override { return m_height; }

/** Get the width of images a grabber produces.
* @return The image width. */
inline int width() const override { return m_w; }
inline int width() const override { return m_width; }

/**
* Implements the IPreciselyTimed interface.
Expand All @@ -81,28 +77,15 @@ class OpenCVGrabber :

protected:

/** Width of the images a grabber produces. */
int m_w;
/** Height of the images a grabber produces. */
int m_h;

/** Whether to loop or not. */
bool m_loop;

bool m_saidSize;
bool m_saidResize;
bool m_saidSize = false;
bool m_saidResize = false;

/** Whether reading from file or camera. */
bool fromFile;
bool fromFile = false;

/** OpenCV image capture object. */
cv::VideoCapture m_cap;

/* optional image modifiers */
bool m_transpose;
bool m_flip_x;
bool m_flip_y;

/** Saved copy of the device configuration. */
yarp::os::Property m_config;

Expand Down
11 changes: 11 additions & 0 deletions src/devices/opencvGrabber/OpenCVGrabber.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
* | Group | Name | Type | Units | Default Value | Required | Description | Notes |
* |:--------:|:---------------------:|:-------:|:--------:|:-------------------:|:------------:|:-----------------------------------------------------------------:|:-----:|
* | | movie | string | - | - | No | if present, read an .avi file instead of opening a camera | |
* | | loop | bool | - | false | No | if true, and movie parameter is set, enable the loop playback of the file | |
* | | camera | int | - | 0 | No | Id of the camera hardware device | |
* | | framerate | double | - | -1 | No | Framerate. Default value obtained by the hardware | |
* | | width | int | - | 0 | No | Width of the frame. Default value obtained by the hardware | |
* | | height | int | - | 0 | No | Height of the frame. Default value obtained by the hardware | |
* | | flip_x | bool | - | false | No | Flip along the x axis | |
* | | flip_y | bool | - | false | No | flip along the y axis | |
* | | transpose | bool | - | false | No | Rotate the image by 90 degrees | |
Loading

0 comments on commit 049f156

Please sign in to comment.