Skip to content

Commit 31d216f

Browse files
committed
Use own image post processing node
1 parent bbcd3eb commit 31d216f

File tree

5 files changed

+103
-44
lines changed

5 files changed

+103
-44
lines changed

bitbots_misc/bitbots_basler_camera/CMakeLists.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,30 @@ if(NOT CMAKE_CXX_STANDARD)
66
set(CMAKE_CXX_STANDARD 17)
77
endif()
88

9-
find_package(rclcpp REQUIRED)
109
find_package(ament_cmake REQUIRED)
11-
find_package(bitbots_docs REQUIRED)
1210
find_package(backward_ros REQUIRED)
11+
find_package(bitbots_docs REQUIRED)
12+
find_package(cv_bridge REQUIRED)
13+
find_package(image_transport REQUIRED)
1314
find_package(OpenCV REQUIRED)
15+
find_package(rclcpp REQUIRED)
16+
find_package(sensor_msgs REQUIRED)
1417

1518
add_compile_options(-Wall -Werror -Wno-unused)
1619

1720
add_executable(postprocessing src/postprocessing.cpp)
1821

19-
target_link_libraries(postprocessing
20-
${OpenCV_LIBRARIES}
21-
)
22+
target_link_libraries(postprocessing ${OpenCV_LIBRARIES})
2223

2324
ament_target_dependencies(
2425
postprocessing
2526
ament_cmake
2627
bitbots_docs
27-
rclcpp)
28+
cv_bridge
29+
image_transport
30+
rclcpp
31+
sensor_msgs
32+
OpenCV)
2833

2934
enable_bitbots_docs()
3035

bitbots_misc/bitbots_basler_camera/config/binning.yaml

Lines changed: 0 additions & 3 deletions
This file was deleted.

bitbots_misc/bitbots_basler_camera/launch/basler_camera.launch

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,12 @@
1313
<param name="enable_current_params_publisher" value="true" />
1414
</node>
1515
<!-- Debayer + Binning -->
16-
<node_container pkg="rclcpp_components" exec="component_container" name="head_camera_image_proc_container" namespace="" launch-prefix="$(var taskset)">
17-
<composable_node pkg="image_proc" plugin="image_proc::DebayerNode" name="debayer">
18-
<remap from="image_raw" to="/pylon_camera_node/image_raw"/>
19-
<remap from="camera_info" to="/pylon_camera_node/camera_info"/>
20-
<remap from="image_color" to="/camera/image_raw"/>
21-
<remap from="image_mono" to="/camera/image_mono"/>
22-
</composable_node>
23-
<composable_node pkg="image_proc" plugin="image_proc::CropDecimateNode" name="crop_decimate">
24-
<remap from="in/image_raw" to="/camera/image_raw"/>
25-
<remap from="in/camera_info" to="/pylon_camera_node/camera_info"/>
26-
<remap from="out/image_raw" to="/camera/image_proc"/>
27-
<remap from="out/camera_info" to="/camera/camera_info"/>
28-
<param from="$(find-pkg-share bitbots_basler_camera)/config/binning.yaml"/>
29-
</composable_node>
30-
</node_container>
16+
<node pkg="bitbots_basler_camera" exec="postprocessing" name="basler_camera_post_processing" output="screen" launch-prefix="$(var taskset)">
17+
<remap from="in/image_raw" to="/pylon_camera_node/image_raw" />
18+
<remap from="in/camera_info" to="/pylon_camera_node/camera_info" />
19+
<remap from="out/image_proc" to="/camera/image_proc" />
20+
<remap from="out/camera_info" to="/camera/camera_info" />
21+
<param name="binning_factor_x" value="4" />
22+
<param name="binning_factor_y" value="4" />
23+
</node>
3124
</launch>

bitbots_misc/bitbots_basler_camera/package.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
<author email="[email protected]">Hamburg Bit-Bots</author>
1414

1515
<depend>bitbots_docs</depend>
16+
<depend>cv_bridge</depend>
17+
<depend>image_transport</depend>
18+
<depend>libopencv-dev</depend>
1619
<depend>pylon_ros2_camera_wrapper</depend>
17-
<depend>image_proc</depend>
20+
<depend>rclcpp</depend>
21+
<depend>sensor_msgs</depend>
1822

1923
<buildtool_depend>ament_cmake</buildtool_depend>
2024

bitbots_misc/bitbots_basler_camera/src/postprocessing.cpp

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,112 @@
11
#include <cmath>
2+
#include <cv_bridge/cv_bridge.hpp>
3+
#include <image_transport/image_transport.hpp>
24
#include <iostream>
35
#include <memory>
6+
#include <opencv2/imgproc/imgproc.hpp>
47
#include <rclcpp/experimental/executors/events_executor/events_executor.hpp>
58
#include <rclcpp/logger.hpp>
69
#include <rclcpp/rclcpp.hpp>
710
#include <string>
811
#include <vector>
912

10-
#include <opencv2/imgproc/imgproc.hpp>
11-
#include <image_transport/image_transport.hpp>
12-
13-
using std::placeholders::_1;
13+
using std::placeholders::_1, std::placeholders::_2;
1414

