Skip to content

Commit f6f16c2

Browse files
authored
Merge pull request #2 from DanielArnett/master
Enabling the use of BGRA in addition to BGR
2 parents 7f1bebe + 6efbddd commit f6f16c2

File tree

8 files changed

+108
-49
lines changed

8 files changed

+108
-49
lines changed

‎opengl_ros/CMakeLists.txt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ find_package(catkin REQUIRED COMPONENTS
1414
image_transport
1515
cv_bridge
1616
opengl_ros_lib
17+
dynamic_reconfigure
1718
)
1819

1920
## System dependencies are found with CMake's conventions
@@ -95,7 +96,9 @@ find_package(OpenCV REQUIRED)
9596
# cfg/DynReconf1.cfg
9697
# cfg/DynReconf2.cfg
9798
# )
98-
99+
generate_dynamic_reconfigure_options(
100+
cfg/opengl_ros.cfg
101+
)
99102
###################################
100103
## catkin specific configuration ##
101104
###################################

‎opengl_ros/cfg/opengl_ros.cfg‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env python
2+
PACKAGE = "opengl_ros"
3+
4+
from dynamic_reconfigure.parameter_generator_catkin import *
5+
6+
gen = ParameterGenerator()
7+
8+
gen.add("threshold_l", double_t, 0, "", 0, 0, 1)
9+
gen.add("svm_coef_a", double_t, 0, "", 0, 0, 1)
10+
gen.add("svm_coef_b", double_t, 0, "", 0, 0, 1)
11+
gen.add("svm_intercept", double_t, 0, "", 0, -100, 100)
12+
exit(gen.generate(PACKAGE, "opengl_ros", "opengl_ros"))

‎opengl_ros/launch/color_extraction_gpu.launch‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,26 @@
1717
<remap from="/usb_cam/image_raw" to="/image_in"/>
1818
</node>
1919

20+
<node name="dynamic_reconfigure_load" pkg="dynamic_reconfigure" type="dynparam" args="load color_extraction_params $(find opengl_ros)/params/color_extraction.yaml" />
2021
<node pkg="opengl_ros" type="simple_renderer"
2122
name="simple_renderer" output="screen">
2223
<param name="width" value="$(arg width)"/>
2324
<param name="height" value="$(arg height)"/>
2425
<param name="vertex_shader" value="$(find opengl_ros_lib)/shader/vs_passthrough.glsl"/>
2526
<param name="fragment_shader" value="$(find opengl_ros)/shader/fs_color_extraction.glsl"/>
26-
27-
<param name="threshold_l" value="0"/>
28-
<param name="svm_coef_a" value="0.266602955271"/>
29-
<param name="svm_coef_b" value="0.0444656815907"/>
30-
<param name="svm_intercept" value="-44.3271851592"/>
31-
32-
<remap from="image_in" to="/image_in"/>
33-
<remap from="image_out" to="/image_out"/>
27+
<param name="image_in" value="/image_in"/>
28+
<param name="image_out" value="/image_out"/>
3429
</node>
3530

31+
<node pkg="rqt_reconfigure" type="rqt_reconfigure" name="reconfigure_gui"/>
32+
3633
<node pkg="image_view" type="image_view" name="viewer_in">
3734
<remap from="image" to="/image_in"/>
35+
<param name="window_name" value="Input Image"/>
3836
</node>
3937

4038
<node pkg="image_view" type="image_view" name="viewer_out">
4139
<remap from="image" to="/image_out"/>
40+
<param name="window_name" value="Output Image"/>
4241
</node>
4342
</launch>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
!!python/object/new:dynamic_reconfigure.encoding.Config
2+
dictitems:
3+
threshold_l: 0
4+
svm_coef_a: 0.266602955271
5+
svm_coef_b: 0.0444656815907
6+
svm_intercept: -44.3271851592
7+
state: []

‎opengl_ros/src/simple_renderer_nodecore.cpp‎

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,25 @@
66

77
using namespace opengl_ros;
88

