MaskRobotInImage.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2018, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package VisionX
19  * @author Julian Zimmer ( urdbu at student dot kit dot edu )
20  * @date 2018
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include "MaskRobotInImage.h"
26 
27 #include <inttypes.h>
28 
29 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
30 
32 
34 
35 #include <Inventor/SoOffscreenRenderer.h>
36 
37 
38 using namespace armarx;
39 
41  std::string cameraFrameName,
42  visionx::ImageFormatInfo imageFormat,
43  float fov,
44  SbColor backgroundColor,
45  bool flipImages,
46  bool useFullModel,
47  float collisionModelInflationMargin)
48 {
49  VirtualRobot::init("MaskRobotInImage");
50  // needed for SoSelection
51  SoInteraction::init();
52 
53  this->cameraFrameName = cameraFrameName;
54  this->fov = fov;
55  this->imageWidth = imageFormat.dimension.width;
56  this->imageHeight = imageFormat.dimension.height;
57  this->backgroundColor = backgroundColor;
58  this->flipImages = flipImages;
59  this->useFullModel = useFullModel;
60  this->collisionModelInflationMargin = collisionModelInflationMargin;
61 
62 
63  renderedImage = new CByteImage(imageWidth, imageHeight, CByteImage::eRGB24);
64  maskImage = new CByteImage(imageWidth, imageHeight, CByteImage::eGrayScale);
65 
66  //get the local robot
67  ARMARX_CHECK_EXPRESSION(robotStateComponent);
68 
69  this->robotStateComponent = robotStateComponent;
70 
73 
74 
75  //create the offscreen renderer
76  renderer.reset(
77  VirtualRobot::CoinVisualizationFactory::createOffscreenRenderer(imageWidth, imageHeight));
78  renderBuffer.resize(imageWidth * imageHeight * 3);
79 
80 
81  renderer->setBackgroundColor(backgroundColor);
82 
83 
84  if (!useFullModel)
85  {
86  if (collisionModelInflationMargin > 0.f)
87  {
88  //inflate the collision model
89  for (auto& model : localRobot->getCollisionModels())
90  {
91  model->setUpdateVisualization(true);
92  model->inflateModel(collisionModelInflationMargin);
93  ARMARX_INFO << "MARGIN AFTER INITIALIZATION: " << model->getMargin();
94  }
95  }
96  }
97  else
98  {
99  if (collisionModelInflationMargin > 0.f)
100  {
101  ARMARX_IMPORTANT << "Inflating collisionModel but not rendering collisionModel!";
102  }
103  }
104 
105 
106  //ARMARX_INFO << "HASTIMESERVER: " << TimeUtil::HasTimeServer();
107 
108 
109  ARMARX_INFO << "RENDERER BACKGROUND COLOR IS: " << renderer->getBackgroundColor().getValue()[0]
110  << ";" << renderer->getBackgroundColor().getValue()[1] << ";"
111  << renderer->getBackgroundColor().getValue()[2] << "]";
112 }
113 
115 {
116 }
117 
118 CByteImage*
120 {
121  ARMARX_CHECK_EXPRESSION(robotStateComponent);
122  //synchronize the localRobot
123  RemoteRobot::synchronizeLocalCloneToTimestamp(localRobot, robotStateComponent, timestamp);
124  ARMARX_CHECK_EXPRESSION(localRobot);
125  //get the cameraNode
126  VirtualRobot::RobotNodePtr cameraNode = localRobot->getRobotNode(cameraFrameName);
127  ARMARX_CHECK_EXPRESSION(cameraNode);
128 
129 
130  //get the visualization
131  VirtualRobot::SceneObject::VisualizationType visuType = VirtualRobot::SceneObject::Collision;
132 
133  if (useFullModel)
134  {
135  visuType = VirtualRobot::SceneObject::Full;
136  }
137 
138 
139  VirtualRobot::CoinVisualizationPtr visualization = localRobot->getVisualization(visuType);
140  ARMARX_CHECK_EXPRESSION(visualization);
141 
142 
143  SoNode* visualisationNode = NULL;
144  ARMARX_CHECK_EXPRESSION(visualization);
145 
146  visualisationNode = visualization->getCoinVisualization();
147 
148  ARMARX_CHECK_EXPRESSION(renderer);
149 
150 
151  //feed it into the renderer
152  bool renderOK = false;
153 
154  auto bufferPtr = renderBuffer.data();
155 
156 
157  //increasing the zNear drawing distance, because the DepthCameraSim camera node is inside the depth camera model
158  renderOK = VirtualRobot::CoinVisualizationFactory::renderOffscreen(
159  renderer.get(), cameraNode, visualisationNode, &bufferPtr, 20.0f, 100000.0f, fov);
160 
161  //Depending on the pose of the camera node, the image should be flipped upside down
162  //If the nodes like EyeLeftCameraSim or DepthCameraSim are used, this has to be performed,
163  //since the orientation of these nodes is flipped in comparison to the orientation expected by the offscreen renderer
164 
165  //copy rendering into image and create the image mask
166  unsigned char* pRenderedImage = renderer->getBuffer();
167  if (renderOK)
168  {
169  std::uint8_t* pixelsRow = renderedImage->pixels;
170  std::uint8_t* maskPixelsRow = maskImage->pixels;
171  for (int y = 0; y < imageHeight; y++)
172  {
173  for (int x = 0; x < imageWidth; x++)
174  {
175  int adjustedX = x;
176  int adjustedY = y;
177  if (flipImages)
178  {
179  adjustedX = imageWidth - 1 - x;
180  adjustedY = imageHeight - 1 - y;
181  }
182 
183 
184  pixelsRow[x * 3 + 0] =
185  pRenderedImage[3 * (imageWidth * (imageHeight - adjustedY) + adjustedX) + 0];
186  pixelsRow[x * 3 + 1] =
187  pRenderedImage[3 * (imageWidth * (imageHeight - adjustedY) + adjustedX) + 1];
188  pixelsRow[x * 3 + 2] =
189  pRenderedImage[3 * (imageWidth * (imageHeight - adjustedY) + adjustedX) + 2];
190 
191  //set the masking pixel to 255 if the background color is in the image pixel, else set it to 0
192  SbColor pixelColor(((float)pixelsRow[x * 3 + 0]) / 255.f,
193  ((float)pixelsRow[x * 3 + 1]) / 255.f,
194  ((float)pixelsRow[x * 3 + 2]) / 255.f);
195  if (backgroundColor.equals(pixelColor, 0.004f))
196  {
197  maskPixelsRow[x] = 0;
198  }
199  else
200  {
201  maskPixelsRow[x] = 255;
202  }
203  }
204  pixelsRow += imageWidth * 3;
205  maskPixelsRow += imageWidth;
206  }
207  }
208 
209 
210  return maskImage;
211 }
212 
213 void
214 MaskRobotInImage::setBackgroundColor(SbColor newBackgroundColor)
215 {
216  backgroundColor = newBackgroundColor;
217  renderer->setBackgroundColor(newBackgroundColor);
218 }
RemoteRobot.h
armarx::eFull
@ eFull
Definition: MorphingItem.h:35
MaskRobotInImage.h
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
armarx::RemoteRobot::createLocalCloneFromFile
static VirtualRobot::RobotPtr createLocalCloneFromFile(RobotStateComponentInterfacePrx robotStatePrx, VirtualRobot::RobotIO::RobotDescription loadMode=VirtualRobot::RobotIO::eFull)
This is a convenience function for createLocalClone, which automatically gets the filename from the R...
Definition: RemoteRobot.cpp:512
armarx::MaskRobotInImage::~MaskRobotInImage
~MaskRobotInImage()
MaskRobotInImage Destructor.
Definition: MaskRobotInImage.cpp:114
CoinVisualizationPtr
boost::shared_ptr< VirtualRobot::CoinVisualization > CoinVisualizationPtr
Definition: ManipulatorVisualization.h:56
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:918
CMakePackageFinder.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::MaskRobotInImage::MaskRobotInImage
MaskRobotInImage(RobotStateComponentInterfacePrx robotStateComponent, std::string cameraFrameName, visionx::ImageFormatInfo imageFormat, float fov, SbColor backgroundColor=SbColor(0.f,(177.f/255.f),(64.f/255.f)), bool flipImages=true, bool useFullModel=true, float collisionModelInflationMargin=0.f)
MaskRobotInImage Constructor.
Definition: MaskRobotInImage.cpp:40
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::RemoteRobot::synchronizeLocalCloneToTimestamp
static bool synchronizeLocalCloneToTimestamp(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx, Ice::Long timestamp)
Synchronizes a local robot to a robot state at timestamp.
Definition: RemoteRobot.cpp:566
IceInternal::ProxyHandle<::IceProxy::armarx::RobotStateComponentInterface >
armarx::MaskRobotInImage::setBackgroundColor
void setBackgroundColor(SbColor newBackgroundColor)
Definition: MaskRobotInImage.cpp:214
armarx::MaskRobotInImage::getMaskImage
CByteImage * getMaskImage(Ice::Long timestamp)
Definition: MaskRobotInImage.cpp:119
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27