41 #include <opencv2/opencv.hpp> 43 #include <QMessageBox> 55 setObjectName(
"ImageCropper");
69 ui_.image_frame->installEventFilter(
this);
73 ui_.topics_combo_box->setCurrentIndex(
ui_.topics_combo_box->findText(
""));
74 connect(
ui_.topics_combo_box, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
onInTopicChanged(
int)));
76 ui_.out_topic_line_edit->setText(
"/cropped");
80 ui_.refresh_topics_push_button->setIcon(QIcon::fromTheme(
"view-refresh"));
81 connect(
ui_.refresh_topics_push_button, SIGNAL(pressed()),
this, SLOT(
updateTopicList()));
83 connect(
ui_.dynamic_range_check_box, SIGNAL(toggled(
bool)),
this, SLOT(
onDynamicRange(
bool)));
86 connect(
ui_.image_frame, SIGNAL(selectionInProgress(QPoint,QPoint)),
this, SLOT(
onSelectionInProgress(QPoint,QPoint)));
87 connect(
ui_.image_frame, SIGNAL(selectionFinished(QPoint,QPoint)),
this, SLOT(
onSelectionFinished(QPoint,QPoint)));
92 if (watched ==
ui_.image_frame && event->type() == QEvent::Paint)
94 QPainter painter(
ui_.image_frame);
97 ui_.image_frame->resizeToFitAspectRatio();
102 painter.drawImage(
ui_.image_frame->contentsRect(),
qimage_);
106 QLinearGradient gradient(0, 0,
ui_.image_frame->frameRect().width(),
ui_.image_frame->frameRect().height());
107 gradient.setColorAt(0, Qt::white);
108 gradient.setColorAt(1, Qt::black);
109 painter.setBrush(gradient);
110 painter.drawRect(0, 0,
ui_.image_frame->frameRect().width() + 1,
ui_.image_frame->frameRect().height() + 1);
117 painter.setPen(Qt::red);
121 ui_.image_frame->update();
126 return QObject::eventFilter(watched, event);
137 QString topic =
ui_.topics_combo_box->currentText();
139 instance_settings.
setValue(
"topic", topic);
140 instance_settings.
setValue(
"dynamic_range",
ui_.dynamic_range_check_box->isChecked());
141 instance_settings.
setValue(
"max_range",
ui_.max_range_double_spin_box->value());
146 bool dynamic_range_checked = instance_settings.
value(
"dynamic_range",
false).toBool();
147 ui_.dynamic_range_check_box->setChecked(dynamic_range_checked);
149 double max_range = instance_settings.
value(
"max_range",
ui_.max_range_double_spin_box->value()).toDouble();
150 ui_.max_range_double_spin_box->setValue(max_range);
152 QString topic = instance_settings.
value(
"topic",
"").toString();
159 QSet<QString> message_types;
160 message_types.insert(
"sensor_msgs/Image");
163 QList<QString> transports;
166 for (std::vector<std::string>::const_iterator it = declared.begin(); it != declared.end(); it++)
169 QString transport = it->c_str();
172 QString prefix =
"image_transport/";
173 if (transport.startsWith(prefix))
175 transport = transport.mid(prefix.length());
177 transports.append(transport);
180 QString selected =
ui_.topics_combo_box->currentText();
183 QList<QString> topics =
getTopicList(message_types, transports);
186 ui_.topics_combo_box->clear();
187 for (QList<QString>::const_iterator it = topics.begin(); it != topics.end(); it++)
190 label.replace(
" ",
"/");
191 ui_.topics_combo_box->addItem(label, QVariant(*it));
203 QSet<QString> all_topics;
204 for (ros::master::V_TopicInfo::const_iterator it = topic_info.begin(); it != topic_info.end(); it++)
206 all_topics.insert(it->name.c_str());
209 QList<QString> topics;
210 for (ros::master::V_TopicInfo::const_iterator it = topic_info.begin(); it != topic_info.end(); it++)
212 if (message_types.contains(it->datatype.c_str()))
214 QString topic = it->name.c_str();
217 topics.append(topic);
221 for (QList<QString>::const_iterator jt = transports.begin(); jt != transports.end(); jt++)
223 if (all_topics.contains(topic +
"/" + *jt))
225 QString sub = topic +
" " + *jt;
237 int index =
ui_.topics_combo_box->findText(topic);
240 index =
ui_.topics_combo_box->findText(
"");
242 ui_.topics_combo_box->setCurrentIndex(index);
251 ui_.image_frame->update();
253 QStringList parts =
ui_.topics_combo_box->itemData(index).toString().split(
" ");
254 QString topic = parts.first();
255 QString transport = parts.length() == 2 ? parts.last() :
"raw";
257 if (!topic.isEmpty())
265 QMessageBox::warning(
widget_, tr(
"Loading image transport plugin failed"), e.what());
276 QString topic =
ui_.out_topic_line_edit->text();
285 QMessageBox::warning(
widget_, tr(
"Loading image transport plugin failed"), e.what());
297 int tl_x = std::min(p1.x(), p2.x());
298 int tl_y = std::min(p1.y(), p2.y());
313 int tl_x = p1.x() < p2.x() ? p1.x() : p2.x();
314 int tl_y = p1.y() < p2.y() ? p1.y() : p2.y();
338 sensor_msgs::CameraInfoPtr out_info = boost::make_shared<sensor_msgs::CameraInfo>(*camera_info_);
339 int binning_x = std::max((
int)camera_info_->binning_x, 1);
340 int binning_y = std::max((
int)camera_info_->binning_y, 1);
341 out_info->binning_x = binning_x * 1;
342 out_info->binning_y = binning_y * 1;
364 int max_x =
ui_.image_frame->width() - 2 *
ui_.image_frame->frameWidth();
367 int max_y =
ui_.image_frame->height() - 2 *
ui_.image_frame->frameWidth();
369 p.setX(std::min(std::max(p.x(),min_x),max_x));
370 p.setY(std::min(std::max(p.y(),min_y),max_y));
375 ui_.max_range_double_spin_box->setEnabled(!checked);
396 if (img->encoding ==
"CV_8UC3")
400 }
else if (img->encoding ==
"8UC1") {
403 }
else if (img->encoding ==
"16UC1" || img->encoding ==
"32FC1") {
408 if (
ui_.dynamic_range_check_box->isChecked())
418 cv::Mat img_scaled_8u;
422 qWarning(
"ImageCropper.callback_image() could not convert image from '%s' to 'rgb8' (%s)", img->encoding.c_str(), e.what());
437 ui_.image_frame->setInnerFrameMinimumSize(QSize(80, 60));
438 ui_.image_frame->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
439 widget_->setMinimumSize(QSize(80, 60));
440 widget_->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
sensor_msgs::Image::ConstPtr sens_msg_image_
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
image_transport::CameraSubscriber subscriber_
QSizeF selection_size_rect_
virtual void selectTopic(const QString &topic)
virtual void onInTopicChanged(int index)
CameraSubscriber subscribeCamera(const std::string &base_topic, uint32_t queue_size, const CameraSubscriber::Callback &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
virtual void onDynamicRange(bool checked)
uint32_t getNumSubscribers() const
virtual QList< QString > getTopicList(const QSet< QString > &message_types, const QList< QString > &transports)
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void addWidget(QWidget *widget)
std::vector< TopicInfo > V_TopicInfo
CameraPublisher advertiseCamera(const std::string &base_topic, uint32_t queue_size, bool latch=false)
virtual bool eventFilter(QObject *watched, QEvent *event)
virtual void onSelectionFinished(QPoint p1, QPoint p2)
std::vector< std::string > getDeclaredTransports() const
virtual void callbackImage(const sensor_msgs::Image::ConstPtr &msg, const sensor_msgs::CameraInfoConstPtr &ci)
image_transport::CameraPublisher publisher_
virtual void onSelectionInProgress(QPoint p1, QPoint p2)
virtual void initPlugin(qt_gui_cpp::PluginContext &context)
void setValue(const QString &key, const QVariant &value)
virtual void onRemoveSelection()
virtual void shutdownPlugin()
virtual void saveSettings(qt_gui_cpp::Settings &plugin_settings, qt_gui_cpp::Settings &instance_settings) const
virtual void onOutTopicChanged()
ros::NodeHandle & getNodeHandle() const
Ui::ImageCropperWidget ui_
virtual void updateTopicList()
virtual void restoreSettings(const qt_gui_cpp::Settings &plugin_settings, const qt_gui_cpp::Settings &instance_settings)
QPointF selection_top_left_
virtual void publishCrop()
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
QPointF selection_top_left_rect_
sensor_msgs::CameraInfoConstPtr camera_info_
virtual void enforceSelectionConstraints(QPoint &p)