9+
void SimpleRendererNode::reconfigure_callback(opengl_ros::opengl_rosConfig &config, uint32_t level) {
10+
threshold_l_ = config.threshold_l;
11+
svm_coef_a_ = config.svm_coef_a;
12+
svm_coef_b_ = config.svm_coef_b;
13+
svm_intercept_ = config.svm_intercept;
14+
15+
renderer_->uniform("threshold_l" , threshold_l_);
16+
renderer_->uniform("svm_coef_a" , svm_coef_a_);
17+
renderer_->uniform("svm_coef_b" , svm_coef_b_);
18+
renderer_->uniform("svm_intercept", svm_intercept_);
19+
}
20+
921
SimpleRendererNode::SimpleRendererNode(const ros::NodeHandle& nh, const ros::NodeHandle& nh_private)
1022
: nh_(nh_private), it_(nh)
1123
{
24+
std::string image_in, image_out;
25+
nh_.param<std::string>("image_in" , image_in , "");
26+
nh_.param<std::string>("image_out" , image_out , "");
27+
1228
imagePublisher_ = it_.advertise("image_out", 1);
1329
imageSubscriber_ = it_.subscribe("image_in" , 1, &SimpleRendererNode::imageCallback, this);
1430

@@ -25,17 +41,6 @@ SimpleRendererNode::SimpleRendererNode(const ros::NodeHandle& nh, const ros::Nod
2541
vertexShader, fragmentShader
2642
);
2743

28-
float threshold_l, svm_coef_a, svm_coef_b, svm_intercept;
29-
nh_.param<float>("threshold_l" , threshold_l , 0);
30-
nh_.param<float>("svm_coef_a" , svm_coef_a , 0);
31-
nh_.param<float>("svm_coef_b" , svm_coef_b , 0);
32-
nh_.param<float>("svm_intercept", svm_intercept, 0);
33-
34-
renderer_->uniform("threshold_l" , threshold_l);
35-
renderer_->uniform("svm_coef_a" , svm_coef_a);
36-
renderer_->uniform("svm_coef_b" , svm_coef_b);
37-
renderer_->uniform("svm_intercept", svm_intercept);
38-
3944
output_.create(height, width, CV_8UC3);
4045
}
4146

@@ -71,5 +76,10 @@ void SimpleRendererNode::imageCallback(const sensor_msgs::Image::ConstPtr& msg)
7176

7277
void SimpleRendererNode::run()
7378
{
79+
dynamic_reconfigure::Server<opengl_ros::opengl_rosConfig> server(ros::NodeHandle("color_extraction_params"));
80+
dynamic_reconfigure::Server<opengl_ros::opengl_rosConfig>::CallbackType f;
81+
f = boost::bind(boost::mem_fn(&SimpleRendererNode::reconfigure_callback), this, _1, _2);
82+
server.setCallback(f);
83+
7484
ros::spin();
7585
}

‎opengl_ros/src/simple_renderer_nodecore.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
#include <ros/ros.h>
77
#include <sensor_msgs/Image.h>
88
#include <image_transport/image_transport.h>
9+
#include <dynamic_reconfigure/server.h>
10+
#include <opengl_ros/opengl_rosConfig.h>
911

1012
#include "simple_renderer.h"
1113

14+
1215
namespace opengl_ros {
1316

1417
class SimpleRendererNode
@@ -26,6 +29,9 @@ class SimpleRendererNode
2629
cv::Mat output_;
2730

2831
void imageCallback(const sensor_msgs::Image::ConstPtr& msg);
32+
void reconfigure_callback(opengl_ros::opengl_rosConfig &config, uint32_t level);
33+
float threshold_l_, svm_coef_a_, svm_coef_b_, svm_intercept_;
34+
2935

3036
public:
3137
SimpleRendererNode(const ros::NodeHandle& nh, const ros::NodeHandle& nh_private);

‎opengl_ros_lib/include/simple_renderer.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class SimpleRenderer final
3030
void uniform(const std::string& name, unsigned int v1, unsigned int v2, unsigned int v3, unsigned int v4);
3131

3232
void render(cv::Mat& dest, const cv::Mat& src);
33+
void render(cv::Mat& dest, const cv::Mat& src, const cv::Mat& secondSrc);
3334

3435
SimpleRenderer(const SimpleRenderer&) = delete;
3536
SimpleRenderer& operator=(const SimpleRenderer&) = delete;
@@ -43,4 +44,4 @@ class SimpleRenderer final
4344

4445
} //cgs
4546