1515
namespace postprocessing {
1616

17-
1817
class PostProcessor {
1918
std::shared_ptr<rclcpp::Node> node_;
2019

21-
// Declare subscriber
22-
//rclcpp::Subscription<bitbots_msgs::msg::HeadMode>::SharedPtr head_mode_subscriber_;
23-
//rclcpp::Subscription<sensor_msgs::msg::JointState>::SharedPtr joint_state_subscriber_;
20+
image_transport::TransportHints transport_hints_;
21+
std::unique_ptr<image_transport::CameraSubscriber> image_sub_;
22+
std::unique_ptr<image_transport::CameraPublisher> image_pub_;
2423

25-
// Declare publisher
26-
//rclcpp::Publisher<bitbots_msgs::msg::JointCommand>::SharedPtr position_publisher_;
24+
int binning_factor_x_ = 1;
25+
int binning_factor_y_ = 1;
2726

2827
public:
29-
PostProcessor() : node_(std::make_shared<rclcpp::Node>("post_processor")) {
30-
// Initialize publisher for head motor goals
31-
//position_publisher_ = node_->create_publisher<bitbots_msgs::msg::JointCommand>("head_motor_goals", 10);
32-
33-
// Initialize subscriber for head mode
34-
//head_mode_subscriber_ = node_->create_subscription<bitbots_msgs::msg::HeadMode>(
35-
// "head_mode", 10, [this](const bitbots_msgs::msg::HeadMode::SharedPtr msg) { head_mode_callback(msg); });
28+
PostProcessor()
29+
: node_(std::make_shared<rclcpp::Node>("post_processor")),
30+
transport_hints_(node_.get()),
31+
image_sub_(std::make_unique<image_transport::CameraSubscriber>(image_transport::create_camera_subscription(
32+
node_.get(), "in/image_raw", std::bind(&PostProcessor::image_callback, this, _1, _2),
33+
transport_hints_.getTransport()))),
34+
image_pub_(std::make_unique<image_transport::CameraPublisher>(
35+
image_transport::create_camera_publisher(node_.get(), "out/image_proc"))) {
36+
// Declare parameters
37+
node_->declare_parameter("binning_factor_x", 4);
38+
node_->declare_parameter("binning_factor_y", 4);
3639

40+
// Get parameters
41+
node_->get_parameter("binning_factor_x", binning_factor_x_);
42+
node_->get_parameter("binning_factor_y", binning_factor_y_);
3743
}
3844

3945
/**
4046
* @brief Callback used to update the head mode
4147
*/
42-
//void head_mode_callback(const bitbots_msgs::msg::HeadMode::SharedPtr msg) { head_mode_ = msg->head_mode; }
48+
void image_callback(const sensor_msgs::msg::Image::ConstSharedPtr& image_msg,
49+
const sensor_msgs::msg::CameraInfo::ConstSharedPtr& info_msg) {
50+
// Convert to cv::Mat
51+
cv::Mat image = cv_bridge::toCvShare(image_msg)->image;
52+
53+
// Do some processing
54+
int bit_depth = sensor_msgs::image_encodings::bitDepth(image_msg->encoding);
55+
56+
int type = bit_depth == 8 ? CV_8U : CV_16U;
57+
58+
// Create cv::Mat for color image
59+
cv::Mat color(image_msg->height, image_msg->width, CV_MAKETYPE(type, 3));
60+
61+
// Create cv::Mat for
62+
const cv::Mat bayer(image_msg->height, image_msg->width, CV_MAKETYPE(type, 1),
63+
const_cast<uint8_t*>(&image_msg->data[0]), image_msg->step);
64+
65+
// Get the correct conversion code
66+
int code = -1;
67+
if (image_msg->encoding == sensor_msgs::image_encodings::BAYER_RGGB8 ||
68+
image_msg->encoding == sensor_msgs::image_encodings::BAYER_RGGB16) {
69+
code = cv::COLOR_BayerBG2BGR;
70+
} else if (image_msg->encoding == sensor_msgs::image_encodings::BAYER_BGGR8 || // NOLINT
71+
image_msg->encoding == sensor_msgs::image_encodings::BAYER_BGGR16) {
72+
code = cv::COLOR_BayerRG2BGR;
73+
} else if (image_msg->encoding == sensor_msgs::image_encodings::BAYER_GBRG8 || // NOLINT
74+
image_msg->encoding == sensor_msgs::image_encodings::BAYER_GBRG16) {
75+
code = cv::COLOR_BayerGR2BGR;
76+
} else if (image_msg->encoding == sensor_msgs::image_encodings::BAYER_GRBG8 || // NOLINT
77+
image_msg->encoding == sensor_msgs::image_encodings::BAYER_GRBG16) {
78+
code = cv::COLOR_BayerGB2BGR;
79+
}
80+
code += cv::COLOR_BayerBG2BGR_VNG - cv::COLOR_BayerBG2BGR;
81+
82+
// Debayer the image
83+
cv::cvtColor(bayer, color, code);
84+
85+
// Perform binning by a given factor
86+
cv::Mat binned(image_msg->height / binning_factor_y_, image_msg->width / binning_factor_x_, CV_MAKETYPE(type, 3));
87+
cv::resize(color, binned, cv::Size(), 1.0 / binning_factor_x_, 1.0 / binning_factor_y_, cv::INTER_AREA);
88+
89+
// Add the binning to the camera info
90+
auto new_camera_info = std::make_shared<sensor_msgs::msg::CameraInfo>(*info_msg);
91+
new_camera_info->binning_x = binning_factor_x_;
92+
new_camera_info->binning_y = binning_factor_y_;
93+
94+
// Convert back to sensor_msgs::Image
95+
cv_bridge::CvImage color_msg;
96+
color_msg.header = image_msg->header;
97+
color_msg.encoding = sensor_msgs::image_encodings::BGR8;
98+
color_msg.image = binned;
99+
100+
// Publish the image
101+
image_pub_->publish(color_msg.toImageMsg(), new_camera_info);
102+
}
43103

44104
/**
45105
* @brief A getter that returns the node
46106
*/
47107
std::shared_ptr<rclcpp::Node> get_node() { return node_; }
48108
};
49-
} // namespace move_head
109+
} // namespace postprocessing
50110

51111
int main(int argc, char* argv[]) {
52112
rclcpp::init(argc, argv);

0 commit comments

Comments
 (0)