20
20
#include < filesystem>
21
21
#include < iostream>
22
22
23
+ using std::placeholders::_1;
24
+ using std::placeholders::_2;
25
+
23
26
void setFormatDate (QLabel * line, double time)
24
27
{
25
28
char buffer[128 ];
@@ -47,13 +50,13 @@ AutowareScreenCapturePanel::AutowareScreenCapturePanel(QWidget * parent)
47
50
// video capture
48
51
auto * video_cap_layout = new QHBoxLayout;
49
52
{
50
- capture_to_mp4_button_ptr_ = new QPushButton (" Capture To Video " );
53
+ capture_to_mp4_button_ptr_ = new QPushButton (" Capture Screen " );
51
54
connect (capture_to_mp4_button_ptr_, SIGNAL (clicked ()), this , SLOT (onClickVideoCapture ()));
52
55
capture_hz_ = new QSpinBox ();
53
- capture_hz_->setRange (1 , 2 );
54
- capture_hz_->setValue (1 );
56
+ capture_hz_->setRange (1 , 10 );
57
+ capture_hz_->setValue (10 );
55
58
capture_hz_->setSingleStep (1 );
56
- connect (capture_hz_, SIGNAL (valueChanged (int )), this , SLOT (onRateChanged (int )));
59
+ connect (capture_hz_, SIGNAL (valueChanged (int )), this , SLOT (onRateChanged ()));
57
60
// video cap layout
58
61
video_cap_layout->addWidget (capture_to_mp4_button_ptr_);
59
62
video_cap_layout->addWidget (capture_hz_);
@@ -74,11 +77,25 @@ AutowareScreenCapturePanel::AutowareScreenCapturePanel(QWidget * parent)
74
77
state_ = State::WAITING_FOR_CAPTURE;
75
78
}
76
79
80
+ void AutowareScreenCapturePanel::onCaptureTrigger (
81
+ [[maybe_unused]] const std::shared_ptr<std_srvs::srv::Trigger::Request> req,
82
+ const std::shared_ptr<std_srvs::srv::Trigger::Response> res)
83
+ {
84
+ onClickVideoCapture ();
85
+ res->success = true ;
86
+ res->message = stateToString (state_);
87
+ }
88
+
77
89
void AutowareScreenCapturePanel::onInitialize ()
78
90
{
79
- rviz_ros_node_ = getDisplayContext ()->getRosNodeAbstraction ();
91
+ raw_node_ = this ->getDisplayContext ()->getRosNodeAbstraction ().lock ()->get_raw_node ();
92
+ capture_service_ = raw_node_->create_service <std_srvs::srv::Trigger>(
93
+ " /debug/service/capture_screen" ,
94
+ std::bind (&AutowareScreenCapturePanel::onCaptureTrigger, this , _1, _2));
80
95
}
81
96
97
+ void AutowareScreenCapturePanel::onRateChanged () {}
98
+
82
99
void AutowareScreenCapturePanel::onClickScreenCapture ()
83
100
{
84
101
const std::string time_text = " capture/" + ros_time_label_->text ().toStdString ();
@@ -87,24 +104,24 @@ void AutowareScreenCapturePanel::onClickScreenCapture()
87
104
return ;
88
105
}
89
106
90
- void AutowareScreenCapturePanel::convertPNGImagesToMP4 () {
91
- cv::VideoCapture capture (root_folder_+ " /%06d.png" , cv::CAP_IMAGES);
107
+ void AutowareScreenCapturePanel::convertPNGImagesToMP4 ()
108
+ {
109
+ cv::VideoCapture capture (root_folder_ + " /%06d.png" , cv::CAP_IMAGES);
92
110
if (!capture.isOpened ()) {
93
111
return ;
94
112
}
95
- int fourcc = cv::VideoWriter::fourcc (' m' , ' p' , ' 4' , ' v' ); // mp4
113
+ int fourcc = cv::VideoWriter::fourcc (' m' , ' p' , ' 4' , ' v' ); // mp4
96
114
cv::VideoWriter writer;
97
- cv::Size size = cv::Size (1280 ,720 );
98
- writer.open (" capture/" + root_folder_ + " .mp4" , fourcc, 1 , size);
99
- cv::Mat image, resized ;
115
+ cv::Size size = cv::Size (1280 , 720 );
116
+ writer.open (" capture/" + root_folder_ + " .mp4" , fourcc, capture_hz_-> value () , size);
117
+ cv::Mat image;
100
118
while (true ) {
101
119
capture >> image;
102
120
if (image.empty ()) {
103
121
break ;
104
122
}
105
123
// need to resize for fixed frame video
106
- cv::resize (image,resized,size);
107
- writer << resized;
124
+ writer << image;
108
125
cv::waitKey (0 );
109
126
}
110
127
capture.release ();
@@ -116,6 +133,18 @@ void AutowareScreenCapturePanel::convertPNGImagesToMP4() {
116
133
void AutowareScreenCapturePanel::onClickVideoCapture ()
117
134
{
118
135
const int clock = static_cast <int >(1e3 / capture_hz_->value ());
136
+ try {
137
+ const QWidgetList top_level_widgets = QApplication::topLevelWidgets ();
138
+ for (QWidget * widget : top_level_widgets) {
139
+ QMainWindow * main_window_candidate = qobject_cast<QMainWindow *>(widget);
140
+ if (main_window_candidate) {
141
+ main_window_ = main_window_candidate;
142
+ }
143
+ }
144
+ } catch (...) {
145
+ return ;
146
+ }
147
+ if (!main_window_) return ;
119
148
switch (state_) {
120
149
case State::WAITING_FOR_CAPTURE:
121
150
// initialize setting
@@ -129,16 +158,12 @@ void AutowareScreenCapturePanel::onClickVideoCapture()
129
158
capture_timer_->start (clock );
130
159
state_ = State::CAPTURING;
131
160
break ;
132
- case State::CAPTURING:
133
- {
134
- capture_timer_->stop ();
135
- }
161
+ case State::CAPTURING: {
162
+ capture_timer_->stop ();
163
+ }
136
164
capture_to_mp4_button_ptr_->setText (" writing to video" );
137
165
capture_to_mp4_button_ptr_->setStyleSheet (" background-color: #FFFF00;" );
138
166
convertPNGImagesToMP4 ();
139
- state_ = State::FINALIZED;
140
- break ;
141
- case State::FINALIZED:
142
167
capture_to_mp4_button_ptr_->setText (" waiting for capture" );
143
168
capture_to_mp4_button_ptr_->setStyleSheet (" background-color: #00FF00;" );
144
169
state_ = State::WAITING_FOR_CAPTURE;
@@ -152,15 +177,42 @@ void AutowareScreenCapturePanel::onTimer()
152
177
std::stringstream count_text;
153
178
count_text << std::setw (6 ) << std::setfill (' 0' ) << counter_;
154
179
const std::string file = root_folder_ + " /" + count_text.str () + " .png" ;
155
- getDisplayContext ()->getViewManager ()->getRenderPanel ()->getRenderWindow ()->captureScreenShot (
156
- file);
180
+ if (!main_window_) return ;
181
+ try {
182
+ // this is deprecated but only way to capture nicely
183
+ QPixmap original_pixmap = QPixmap::grabWindow (main_window_->winId ());
184
+ QString format = " png" ;
185
+ QString file_name = QString::fromStdString (file);
186
+ if (!file_name.isEmpty ())
187
+ original_pixmap.scaled (width_, height_).save (file_name, format.toLatin1 ().constData ());
188
+ } catch (std::exception & e) {
189
+ std::cout << e.what () << std::endl;
190
+ }
157
191
counter_++;
158
192
}
159
193
160
194
void AutowareScreenCapturePanel::update ()
161
195
{
162
- setFormatDate (
163
- ros_time_label_, rviz_ros_node_.lock ()->get_raw_node ()->get_clock ()->now ().seconds ());
196
+ setFormatDate (ros_time_label_, raw_node_->get_clock ()->now ().seconds ());
197
+ }
198
+
199
+ void AutowareScreenCapturePanel::save (rviz_common::Config config) const
200
+ {
201
+ Panel::save (config);
202
+ config.mapSetValue (" width" , &width_);
203
+ config.mapSetValue (" height" , &height_);
204
+ }
205
+
206
+ void AutowareScreenCapturePanel::load (const rviz_common::Config & config)
207
+ {
208
+ Panel::load (config);
209
+ if (!config.mapGetFloat (" width" , &width_)) width_ = 1280 ;
210
+ if (!config.mapGetFloat (" height" , &height_)) height_ = 720 ;
211
+ }
212
+
213
+ AutowareScreenCapturePanel::~AutowareScreenCapturePanel ()
214
+ {
215
+ std::filesystem::remove_all (root_folder_);
164
216
}
165
217
166
218
#include < pluginlib/class_list_macros.hpp>
0 commit comments