46-
#endif
47+
#endif

‎opengl_ros_lib/src/simple_renderer.cpp‎

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,26 @@ struct SimpleRenderer::Impl
3737

3838
Egl egl_;
3939
const int width_, height_;
40+
int channels_ = 3;
41+
unsigned int glFormat_ = GL_BGR;
42+
unsigned int cvMatType_ = CV_8UC3;
43+
bool formatSet_;
4044

4145
std::array<cgs::gl::Shader, 2> shaders_;
4246
cgs::gl::Program program_;
4347
cgs::gl::VertexBuffer<Vertex> vbo_;
4448
cgs::gl::ElementBuffer<uint> ebo_;
4549
cgs::gl::VertexArray vao_;
46-
cgs::gl::Texture2D textureIn_, textureOut_;
50+
cgs::gl::Texture2D textureIn_, textureOut_, secondTexture_;
4751
cgs::gl::Sampler sampler_;
4852
cgs::gl::FrameBuffer fbo_;
4953

5054
Impl(int width, int height,
5155
const std::string& vertexShader,
5256
const std::string& fragmentShader);
53-
57+
void checkFormat(const cv::Mat& src);
5458
void render(cv::Mat& dest, const cv::Mat& src);
59+
void render(cv::Mat& dest, const cv::Mat& src, const cv::Mat& secondSrc);
5560
};
5661

