7 nh_(
std::make_shared<
ros::NodeHandle>()),
13 qRegisterMetaType<QMessageBox::Icon>();
18 QVBoxLayout *layout =
new QVBoxLayout();
25 QHBoxLayout *buttons(
new QHBoxLayout);
29 connect(
start_stop_, &QPushButton::clicked,
this, [=]()
52 QLabel *refresh_label(
new QLabel(
"Refresh frequency:"));
53 graph_refresh_frequency_->setToolTip(
"Change the histogram display frequency");
54 refresh_label->setToolTip(graph_refresh_frequency_->toolTip());
56 graph_refresh_frequency_->addItem(
"1 Hz");
57 graph_refresh_frequency_->addItem(
"2 Hz");
58 graph_refresh_frequency_->addItem(
"5 Hz");
59 graph_refresh_frequency_->addItem(
"10 Hz");
60 graph_refresh_frequency_->addItem(
"20 Hz");
61 graph_refresh_frequency_->addItem(
"50 Hz");
62 graph_refresh_frequency_->setCurrentIndex(3);
64 connect(graph_refresh_frequency_, qOverload<int>(&QComboBox::currentIndexChanged),
this, &Panel::configChanged);
65 connect(graph_refresh_frequency_, qOverload<int>(&QComboBox::currentIndexChanged),
this, [=](
int index)
109 bars_ =
new QCPBars(custom_plot_->xAxis, custom_plot_->yAxis);
141 for (
int i(0); i < 255; ++i)
144 custom_plot_->yAxis->rescale();
145 custom_plot_->xAxis->setRange(0,
ticks_.back());
149 QLabel *bins_selection_label =
new QLabel(
"Bins selection:");
150 bins_selection_->setToolTip(
"Change the bins number used to compute the histogram");
165 connect(
bins_selection_, qOverload<int>(&QComboBox::currentIndexChanged),
this, &Panel::configChanged);
166 connect(
bins_selection_, qOverload<int>(&QComboBox::currentIndexChanged),
this, [=](
const int index)
235 QPushButton *topic(
new QPushButton(
"Topic"));
236 topic->setToolTip(
"Select the image topic");
239 buttons->addWidget(topic);
240 buttons->addStretch(1);
242 buttons->addStretch(1);
243 buttons->addWidget(refresh_label);
244 buttons->addWidget(graph_refresh_frequency_);
245 buttons->addStretch(1);
246 buttons->addWidget(bins_selection_label);
249 layout->addLayout(buttons);
250 layout->addWidget(custom_plot_);
299 std::vector<std::string> allowed_topics;
300 allowed_topics.emplace_back(
"sensor_msgs/Image");
302 std::deque<std::shared_ptr<TopicData>> displayed_topics;
307 Q_EMIT
displayMessageBox(
"No supported topic",
"Error with topics, no supported topics found.",
"",
308 QMessageBox::Icon::Warning);
343 catch (
const cv::Exception &e)
345 std::string error(
"Error converting the image: ");
352 if (cv_image->image.channels() == 1)
358 for (
int i(0); i <
ticks_.size(); ++i)
361 if (cv_image->image.channels() == 1)
363 std::vector<cv::Mat> input_image = {cv_image->image};
365 cv::Mat_<float> tmp_mat;
366 cv::OutputArray histogram(tmp_mat);
370 if (cv_image->image.depth() == CV_8U)
372 std::vector<float> ranges = {0, 256};
373 cv::calcHist(input_image, {0}, cv::Mat(), histogram, histogram_size, ranges);
374 for (
int i(0); i <
ticks_.size(); ++i)
376 data_.push_back(histogram.getMatRef().at<
float>(i));
381 else if (cv_image->image.depth() == CV_16U)
383 std::vector<float> ranges = {0, 65536};
384 cv::calcHist(input_image, {0}, cv::Mat(), histogram, histogram_size, ranges);
385 for (
int i(0); i <
ticks_.size(); ++i)
387 data_.push_back(histogram.getMatRef().at<
float>(i));
395 "Image format is not supported: only CV_8U and CV_16U images are supported");
399 else if (cv_image->image.channels() == 3)
401 cv::Mat_<float> bgr[3];
402 split(cv_image->image, bgr);
403 std::vector<cv::Mat> input_image_b = {bgr[0]};
404 std::vector<cv::Mat> input_image_g = {bgr[1]};
405 std::vector<cv::Mat> input_image_r = {bgr[2]};
407 cv::Mat_<float> tmp_mat_b;
408 cv::Mat_<float> tmp_mat_g;
409 cv::Mat_<float> tmp_mat_r;
410 cv::OutputArray blue_histogram(tmp_mat_b);
411 cv::OutputArray green_histogram(tmp_mat_g);
412 cv::OutputArray red_histogram(tmp_mat_r);
418 if (cv_image->image.depth() == CV_8U)
420 std::vector<float> ranges = {0, 256};
421 cv::calcHist(input_image_b, {0}, cv::Mat(), blue_histogram, histogram_size, ranges);
422 cv::calcHist(input_image_g, {0}, cv::Mat(), green_histogram, histogram_size, ranges);
423 cv::calcHist(input_image_r, {0}, cv::Mat(), red_histogram, histogram_size, ranges);
425 for (
int i(0); i <
ticks_.size(); ++i)
438 else if (cv_image->image.depth() == CV_16U)
440 std::vector<float> ranges = {0, 65536};
441 cv::calcHist(input_image_b, {0}, cv::Mat(), blue_histogram, histogram_size, ranges);
442 cv::calcHist(input_image_g, {0}, cv::Mat(), green_histogram, histogram_size, ranges);
443 cv::calcHist(input_image_r, {0}, cv::Mat(), red_histogram, histogram_size, ranges);
445 for (
int i(0); i <
ticks_.size(); ++i)
461 "Image format is not supported: only CV_8U and CV_16U images are supported");
468 "Image depth is not 1 or 3 : this format is not supported. Only grayscale or color images are supported.");
480 if (config.
mapGetString(objectName() +
"_subscriber", &tmp_str))
483 if (config.
mapGetInt(objectName() +
"_graph_refresh_frequency", &tmp_int))
486 if (config.
mapGetInt(objectName() +
"_bins_selection", &tmp_int))
499 const QString message,
500 const QString info_msg,
501 const QMessageBox::Icon icon)
503 const bool old(isEnabled());
504 Q_EMIT setEnabled(
false);
506 msg_box.setWindowTitle(title);
507 msg_box.setText(message);
508 msg_box.setInformativeText(info_msg);
509 msg_box.setIcon(icon);
510 msg_box.setStandardButtons(QMessageBox::Ok);
512 Q_EMIT setEnabled(old);
void setBrush(const QBrush &brush)
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes) ...
void setWidth(double width)
std::shared_ptr< ros::NodeHandle > nh_
std::string getTopic() const
void setWidthType(WidthType widthType)
#define ROS_ERROR_STREAM_NAMED(name, args)
void setInteractions(const QCP::Interactions &interactions)
virtual QString getName() const
void subscribeToTopicSlot(const QString topic)
std::deque< std::shared_ptr< TopicData > > displayed_topics_
QVector< double > blue_channel_data_
virtual void save(rviz::Config config) const
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint)
void setData(QSharedPointer< QCPBarsDataContainer > data)
Q_SLOT void setRange(const QCPRange &range)
void imageCallback(const sensor_msgs::ImageConstPtr &msg)
virtual void save(Config config) const
bool mapGetString(const QString &key, QString *value_out) const
QVector< double > red_channel_data_
std::mutex data_ticks_mutex_
void mapSetValue(const QString &key, QVariant value)
QCustomPlot * custom_plot_
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
QComboBox * graph_refresh_frequency_
virtual void setName(const QString &name)
void setAntialiased(bool enabled)
QVector< double > green_channel_data_
QComboBox * bins_selection_
void setPen(const QPen &pen)
void displayMessageBox(const QString, const QString, const QString, const QMessageBox::Icon)
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
double histogram_max_counter_
void subscribeToTopic(const QString)
HistogramPanel(QWidget *parent=nullptr)
ros::master::V_TopicInfo supported_topics_
virtual ~HistogramPanel()
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom, QCPAxisRect::setRangeZoomAxes)
A plottable representing a bar chart in a plot.
std::atomic< bool > updating_
virtual void load(const Config &config)
bool mapGetInt(const QString &key, int *value_out) const
void displayMessageBoxHandler(const QString title, const QString text, const QString info="", const QMessageBox::Icon icon=QMessageBox::Icon::Information)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
QPushButton * start_stop_
QTimer * graph_refresh_timer_
void topicSelectionSlot()
virtual void load(const rviz::Config &config)