Skip to content

Commit 5d81e51

Browse files
author
Joshua Whitley
authored
Removing image_view node and replacing with image_view that loads nodelet. (#479)
1 parent 1cdc128 commit 5d81e51

File tree

1 file changed

+9
-184
lines changed

1 file changed

+9
-184
lines changed
Lines changed: 9 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*********************************************************************
22
* Software License Agreement (BSD License)
33
*
4-
* Copyright (c) 2008, Willow Garage, Inc.
4+
* Copyright (c) 2008, 2019 Willow Garage, Inc., Joshua Whitley
55
* All rights reserved.
66
*
77
* Redistribution and use in source and binary forms, with or without
@@ -31,197 +31,22 @@
3131
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3232
* POSSIBILITY OF SUCH DAMAGE.
3333
*********************************************************************/
34-
#include <image_view/ImageViewConfig.h>
3534

3635
#include <ros/ros.h>
37-
#include <image_transport/image_transport.h>
38-
#include <dynamic_reconfigure/server.h>
36+
#include <nodelet/loader.h>
3937

40-
#include <cv_bridge/cv_bridge.h>
41-
#include <opencv2/highgui/highgui.hpp>
42-
43-
#include <boost/format.hpp>
44-
#include <boost/thread.hpp>
45-
#include <boost/filesystem.hpp>
46-
47-
int g_count;
48-
cv::Mat g_last_image;
49-
boost::format g_filename_format;
50-
boost::mutex g_image_mutex;
51-
std::string g_window_name;
52-
bool g_gui;
53-
ros::Publisher g_pub;
54-
bool g_do_dynamic_scaling;
55-
int g_colormap;
56-
double g_min_image_value;
57-
double g_max_image_value;
58-
59-
void reconfigureCb(image_view::ImageViewConfig &config, uint32_t level)
60-
{
61-
boost::mutex::scoped_lock lock(g_image_mutex);
62-
g_do_dynamic_scaling = config.do_dynamic_scaling;
63-
g_colormap = config.colormap;
64-
g_min_image_value = config.min_image_value;
65-
g_max_image_value = config.max_image_value;
66-
}
67-
68-
void imageCb(const sensor_msgs::ImageConstPtr& msg)
69-
{
70-
boost::mutex::scoped_lock lock(g_image_mutex);
71-
72-
// Convert to OpenCV native BGR color
73-
cv_bridge::CvImageConstPtr cv_ptr;
74-
try {
75-
cv_bridge::CvtColorForDisplayOptions options;
76-
options.do_dynamic_scaling = g_do_dynamic_scaling;
77-
options.colormap = g_colormap;
78-
// Set min/max value for scaling to visualize depth/float image.
79-
if (g_min_image_value == g_max_image_value) {
80-
// Not specified by rosparam, then set default value.
81-
// Because of current sensor limitation, we use 10m as default of max range of depth
82-
// with consistency to the configuration in rqt_image_view.
83-
options.min_image_value = 0;
84-
if (msg->encoding == "32FC1") {
85-
options.max_image_value = 10; // 10 [m]
86-
} else if (msg->encoding == "16UC1") {
87-
options.max_image_value = 10 * 1000; // 10 * 1000 [mm]
88-
}
89-
} else {
90-
options.min_image_value = g_min_image_value;
91-
options.max_image_value = g_max_image_value;
92-
}
93-
cv_ptr = cv_bridge::cvtColorForDisplay(cv_bridge::toCvShare(msg), "", options);
94-
g_last_image = cv_ptr->image;
95-
} catch (cv_bridge::Exception& e) {
96-
ROS_ERROR_THROTTLE(30, "Unable to convert '%s' image for display: '%s'",
97-
msg->encoding.c_str(), e.what());
98-
}
99-
if (g_gui && !g_last_image.empty()) {
100-
const cv::Mat &image = g_last_image;
101-
cv::imshow(g_window_name, image);
102-
cv::waitKey(1);
103-
}
104-
if (g_pub.getNumSubscribers() > 0) {
105-
g_pub.publish(cv_ptr);
106-
}
107-
}
108-
109-
static void mouseCb(int event, int x, int y, int flags, void* param)
110-
{
111-
if (event == cv::EVENT_LBUTTONDOWN) {
112-
ROS_WARN_ONCE("Left-clicking no longer saves images. Right-click instead.");
113-
return;
114-
} else if (event != cv::EVENT_RBUTTONDOWN) {
115-
return;
116-
}
117-
118-
boost::mutex::scoped_lock lock(g_image_mutex);
119-
120-
const cv::Mat &image = g_last_image;
121-
122-
if (image.empty()) {
123-
ROS_WARN("Couldn't save image, no data!");
124-
return;
125-
}
126-
127-
std::string filename = (g_filename_format % g_count).str();
128-
if (cv::imwrite(filename, image)) {
129-
ROS_INFO("Saved image %s", filename.c_str());
130-
g_count++;
131-
} else {
132-
boost::filesystem::path full_path = boost::filesystem::complete(filename);
133-
ROS_ERROR_STREAM("Failed to save image. Have permission to write there?: " << full_path);
134-
}
135-
}
136-
137-
static void guiCb(const ros::WallTimerEvent&)
138-
{
139-
// Process pending GUI events and return immediately
140-
cv::waitKey(1);
141-
}
142-
143-
int main(int argc, char **argv)
38+
int main(int argc, char** argv)
14439
{
145-
ros::init(argc, argv, "image_view", ros::init_options::AnonymousName);
146-
if (ros::names::remap("image") == "image") {
147-
ROS_WARN("Topic 'image' has not been remapped! Typical command-line usage:\n"
148-
"\t$ rosrun image_view image_view image:=<image topic> [transport]");
149-
}
150-
151-
ros::NodeHandle nh;
152-
ros::NodeHandle local_nh("~");
153-
ros::WallTimer gui_timer;
154-
155-
// Default window name is the resolved topic name
156-
std::string topic = nh.resolveName("image");
157-
local_nh.param("window_name", g_window_name, topic);
158-
local_nh.param("gui", g_gui, true); // gui/no_gui mode
159-
160-
if (g_gui) {
161-
std::string format_string;
162-
local_nh.param("filename_format", format_string, std::string("frame%04i.jpg"));
163-
g_filename_format.parse(format_string);
164-
165-
// Handle window size
166-
bool autosize;
167-
local_nh.param("autosize", autosize, false);
168-
cv::namedWindow(g_window_name, autosize ? (cv::WINDOW_AUTOSIZE | cv::WINDOW_KEEPRATIO | cv::WINDOW_GUI_EXPANDED) : 0);
169-
cv::setMouseCallback(g_window_name, &mouseCb);
170-
171-
if(autosize == false)
172-
{
173-
if(local_nh.hasParam("width") && local_nh.hasParam("height"))
174-
{
175-
int width;
176-
local_nh.getParam("width", width);
177-
int height;
178-
local_nh.getParam("height", height);
179-
cv::resizeWindow(g_window_name, width, height);
180-
}
181-
}
182-
183-
// Since cv::startWindowThread() triggers a crash in cv::waitKey()
184-
// if OpenCV is compiled against GTK, we call cv::waitKey() from
185-
// the ROS event loop periodically, instead.
186-
/*cv::startWindowThread();*/
187-
gui_timer = local_nh.createWallTimer(ros::WallDuration(0.1), guiCb);
188-
}
40+
ros::init(argc, argv, "image_view");
18941

190-
// Handle transport
191-
// priority:
192-
// 1. command line argument
193-
// 2. rosparam '~image_transport'
194-
std::string transport;
195-
local_nh.param("image_transport", transport, std::string("raw"));
196-
ros::V_string myargv;
197-
ros::removeROSArgs(argc, argv, myargv);
198-
for (size_t i = 1; i < myargv.size(); ++i) {
199-
if (myargv[i][0] != '-') {
200-
transport = myargv[i];
201-
break;
202-
}
203-
}
204-
ROS_INFO_STREAM("Using transport \"" << transport << "\"");
205-
image_transport::ImageTransport it(nh);
206-
image_transport::TransportHints hints(transport, ros::TransportHints(), local_nh);
207-
image_transport::Subscriber sub = it.subscribe(topic, 1, imageCb, hints);
208-
g_pub = local_nh.advertise<sensor_msgs::Image>("output", 1);
42+
nodelet::Loader nodelet;
43+
nodelet::M_string remap(ros::names::getRemappings());
44+
nodelet::V_string nargv;
20945

210-
dynamic_reconfigure::Server<image_view::ImageViewConfig> srv;
211-
dynamic_reconfigure::Server<image_view::ImageViewConfig>::CallbackType f =
212-
boost::bind(&reconfigureCb, _1, _2);
213-
srv.setCallback(f);
46+
std::string nodelet_name = ros::this_node::getName();
47+
nodelet.load(nodelet_name, "image_view/image", remap, nargv);
21448

21549
ros::spin();
21650

217-
if (g_gui) {
218-
cv::destroyWindow(g_window_name);
219-
}
220-
// The publisher is a global variable, and therefore its scope exceeds those
221-
// of the node handles in main(). Unfortunately, this will cause a crash
222-
// when the publisher tries to shut down and all node handles are gone
223-
// already. Therefore, we shut down the publisher now and avoid the annoying
224-
// mutex assertion.
225-
g_pub.shutdown();
22651
return 0;
22752
}

0 commit comments

Comments
 (0)