5762
constexpr std::array<Vertex, 4> SimpleRenderer::Impl::VERTICIES;
@@ -113,7 +118,7 @@ SimpleRenderer::Impl::Egl::Egl() :
113118
SimpleRenderer::Impl::Impl(
114119
int width, int height,
115120
const std::string& vertexShader,
116-
const std::string& fragmentShader) :
121+
const std::string& fragmentShader) :
117122
width_(width), height_(height),
118123
shaders_({
119124
cgs::gl::Shader(GL_VERTEX_SHADER, vertexShader),
@@ -122,47 +127,50 @@ SimpleRenderer::Impl::Impl(
122127
program_(shaders_),
123128
vbo_(VERTICIES, GL_STATIC_DRAW),
124129
ebo_(INDICIES, GL_STATIC_DRAW),
125-
textureIn_(GL_SRGB8, width_, height_), //
126-
textureOut_(GL_SRGB8, width_, height_), //Assuming sRGB input and output
130+
textureIn_(GL_SRGB8_ALPHA8, width_, height_), //
131+
textureOut_(GL_SRGB8_ALPHA8, width_, height_), //Assuming sRGB input and output
132+
secondTexture_(GL_SRGB8_ALPHA8, width_, height_),
127133
sampler_(GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE),
128134
fbo_(textureOut_)
129135
{
130136
//Shaders setup
131137
program_.use();
132138
glUniform2f(glGetUniformLocation(program_.get(), "resolution"), width_, height_);
133139
glUniform1i(glGetUniformLocation(program_.get(), "texture"), 0);
140+
glUniform1i(glGetUniformLocation(program_.get(), "secondTexture"), 1);
134141

135142
//Verticies setup
136143
vao_.mapVariable(vbo_, glGetAttribLocation(program_.get(), "position"), 3, GL_FLOAT, 0);
137144
vao_.mapVariable(ebo_);
138145
}
139-
140-
void SimpleRenderer::Impl::render(cv::Mat& dest, const cv::Mat& src)
146+
void SimpleRenderer::Impl::checkFormat(const cv::Mat& src)
141147
{
142-
if (width_ != dest.cols || height_ != dest.rows || CV_8UC3 != dest.type())
143-
{
144-
ROS_ERROR_STREAM(
145-
"Destination image resolution does not match." <<
146-
"width: texture=" << width_ << ", input=" << dest.cols <<
147-
"height: texture=" << height_ << ", input=" << dest.rows <<
148-
"channel: texture=" << 3 << ", input=" << dest.channels() <<
149-
"elemSize1: texture=" << 1 << ", input=" << dest.elemSize1());
150-
return;
148+
if (!formatSet_) {
149+
if (src.channels() == 4)
150+
{
151+
channels_ = 4;
152+
glFormat_ = GL_BGRA;
153+
cvMatType_ = CV_8UC4;
154+
}
155+
formatSet_ = true;
151156
}
152-
153-
if (width_ != src.cols || height_ != src.rows || CV_8UC3 != dest.type())
157+
if (width_ != src.cols || height_ != src.rows || cvMatType_ != src.type())
154158
{
155159
ROS_ERROR_STREAM(
156-
"Source image resolution does not match." <<
157-
"width: texture=" << width_ << ", input=" << src.cols <<
158-
"height: texture=" << height_ << ", input=" << src.rows <<
159-
"channel: texture=" << 3 << ", input=" << src.channels() <<
160-
"elemSize1: texture=" << 1 << ", input=" << src.elemSize1());
160+
"Image resolution does not match." <<
161+
"width: texture=" << width_ << ", input=" << src.cols <<
162+
"height: texture=" << height_ << ", input=" << src.rows <<
163+
"channel: texture=" << channels_<< ", input=" << src.channels() <<
164+
"elemSize1: texture=" << 1 << ", input=" << src.elemSize1());
161165
return;
162166
}
163-
167+
}
168+
void SimpleRenderer::Impl::render(cv::Mat& dest, const cv::Mat& src)
169+
{
170+
checkFormat(src);
171+
checkFormat(dest);
164172
//Perform rendering
165-
textureIn_.write(GL_BGR, GL_UNSIGNED_BYTE, src.data);
173+
textureIn_.write(glFormat_, GL_UNSIGNED_BYTE, src.data);
166174
textureIn_.bindToUnit(0);
167175
sampler_.bindToUnit(0);
168176

@@ -175,7 +183,16 @@ void SimpleRenderer::Impl::render(cv::Mat& dest, const cv::Mat& src)
175183
glFinish();
176184

177185
//Read result
178-
textureOut_.read(GL_BGR, GL_UNSIGNED_BYTE, dest.data, dest.rows * dest.cols * dest.channels());
186+
textureOut_.read(glFormat_, GL_UNSIGNED_BYTE, dest.data, dest.rows * dest.cols * dest.channels());
187+
}
188+
189+
void SimpleRenderer::Impl::render(cv::Mat& dest, const cv::Mat& src, const cv::Mat& secondSrc)
190+
{
191+
checkFormat(secondSrc);
192+
secondTexture_.write(glFormat_, GL_UNSIGNED_BYTE, secondSrc.data);
193+
secondTexture_.bindToUnit(1);
194+
sampler_.bindToUnit(1);
195+
this->render(dest, src);
179196
}
180197

181198
SimpleRenderer::SimpleRenderer(
@@ -198,7 +215,6 @@ catch (cgs::gl::Exception& e)
198215
}
199216

200217
SimpleRenderer::~SimpleRenderer() = default;
201-
202218
void SimpleRenderer::uniform(const std::string& name, float v1) {
203219
glUniform1f(glGetUniformLocation(impl_->program_.get(), name.c_str()), v1);
204220
}
@@ -236,7 +252,12 @@ void SimpleRenderer::uniform(const std::string& name, unsigned int v1, unsigned
236252
glUniform4ui(glGetUniformLocation(impl_->program_.get(), name.c_str()), v1, v2, v3, v4);
237253
}
238254

255+
void SimpleRenderer::render(cv::Mat& dest, const cv::Mat& src, const cv::Mat& secondSrc)
256+
{
257+
impl_->render(dest, src, secondSrc);
258+
}
259+
239260
void SimpleRenderer::render(cv::Mat& dest, const cv::Mat& src)
240261
{
241262
impl_->render(dest, src);
242-
}
263+
}

0 commit comments

Comments
 (0)