33 constexpr
char num[12][16]
119 constexpr
size_t num_width = 3;
120 constexpr
size_t num_height = 5;
128 bool ok = command.
read(connection);
138 reply.
addString(
"set_image <file_name>/off");
139 reply.
addString(
"available modes: ball, line, grid, size, rand, none, time");
161 w = background.width();
162 h = background.height();
173 else if (command.
get(0).
asString() ==
"set_topIsLow")
204 reply.
addString(
"Unknown command. Type 'help'.");
208 if (returnToSender !=
nullptr)
210 reply.
write(*returnToSender);
223 m_rpcPortName = config.
check(
"fakeFrameGrabber_rpc_port",
yarp::os::Value(
"/fakeFrameGrabber/rpc"),
"rpc port for the fakeFrameGrabber").asString();
225 "desired width of test image").asInt32();
227 "desired height of test image").asInt32();
228 horizontalFov=config.
check(
"horizontalFov",
Value(1.0),
229 "desired horizontal fov of test image").asFloat64();
230 verticalFov=config.
check(
"verticalFov",
Value(2.0),
231 "desired vertical fov of test image").asFloat64();
233 "mirroring disabled by default").asBool();
235 "syncronize producer and consumer, so that all images are used once and only once").asBool();
237 "explicitly set the topIsLow field in the images").asBool();
238 intrinsic.put(
"physFocalLength",config.
check(
"physFocalLength",
Value(3.0),
"Physical focal length of the fakeFrameGrabber").asFloat64());
239 intrinsic.put(
"focalLengthX",config.
check(
"focalLengthX",
Value(4.0),
"Horizontal component of the focal length of the fakeFrameGrabber").asFloat64());
240 intrinsic.put(
"focalLengthY",config.
check(
"focalLengthY",
Value(5.0),
"Vertical component of the focal length of the fakeFrameGrabber").asFloat64());
241 intrinsic.put(
"principalPointX",config.
check(
"principalPointX",
Value(6.0),
"X coordinate of the principal point of the fakeFrameGrabber").asFloat64());
242 intrinsic.put(
"principalPointY",config.
check(
"principalPointY",
Value(7.0),
"Y coordinate of the principal point of the fakeFrameGrabber").asFloat64());
246 intrinsic.put(
"rectificationMatrix",config.
check(
"rectificationMatrix",*retM,
"Matrix that describes the lens' distortion(fake)"));
249 intrinsic.put(
"distortionModel",config.
check(
"distortionModel",
Value(
"FishEye"),
"Reference to group of parameters describing the distortion model of the camera").asString());
250 intrinsic.put(
"k1",config.
check(
"k1",
Value(8.0),
"Radial distortion coefficient of the lens(fake)").asFloat64());
251 intrinsic.put(
"k2",config.
check(
"k2",
Value(9.0),
"Radial distortion coefficient of the lens(fake)").asFloat64());
252 intrinsic.put(
"k3",config.
check(
"k3",
Value(10.0),
"Radial distortion coefficient of the lens(fake)").asFloat64());
253 intrinsic.put(
"t1",config.
check(
"t1",
Value(11.0),
"Tangential distortion of the lens(fake)").asFloat64());
254 intrinsic.put(
"t2",config.
check(
"t2",
Value(12.0),
"Tangential distortion of the lens(fake)").asFloat64());
261 configurations.push_back(conf1);
268 configurations.push_back(conf2);
275 configurations.push_back(conf3);
278 if (config.
check(
"freq", val,
"rate of test images in Hz")) {
281 }
else if (config.
check(
"period", val,
282 "period of test images in seconds")) {
290 mode = config.
check(
"mode",
292 "bouncy [ball], scrolly [line], grid [grid], grid multisize [size], random [rand], none [none], time test[time]").asVocab32();
294 if (config.
check(
"src")) {
298 "background image to use, if any").asString())) {
301 if (background.width()>0) {
302 if (config.
check(
"width") || config.
check(
"height")) {
303 yCWarning(FAKEFRAMEGRABBER,
"width and height option are ignored when passing a background image");
305 w = background.width();
306 h = background.height();
311 add_timestamp = config.
check(
"timestamp",
"should write the timestamp in the first bytes of the image");
313 add_noise = config.
check(
"noise",
"Should add noise to the image (uses snr)");
315 snr =
yarp::conf::clamp(config.
check(
"snr",
Value(default_snr),
"Signal noise ratio ([0.0-1.0] default 0.5)").asFloat64(), 0.0, 1.0);
317 use_bayer = config.
check(
"bayer",
"should emit bayer test image?");
318 use_mono = config.
check(
"mono",
"should emit a monochrome image?");
319 use_mono = use_mono||use_bayer;
323 "Test grabber period %g / freq %g , mode [%s]",
329 "Test grabber period %g / freq [inf], mode [%s]",
337 for (
auto& buff : buffs) {
342 if (!m_rpcPort.open(m_rpcPortName.c_str()))
344 yCError(FAKEFRAMEGRABBER,
"Failed to open port %s", m_rpcPortName.c_str());
345 yCError(FAKEFRAMEGRABBER,
"Do you have multiple FakeFrameGrabber devices running?");
346 yCError(FAKEFRAMEGRABBER,
"If yes, use the `fakeFrameGrabber_rpc_port` parameter to set a different name for each of them");
349 m_rpcPort.setReader(*
this);
363 double dt = period-(
now-prev);
391 configurations=this->configurations;
408 horizontalFov=this->horizontalFov;
409 verticalFov=this->verticalFov;
414 this->horizontalFov=horizontalFov;
415 this->verticalFov=verticalFov;
420 intrinsic=this->intrinsic;
435 while (!isStopping()) {
436 for (
size_t i = 0; i < 2 && !isStopping(); ++i) {
438 std::unique_lock<std::mutex> lk(mutex[i]);
439 createTestImage(buffs[i], buff_ts[i]);
443 curr_buff_mutex.lock();
445 curr_buff_mutex.unlock();
448 std::unique_lock<std::mutex> lk(mutex[i]);
449 img_consumed_cv[i].wait(lk, [&]{
if (img_ready[i]) {img_ready_cv[i].notify_one();}
return (isStopping() || img_consumed[i]);});
453 img_ready[i] =
false;
454 img_consumed[i] =
false;
455 createTestImage(buffs[i], buff_ts[i]);
457 img_ready_cv[i].notify_all();
467 for (
size_t i = 0; i < 2; ++i) {
468 std::unique_lock<std::mutex> lk(mutex[i]);
469 img_consumed[i] =
true;
470 img_consumed_cv[i].notify_all();
472 img_ready_cv[i].notify_all();
485 curr_buff_mutex.lock();
486 size_t cb = curr_buff;
487 std::unique_lock<std::mutex> lk(mutex[cb]);
490 curr_buff_mutex.unlock();
491 image.
copy(buffs[cb]);
492 stamp.update(buff_ts[cb]);
494 curr_buff_mutex.lock();
496 size_t cb = curr_buff;
497 std::unique_lock<std::mutex> lk(mutex[cb]);
498 img_ready_cv[cb].wait(lk, [&]{
return (!isRunning() || img_ready[cb]);});
503 image.
copy(buffs[cb]);
504 stamp.update(buff_ts[cb]);
505 img_consumed[cb] =
true;
506 img_consumed_cv[cb].notify_one();
508 curr_buff = (cb + 1) % 2;
509 curr_buff_mutex.unlock();
522 curr_buff_mutex.lock();
523 size_t cb = curr_buff;
524 std::unique_lock<std::mutex> lk(mutex[cb]);
525 curr_buff_mutex.unlock();
527 makeSimpleBayer(buffs[cb], image);
529 image.
copy(buffs[cb]);
531 stamp.update(buff_ts[cb]);
533 curr_buff_mutex.lock();
535 size_t cb = curr_buff;
536 std::unique_lock<std::mutex> lk(mutex[cb]);
537 img_ready_cv[cb].wait(lk, [&]{
return (!isRunning() || img_ready[cb]);});
542 makeSimpleBayer(buffs[cb], image);
544 image.
copy(buffs[cb]);
546 stamp.update(buff_ts[cb]);
547 img_consumed[cb] =
true;
548 img_consumed_cv[cb].notify_one();
550 curr_buff = (cb + 1) % 2;
551 curr_buff_mutex.unlock();
601 void FakeFrameGrabber::printTime(
unsigned char* pixbuf,
size_t pixbuf_w,
size_t pixbuf_h,
size_t x,
size_t y,
char* s,
size_t size)
603 for (
size_t i = 0; i < size; i++)
605 const char* num_p =
nullptr;
607 case '0': num_p = num[0];
break;
608 case '1': num_p = num[1];
break;
609 case '2': num_p = num[2];
break;
610 case '3': num_p = num[3];
break;
611 case '4': num_p = num[4];
break;
612 case '5': num_p = num[5];
break;
613 case '6': num_p = num[6];
break;
614 case '7': num_p = num[7];
break;
615 case '8': num_p = num[8];
break;
616 case '9': num_p = num[9];
break;
617 case ' ': num_p = num[10];
break;
618 case '.': num_p = num[11];
break;
619 default: num_p = num[10];
break;
622 for (
size_t yi = 0; yi < num_height; yi++) {
623 for (
size_t xi = 0; xi < num_width; xi++) {
624 size_t ii = yi * num_width + xi;
625 if (num_p[ii] ==
'*') {
626 for (
size_t r = yi * num_height; r < yi*num_height + num_height; r++) {
627 size_t off = i * (num_height + 20);
628 for (
size_t c = xi * num_height + off; c < xi*num_height + num_height + off; c++) {
629 if (c >= pixbuf_h || r >= pixbuf_w) {
633 unsigned char *pixel = pixbuf;
635 pixel = pixel + offset;
651 t -= (((
t*1000) -
static_cast<int64_t
>(
t*1000)) / 1000);
660 image.
copy(background);
665 static const double start_time =
t;
666 double time =
t - start_time;
667 std::snprintf(txtbuf, 50,
"%.3f", time);
668 int len = strlen(txtbuf);
678 image.
copy(background);
687 int delta_x = (rnd % 5) - 2;
691 int delta_y = (rnd % 5) - 2;
705 size_t ww = image.
width();
706 size_t hh = image.
height();
708 for (
size_t x=0; x<ww; x++) {
709 for (
size_t y=0; y<hh; y++) {
710 double xx = ((double)x)/(ww-1);
711 double yy = ((double)y)/(hh-1);
713 auto r =
static_cast<unsigned char>(0.5 + 255 * xx);
714 auto g =
static_cast<unsigned char>(0.5 + 255 * yy);
715 auto b =
static_cast<unsigned char>(act * 255);
722 case VOCAB_GRID_MULTISIZE:
724 static int count = 0;
728 yCDebug(FAKEFRAMEGRABBER) <<
"size 100, 100";
731 else if (count == 200)
733 yCDebug(FAKEFRAMEGRABBER) <<
"size 200, 100";
736 else if (count == 300)
738 yCDebug(FAKEFRAMEGRABBER) <<
"size 300, 50";
743 size_t ww = w = image.
width();
744 size_t hh = h = image.
height();
746 for (
size_t x = 0; x<ww; x++) {
747 for (
size_t y = 0; y<hh; y++) {
748 double xx = ((double)x) / (ww - 1);
749 double yy = ((double)y) / (hh - 1);
750 bool act = (y == ct);
751 auto r =
static_cast<unsigned char>(0.5 + 255 * xx);
752 auto g =
static_cast<unsigned char>(0.5 + 255 * yy);
753 auto b =
static_cast<unsigned char>(act * 255);
764 image.
copy(background);
768 for (
size_t i=0; i<image.
width(); i++) {
769 image.
pixel(i,ct).
r = 255;
775 static unsigned char r = 128;
776 static unsigned char g = 128;
777 static unsigned char b = 128;
779 size_t ww = image.
width();
780 size_t hh = image.
height();
783 for (
size_t x=0; x<ww; x++) {
784 for (
size_t y=0; y<hh; y++) {
797 image.
copy(background);
811 if (bx>=image.
width()) {
812 bx = image.
width()-1;
816 static const double nsr = 1.0 - snr;
817 for (
size_t x = 0; x < image.
width(); ++x) {
818 for (
size_t y = 0; y < image.
height(); ++y) {
821 static_cast<unsigned char>(image.
pixel(x,y).
r * snr + (rand * nsr * 255)),
822 static_cast<unsigned char>(image.
pixel(x,y).
g * snr + (rand * nsr * 255)),
823 static_cast<unsigned char>(image.
pixel(x,y).
b * snr + (rand * nsr * 255))
831 std::snprintf(ttxt, 50,
"%021.10f", timestamp);
832 image.
pixel(0, 0).
r = ttxt[0] -
'0';
833 image.
pixel(0, 0).
g = ttxt[1] -
'0';
834 image.
pixel(0, 0).
b = ttxt[2] -
'0';
836 image.
pixel(1, 0).
r = ttxt[3] -
'0';
837 image.
pixel(1, 0).
g = ttxt[4] -
'0';
838 image.
pixel(1, 0).
b = ttxt[5] -
'0';
840 image.
pixel(2, 0).
r = ttxt[6] -
'0';
841 image.
pixel(2, 0).
g = ttxt[7] -
'0';
842 image.
pixel(2, 0).
b = ttxt[8] -
'0';
844 image.
pixel(3, 0).
r = ttxt[9] -
'0';
845 image.
pixel(3, 0).
g = ttxt[10] -
'0';
846 image.
pixel(3, 0).
b = ttxt[11] -
'0';
848 image.
pixel(4, 0).
r = ttxt[12] -
'0';
849 image.
pixel(4, 0).
g = ttxt[13] -
'0';
850 image.
pixel(4, 0).
b = ttxt[14] -
'0';
852 image.
pixel(5, 0).
r = ttxt[15] -
'0';
853 image.
pixel(5, 0).
g = ttxt[16] -
'0';
854 image.
pixel(5, 0).
b = ttxt[17] -
'0';
856 image.
pixel(6, 0).
r = ttxt[18] -
'0';
857 image.
pixel(6, 0).
g = ttxt[19] -
'0';
858 image.
pixel(6, 0).
b = ttxt[20] -
'0';
870 bool FakeFrameGrabber::makeSimpleBayer(
876 const size_t w = img.
width();
877 const size_t h = img.
height();
880 for (i = 0; i < h; i++) {
884 for (j = 0; j < w; j++) {
std::default_random_engine randengine
int width() const override
Return the width of each frame.
bool getCameraDescription(CameraDescriptor *camera) override
Get a basic description of the camera hw.
bool getImageCrop(cropType_id_t cropType, yarp::sig::VectorOf< std::pair< int, int >> vertices, yarp::sig::ImageOf< yarp::sig::PixelRgb > &image) override
bool hasFeature(int feature, bool *hasFeature) override
Check if camera has the requested feature (saturation, brightness ...
bool getMode(int feature, FeatureMode *mode) override
Get the current mode for the feature.
bool setFeature(int feature, double value) override
Set the requested feature to a value (saturation, brightness ...
int getRgbWidth() override
Return the width of each frame.
int getRgbHeight() override
Return the height of each frame.
yarp::os::Stamp getLastInputStamp() override
Return the time stamp relative to the last acquisition.
bool setOnePush(int feature) override
Set the requested feature to a value (saturation, brightness ...
bool getRgbResolution(int &width, int &height) override
Get the resolution of the rgb image from the camera.
bool getRgbIntrinsicParam(yarp::os::Property &intrinsic) override
Get the intrinsic parameters of the rgb camera.
bool getActive(int feature, bool *isActive) override
Get the current status of the feature, on or off.
bool getRgbSupportedConfigurations(yarp::sig::VectorOf< yarp::dev::CameraConfig > &configurations) override
Get the possible configurations of the camera.
bool hasOnePush(int feature, bool *hasOnePush) override
Check if the requested feature has the 'onePush' mode.
int height() const override
Return the height of each frame.
bool setMode(int feature, FeatureMode mode) override
Set the requested mode for the feature.
bool hasManual(int feature, bool *hasManual) override
Check if the requested feature has the 'manual' mode.
bool getRgbMirroring(bool &mirror) override
Get the mirroring setting of the sensor.
bool hasAuto(int feature, bool *hasAuto) override
Check if the requested feature has the 'auto' mode.
bool hasOnOff(int feature, bool *HasOnOff) override
Check if the camera has the ability to turn on/off the requested feature.
bool getFeature(int feature, double *value) override
Get the current value for the requested feature.
bool getRgbFOV(double &horizontalFov, double &verticalFov) override
Get the field of view (FOV) of the rgb camera.
bool setRgbMirroring(bool mirror) override
Set the mirroring setting of the sensor.
bool setActive(int feature, bool onoff) override
Set the requested feature on or off.
bool open(yarp::os::Searchable &config) override
Configure with a set of options.
bool setRgbResolution(int width, int height) override
Set the resolution of the rgb image from the camera.
bool setRgbFOV(double horizontalFov, double verticalFov) override
Set the field of view (FOV) of the rgb camera.
void run() override
Main body of the new thread.
void onStop() override
Call-back, called while halting the thread (before join).
bool getImage(yarp::sig::ImageOf< yarp::sig::PixelRgb > &image) override
bool hasRawVideo() override
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
bool close() override
Close the DeviceDriver.
A simple collection of objects that can be described and transmitted in a portable way.
void addVocab32(yarp::conf::vocab32_t x)
Places a vocabulary item in the bottle, at the end of the list.
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
void clear()
Empties the bottle of any objects it contains.
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
An interface for reading from a network connection.
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
An interface for writing to a network connection.
A class for storing options and configuration information.
A base class for nested structures that can be searched.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
An abstraction for a time stamp and/or sequence number.
A single value (typically within a Bottle).
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
static Value * makeList()
Create a list Value.
virtual yarp::conf::vocab32_t asVocab32() const
Get vocabulary identifier as an integer.
virtual std::string asString() const
Get string value.
T & pixel(size_t x, size_t y)
size_t width() const
Gets width of image in pixels.
unsigned char * getRawImage() const
Access to the internal image buffer.
bool copy(const Image &alt)
Copy operator.
unsigned char * getRow(size_t r)
Get the address of a the first byte of a row in memory.
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
void setTopIsLowIndex(bool flag)
control whether image has origin at top left (default) or bottom left.
void zero()
Set all pixels to 0.
size_t height() const
Gets height of image in pixels.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCDebugThrottle(component, period,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
An interface for the device drivers.
void yield()
The calling thread releases its remaining quantum upon calling this function.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
void delay(double seconds)
Wait for a certain number of seconds.
std::string decode(NetInt32 code)
Convert a vocabulary identifier into a string.
An interface to the operating system, including Port based communication.
constexpr yarp::conf::vocab32_t createVocab32(char a, char b=0, char c=0, char d=0)
Create a vocab from chars.
Very basic drawing functions, in case you don't have anything better available.
void addCircle(ImageOf< T > &dest, const T &pix, int i, int j, int r)
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
unsigned char PixelMono
Monochrome pixel type.
The main, catch-all namespace for YARP.
Struct describing a possible camera configuration.
YarpVocabPixelTypesEnum pixelCoding