YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: LGPL-2.1-or-later
4 */
5
6#define _USE_MATH_DEFINES
7
8#include <iostream>
9#include <iomanip>
10#include <sstream>
11#include <fstream>
12#include <string>
13#include <cstdio>
14#include <limits>
15#include <cmath>
16#include <opencv2/opencv.hpp>
17#include <vector>
18
19#include <yarp/dev/Drivers.h>
20#include <yarp/os/Network.h>
21#include <yarp/os/Bottle.h>
23#include <yarp/os/Time.h>
24#include <yarp/os/Log.h>
26#include <yarp/os/LogStream.h>
27#include <yarp/sig/Image.h>
29
30using namespace yarp::os;
31using namespace yarp::sig;
32
33const cv::Scalar color_bwhite (200, 200, 255);
34const cv::Scalar color_white (255, 255, 255);
35const cv::Scalar color_red (0, 0, 255);
36const cv::Scalar color_yellow (0, 255, 255);
37const cv::Scalar color_black (0, 0, 0);
38const cv::Scalar color_gray (100, 100, 100);
39
41{
42 double interval_time = 0;
43 double copy_time = 0;
45
46void drawImageExtraStuff(cv::Mat& img)
47{
48 //cvLine(img,cvPoint(0,0),cvPoint(img->width,img->height),color_black);
49
50 char buff[20];
51 snprintf(buff, 20, "%5.3f", stats.interval_time);
52 cv::putText(img, buff, cv::Point(20, 20), cv::FONT_HERSHEY_SIMPLEX, 0.4, cv::Scalar(90, 90, 90), 1, cv::LINE_AA);
53}
54
56{
57 yInfo() << "Available options:";
58 yInfo() << "--stats display statistics about the recevied iamges";
59 yInfo() << "--remote <portname> the port to which the gui connects to";
60 yInfo() << "--local <portname> the name of the port opened by the gui";
61 yInfo() << "--carrier <carriername> the communication protocol used to connect to the remote port";
62 yInfo() << "--record_filename <filename> the name of the output file";
63 yInfo() << "--record_start automatically start recording on receiving the first frame (or press `w` runtime)";
64 yInfo() << "--record_fps the framerate of the output file";
65 yInfo() << "--record_codec the codec used to save the file";
66 yInfo() << "--layered";
67}
68
69int main(int argc, char* argv[])
70{
72
74 rf.setDefaultConfigFile("yarpopencvdisplay.ini");
75 rf.configure(argc, argv);
76 if (rf.check("help")) {
78 return 0;
79 }
80
81 std::string filename = rf.check("record_filename", Value(""), "filename e.g. output.avi").asString();
82 std::string codec_s = rf.check("record_codec", Value("MJPG"), "codec (max 4 chars, e.g. MJPG)").asString();
83 if (codec_s.size() > 4)
84 {
85 yInfo() << "Invalid codec. Should be e 4 chars string, e.g. MJPG, DIVX, MP4V etc.";
86 return 0;
87 }
88 bool recording = rf.check("record_start", Value(false), "automatically start recording on receiving the first frame").asBool();
89 int fps = rf.check("record_fps", Value(30), "fps of the output video file").asInt32();
90 if (!filename.empty())
91 {
92 yInfo() << "Output file will be stored:" << filename << "(fps:" << fps << ", codec:" << codec_s << ")";
93 if (recording)
94 {
95 yInfo() << "record_start option found. Recoding will start on first received frame";
96 }
97 }
98
99 bool verbose = rf.check("stats", Value(false), "verbose stats [0/1]").asBool();
100 std::string remote = rf.check("remote", Value(""), "remote port name").asString();
101 std::string carrier = rf.check("carrier", Value("fast_tcp"), "carrier name").asString();
102 std::string local = rf.check("local", Value("/yarpopencvdisplay:i"), "local port name").asString();
103 bool layered = rf.check("layered", Value(false), "set if the input port will receive a layered image or not").asBool();
104 size_t visible_layers = 10;
105
106 yInfo() << "yarpopencvdisplay ready. Press ESC to quit.";
107
108 yarp::os::Contactable* inputPort = nullptr;
109 if (!layered)
110 {
112 }
113 else
114 {
116 }
117
118 if (inputPort->open(local) == false)
119 {
120 yError() << "Failed to open port" << local;
121 return 0;
122 }
123 else
124 {
125 if (layered)
126 {
127 yInfo() << "Opened LAYERED port:" << local;
128 }
129 else
130 {
131 yInfo() << "Opened port:" << local;
132 }
133 }
134
135 if (!remote.empty()) {
136 if (yarp::os::Network::connect(remote, local, carrier)) {
137 yInfo() << "Successfully connected to port:" << remote;
138 } else {
139 yError() << "Failed to connect to port:" << remote;
140 return 0;
141 }
142 } else
143 {
144 yInfo() << "Waiting for port connection...";
145 }
146
147 std::string window_name = "yarpopencvdisplay: " + local;
148 cv::Mat frame;
149 cv::namedWindow(window_name, cv::WINDOW_AUTOSIZE);
150 cv::VideoWriter videowriter;
151
152 bool exit = false;
153
154
155 FlexImage* fl = nullptr;
157
158 while(!exit)
159 {
160 //Receive image and draw
161 {
162 if (layered)
163 {
165 yarp::sig::LayeredImage* ly = ip->read(false);
166 if (ly)
167 {
168 if (fl)
169 {
170 delete fl;
171 fl = nullptr;
172 }
173 for (size_t i = 0; i < ly->layers.size(); i++)
174 {
175 if (i < visible_layers)
176 {
177 ly->layers[i].enable = true;
178 }
179 else
180 {
181 ly->layers[i].enable = false;
182 }
183 }
184 fl = new FlexImage(*ly);
185 imgdata = (reinterpret_cast<yarp::sig::ImageOf<yarp::sig::PixelRgb>*>(fl));
186 }
187 }
188 else
189 {
192 if (ir)
193 {
194 imgdata = ir;
195 }
196 }
197
198 //if received a new frame, then draw/save it
199 if (imgdata!=nullptr)
200 {
201 static double old = yarp::os::Time::now();
202 double now = yarp::os::Time::now();
203 stats.interval_time = now - old;
205
206 //if this is first received frame, allocate a buffer on the specific size
207 if (frame.empty())
208 {
209 yDebug() << "First frame received with size" << imgdata->width() << imgdata->height();
210 //create the buffer for the frame
211 frame = cv::Mat(imgdata->width(), imgdata->height(), CV_8UC3);
212 //if optionally requested to create an avi file, create the file
213 if (filename.empty() == false)
214 {
215 int codec = cv::VideoWriter::fourcc(codec_s[0], codec_s[1], codec_s[2], codec_s[3]);
216 cv::Size frame_size(imgdata->width(), imgdata->height());
217 bool ret = videowriter.open(filename.c_str(), codec, fps, frame_size, true);
218 if (!ret || videowriter.isOpened() == false)
219 {
220 yError("Unable to open the output file");
221 return -1;
222 }
223 }
224 }
225 //you also need to realloc the buffer if the received frame changed size
226 else if (frame.cols != (int)imgdata->width() || frame.rows != (int)imgdata->height())
227 {
228 yDebug() << "Steam has received a frame with different size" << imgdata->width() << imgdata->height();
229 frame = cv::Mat(imgdata->height(), imgdata->width(), CV_8UC3);
230 }
231
232 //copy the data from the yarp structure 'imgdata' to the opencv structure 'frame'
233 double a = yarp::os::Time::now();
234 for (size_t y = 0; y < imgdata->height(); y++) {
235 for (size_t x = 0; x < imgdata->width(); x++) {
236 PixelRgb& yarpPixel = imgdata->pixel(x, y);
237 frame.at<cv::Vec3b>(y, x) = cv::Vec3b(yarpPixel.b, yarpPixel.g, yarpPixel.r);
238 }
239 }
240
241 //add stats to frame
242 double b = yarp::os::Time::now();
243 stats.copy_time = b - a;
244 if (verbose)
245 {
246 yDebug("copytime: %5.3f frameintervale %5.3f", stats.copy_time, stats.interval_time);
247 drawImageExtraStuff(frame);
248 }
249
250 //save to file
251 if (recording)
252 {
253 videowriter.write(frame);
254 }
255
256 //draw
257 cv::imshow(window_name, frame);
258 }
259 }
260
262
263 //if ESC is pressed, exit.
264 int keypressed = cv::waitKey(2); //wait 2ms. Lower values do not work under Linux
265 keypressed &= 0xFF; //this mask is required in Linux systems
266 if (keypressed == 27)
267 {
268 exit = true;
269 }
270 if(keypressed == 'w')
271 {
272 recording = (!recording);
273 if (recording) {
274 yInfo("recording is now ON");
275 } else {
276 yInfo("recording is now OFF");
277 }
278 }
279 if (keypressed == 'l') {
281 if (visible_layers > 10) {
282 visible_layers = 0;
283 yInfo("Changed max number of visible Layers: %d", visible_layers);
284 }
285 }
286 if(keypressed == 'v' )
287 {
288 verbose= (!verbose);
289 if (verbose) {
290 yInfo("verbose mode is now ON");
291 } else {
292 yInfo("verbose mode is now OFF");
293 }
294 }
295 }
296
297 inputPort->close();
298 delete inputPort;
299
300 cv::destroyAllWindows();
301
302 if (videowriter.isOpened())
303 {
305 }
306}
bool ret
#define yInfo(...)
Definition Log.h:319
#define yError(...)
Definition Log.h:361
#define yDebug(...)
Definition Log.h:275
A mini-server for performing network communication in the background.
void release(void *handle) override
Return control to YARP of an object previously taken control of with the acquire() method.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
T * read(bool shouldWait=true) override
Read an available object from the port.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
An abstract port.
Definition Contactable.h:28
virtual void close()=0
Stop port activity.
virtual bool open(const std::string &name)=0
Start port operation, with a specific name, with automatically-chosen network parameters.
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition Network.cpp:682
Utilities for manipulating the YARP network, including initialization and shutdown.
Definition Network.h:706
Helper class for finding config files and other external resources.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
bool setDefaultConfigFile(const std::string &fname)
Provide a default value for the configuration file (can be overridden from command line with the –fro...
static void delaySystem(double seconds)
A single value (typically within a Bottle).
Definition Value.h:43
Image class with user control of representation details.
Definition Image.h:363
Typed image class.
Definition Image.h:605
A Layered Image, composed by a background and multiple layers.
const CvScalar color_red
Definition main.cpp:44
const CvScalar color_gray
Definition main.cpp:47
const CvScalar color_yellow
Definition main.cpp:45
const CvScalar color_white
Definition main.cpp:43
const CvScalar color_bwhite
Definition main.cpp:42
const CvScalar color_black
Definition main.cpp:46
int main(int argc, char *argv[])
Definition main.cpp:69
void display_help()
Definition main.cpp:55
struct stats_struct stats
void drawImageExtraStuff(cv::Mat &img)
Definition main.cpp:46
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition Time.cpp:121
An interface to the operating system, including Port based communication.
@ YARP_CLOCK_SYSTEM
Definition Time.h:28
The main, catch-all namespace for YARP.
Definition dirs.h:16
double copy_time
Definition main.cpp:43
double interval_time
Definition main.cpp:42