ObjectLocalizerProcessor.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, 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::Component
19  * @author Kai Welke (welke at kit dot edu)
20  * @date 2013
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
26 
27 // VisionXInterface
28 #include <VisionX/interface/components/PointCloudAndImageAndCalibrationProviderInterface.h>
29 #include <VisionX/interface/core/DataTypes.h>
30 
31 // VisionXTools
33 
35 
36 // MemoryX
42 
43 // ArmarXCore
45 
46 // IVT
47 #include "Calibration/Calibration.h"
48 
49 namespace visionx
50 {
51 
53  resultImagesEnabled(true), imagesAreUndistorted(false), numberOfResultImages(2), job(this)
54  {
57  }
58 
59  void
61  {
62  ARMARX_VERBOSE << "Number of result images: " << numberOfResultImages;
63  resultImagesData.clear();
64  resultImagesData.resize(numberOfResultImages, nullptr);
65  // HACK: boost::ptr_vector::c_array() is broken if the value type is nullable (check in new boost version)
66  void* firstEntry = &resultImagesData.begin().base()[0];
67  resultImages = static_cast<CByteImage**>(firstEntry);
68 
69  // get properties
70  priorKnowledgeProxyName = getProperty<std::string>("PriorKnowledgeProxyName").getValue();
71  imageProviderName = getProperty<std::string>("ImageProviderName").getValue();
72 
73  resultImagesEnabled = getProperty<bool>("EnableResultImages").getValue();
74 
75  useResultImageMask = getProperty<bool>("useResultImageMask").getValue();
76  colorMask = getProperty<Eigen::Vector3i>("colorMask").getValue();
77 
78  // setup proxy
81  usingTopic(getProperty<std::string>("CalibrationUpdateTopicName").getValue());
82 
83  // setup noise
84  imageNoiseLeft(0) = imageNoiseLeft(1) =
85  getProperty<float>("2DLocalizationNoise").getValue();
86  imageNoiseRight(0) = imageNoiseRight(1) =
87  getProperty<float>("2DLocalizationNoise").getValue();
88 
89  // subclass initialization
91  }
92 
93  void
95  {
96  // retrieve proxies and required parameters
97  ImageProviderInfo imageProviderInfo = getImageProvider(imageProviderName, visionx::eRgb);
98  imageFormat = imageProviderInfo.imageFormat;
99 
100  imageProviderPrx = getProxy<ImageProviderInterfacePrx>(imageProviderName);
101 
102  // retrieve stereo information
103 
104  StereoCalibrationInterfacePrx calibrationProvider =
105  StereoCalibrationInterfacePrx::checkedCast(imageProviderPrx);
106 
107  if (calibrationProvider)
108  {
109  stereoCalibration.reset(
110  visionx::tools::convert(calibrationProvider->getStereoCalibration()));
111  imagesAreUndistorted = calibrationProvider->getImagesAreUndistorted();
112  referenceFrameName = calibrationProvider->getReferenceFrame();
113  }
114 
115  else
116  {
117  ARMARX_ERROR << "Unable to get calibration data. The image provider is not a "
118  "StereoCalibrationProvider";
119  }
120 
121 
122  if (resultImagesEnabled)
123  {
124  ARMARX_INFO << "Enabeling Visualization with " << numberOfResultImages << " images."
125  << std::endl;
128  ImageDimension(imageFormat.dimension.width, imageFormat.dimension.height),
129  visionx::eRgb);
130  }
131  job.reset();
132  setupImages(imageFormat.dimension.width, imageFormat.dimension.height);
133 
135  }
136 
137  void
138  ObjectLocalizerProcessor::initObjectClasses()
139  {
140  ARMARX_VERBOSE_S << "Initializing object classes";
141 
142  // init proxies
143  priorKnowledgePrx = getProxy<memoryx::PriorKnowledgeInterfacePrx>(priorKnowledgeProxyName);
144  classesSegmentPrx = priorKnowledgePrx->getObjectClassesSegment();
145  databasePrx = priorKnowledgePrx->getCommonStorage();
146 
147  fileManager.reset(new memoryx::GridFileManager(databasePrx));
148 
149  // retrieve object classes suitable for this recognizer type
150  memoryx::CollectionInterfacePrx coll = databasePrx->requestCollection(
151  getProperty<std::string>("DataBaseObjectCollectionName").getValue());
152  classesSegmentPrx->addReadCollection(coll);
153  // classesSegmentPrx->setWriteCollection(coll);
154 
155  memoryx::EntityIdList idList = classesSegmentPrx->getAllEntityIds();
156 
157  ARMARX_INFO << "Found " << idList.size() << " object classes in the class segments: "
158  << classesSegmentPrx->getReadCollectionsNS();
159 
160  int classesUsed = 0;
161 
162  for (memoryx::EntityIdList::iterator iter = idList.begin(); iter != idList.end(); iter++)
163  {
164  memoryx::EntityPtr entity =
165  memoryx::EntityPtr::dynamicCast(classesSegmentPrx->getEntityById(*iter));
166 
167  if (!entity)
168  {
169  ARMARX_IMPORTANT << "RECEIVED NULL Entity";
170  continue;
171  }
172 
174  entity->addWrapper(new memoryx::EntityWrappers::ObjectRecognitionWrapper());
175 
176  if (recognitionWrapper->getRecognitionMethod() == getName())
177  {
178  if (addObjectClass(entity, fileManager))
179  {
180  std::string className = entity->getName();
181  ARMARX_INFO << "Adding class " << className << " to " << getDefaultName();
182  classesUsed++;
183  }
184  }
185  }
186 
187  ARMARX_INFO << getDefaultName() << " is available using " << classesUsed
188  << " object classes";
189  }
190 
191  memoryx::ObjectLocalizationResultList
193  const memoryx::ObjectClassNameList& objectClassNames,
194  const Ice::Current& c)
195  {
196  // assure processor thread is started and ManagedIceObject is fully connected
197  // getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted);
198  memoryx::ObjectLocalizationResultList result;
199 
200  // start localization job in a separate thread
201  try
202  {
203  job.start(objectClassNames);
204  result = job.waitForResult();
205  }
206  catch (std::exception& e)
207  {
209  }
210 
211  return result;
212  }
213 
214  void
216  {
217  job.process();
218  }
219 
222  {
223  // initialize noise
225 
226  Eigen::MatrixXd combinedNoise(4, 4);
227  combinedNoise.setZero();
228  combinedNoise(0, 0) = imageNoiseLeft(0);
229  combinedNoise(1, 1) = imageNoiseLeft(1);
230  combinedNoise(2, 2) = imageNoiseRight(0);
231  combinedNoise(3, 3) = imageNoiseRight(1);
232 
233  Eigen::VectorXd mean(4);
234  mean << left_point.x, left_point.y, right_point.x, right_point.y;
235 
236  Gaussian imageSpaceNoise(4);
237  imageSpaceNoise.setCovariance(combinedNoise);
238  imageSpaceNoise.setMean(mean);
239 
240  // calculate sigma points
241  Eigen::MatrixXd sigmapoints = ut.getSigmaPoints(imageSpaceNoise);
242 
243  // pass sigma points through system
244  Vec2d l, r;
245  Vec3d w;
246  Eigen::VectorXd base(4);
247  Eigen::VectorXd world(4);
248 
249  Eigen::MatrixXd processedpoints(3, sigmapoints.cols());
250 
251  for (int n = 0; n < sigmapoints.cols(); n++)
252  {
253 
254  Math2d::SetVec(l, sigmapoints(0, n), sigmapoints(1, n));
255  Math2d::SetVec(r, sigmapoints(2, n), sigmapoints(3, n));
256 
257  // calc 3d point (2D points are rectified but not distorted)
258  stereoCalibration->Calculate3DPoint(l, r, w, true, true);
259  world << w.x, w.y, w.z, 1.0f;
260 
261  processedpoints(0, n) = world(0);
262  processedpoints(1, n) = world(1);
263  processedpoints(2, n) = world(2);
264  }
265 
266  // recover covariance
267  Gaussian worldSpaceNoise = ut.extractGaussian(processedpoints);
268 
269  // manual hack: avoid underestimation of noise
270  worldSpaceNoise.setCovariance(4.0f * worldSpaceNoise.getCovariance());
271 
273  }
274 
277  {
278  // calculate 2d points for localization uncerainty
279  Vec2d left2d, right2d;
280  Vec3d pos;
281  Math3d::SetVec(pos, position(0), position(1), position(2));
282 
283  getStereoCalibration()->GetLeftCalibration()->WorldToImageCoordinates(pos, left2d);
284  getStereoCalibration()->GetRightCalibration()->WorldToImageCoordinates(pos, right2d);
285 
286  // transform to rectified coordinates
287  Mat3d inverseHLeft, inverseHRight;
288  Math3d::Invert(getStereoCalibration()->rectificationHomographyLeft, inverseHLeft);
289  Math3d::Invert(getStereoCalibration()->rectificationHomographyRight, inverseHRight);
290  Math2d::ApplyHomography(inverseHLeft, left2d, left2d);
291  Math2d::ApplyHomography(inverseHRight, right2d, right2d);
292 
293  return calculateLocalizationUncertainty(left2d, right2d);
294  }
295 
296  void
297  ObjectLocalizerProcessor::setupImages(int width, int height)
298  {
299  ARMARX_IMPORTANT << "Setting up images";
300 
301  for (CByteImage& cameraImage : cameraImagesData)
302  {
303  cameraImage.Set(width, height, CByteImage::eRGB24);
304  }
305 
306  for (int i = 0; i < numberOfResultImages; i++)
307  {
308  resultImagesData.replace(i, new CByteImage(width, height, CByteImage::eRGB24));
309  }
310  }
311 } // namespace visionx
Gaussian::getCovariance
const covariance_type & getCovariance() const
Definition: Gaussian.h:82
visionx::ObjectLocalizerProcessor::onConnectObjectLocalizerProcessor
virtual void onConnectObjectLocalizerProcessor()
ObjectLocalizerProcessor interface: subclass hook.
Definition: ObjectLocalizerProcessor.h:270
UnscentedTransform
Definition: UnscentedTransform.h:19
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
visionx::ObjectLocalizerProcessor::resultImages
CByteImage ** resultImages
Definition: ObjectLocalizerProcessor.h:431
UnscentedTransform::getSigmaPoints
Eigen::MatrixXd getSigmaPoints(const Gaussian &gaussian)
Definition: UnscentedTransform.cpp:25
visionx::ObjectLocalizerProcessor::localizeObjectClasses
memoryx::ObjectLocalizationResultList localizeObjectClasses(const memoryx::ObjectClassNameList &objectClassNames, const Ice::Current &c=Ice::emptyCurrent) override
The process method is inherited from the ObjectLocalizationProcessorInterface and is called by the Wo...
Definition: ObjectLocalizerProcessor.cpp:192
GfxTL::Vec3d
VectorXD< 3, double > Vec3d
Definition: VectorXD.h:737
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
visionx::ObjectLocalizerProcessor::referenceFrameName
std::string referenceFrameName
Definition: ObjectLocalizerProcessor.h:425
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
Pose.h
visionx::ImageProcessor::getImageProvider
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
Definition: ImageProcessor.cpp:167
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
ObjectRecognitionWrapper.h
visionx::ImageProviderInfo::imageFormat
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
Definition: ImageProcessor.h:509
visionx::ObjectLocalizerProcessorJob::waitForResult
memoryx::ObjectLocalizationResultList waitForResult()
Wait for the localization result.
Definition: ObjectLocalizerProcessorJob.cpp:57
visionx::ObjectLocalizerProcessor::addObjectClass
virtual bool addObjectClass(const memoryx::EntityPtr &objectClassEntity, const memoryx::GridFileManagerPtr &fileManager)=0
ObjectLocalizerProcessor interface: The addObjectClass method needs to be implemented by any ObjectLo...
UnscentedTransform.h
visionx::ImageProviderInfo
Definition: ImageProcessor.h:479
IceInternal::Handle
Definition: forward_declarations.h:8
visionx::tools::convert
CByteImage::ImageType convert(const ImageType visionxImageType)
Converts a VisionX image type into an image type of IVT's ByteImage.
Definition: TypeMapping.cpp:97
ObjectLocalizerProcessor.h
visionx::ObjectLocalizerProcessor::process
void process() override
The process method is inherited from ImageProcessor.
Definition: ObjectLocalizerProcessor.cpp:215
UnscentedTransform::extractGaussian
Gaussian extractGaussian(Eigen::MatrixXd processedSigmaPoints)
Definition: UnscentedTransform.cpp:78
armarx::mean
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
Definition: KinematicUnitGuiPlugin.cpp:1620
visionx::ObjectLocalizerProcessor::cameraImages
CByteImage * cameraImages[2]
Definition: ObjectLocalizerProcessor.h:429
Gaussian::setMean
void setMean(const value_type &mean)
Definition: Gaussian.cpp:255
visionx::ImageProcessor::usingImageProvider
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
Definition: ImageProcessor.cpp:128
visionx::ObjectLocalizerProcessor::priorKnowledgeProxyName
std::string priorKnowledgeProxyName
Definition: ObjectLocalizerProcessor.h:424
visionx::ObjectLocalizerProcessor::onConnectImageProcessor
void onConnectImageProcessor() override
Called from framework.
Definition: ObjectLocalizerProcessor.cpp:94
Gaussian::setCovariance
void setCovariance(const covariance_type &cov)
Definition: Gaussian.cpp:272
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
visionx::ObjectLocalizerProcessorJob::reset
void reset()
Definition: ObjectLocalizerProcessorJob.cpp:51
visionx::ObjectLocalizerProcessor::imageProviderName
std::string imageProviderName
Definition: ObjectLocalizerProcessor.h:423
visionx::ObjectLocalizerProcessor::resultImagesData
boost::ptr_vector< boost::nullable< CByteImage > > resultImagesData
Definition: ObjectLocalizerProcessor.h:430
GfxTL::Vec2d
VectorXD< 2, double > Vec2d
Definition: VectorXD.h:736
armarx::ManagedIceObject::getDefaultName
virtual std::string getDefaultName() const =0
Retrieve default name of component.
visionx::ObjectLocalizerProcessor::onInitObjectLocalizerProcessor
virtual void onInitObjectLocalizerProcessor()
ObjectLocalizerProcessor interface: subclass hook.
Definition: ObjectLocalizerProcessor.h:260
ProbabilityMeasures.h
armarx::ManagedIceObject::usingTopic
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Definition: ManagedIceObject.cpp:254
visionx::ObjectLocalizerProcessor::getStereoCalibration
CStereoCalibration * getStereoCalibration() const
Retrieve stereo calibration corresponding to image provider.
Definition: ObjectLocalizerProcessor.h:391
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
Entity.h
visionx::ImageProcessor::enableResultImages
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
Definition: ImageProcessor.cpp:251
EarlyVisionConverters.h
memoryx::EntityWrappers::ObjectRecognitionWrapper
Definition: ObjectRecognitionWrapper.h:40
ImageUtil.h
memoryx::GridFileManager
GridFileManager provides utility functions for working with files in Mongo GridFS and links to them s...
Definition: GridFileManager.h:41
visionx::ObjectLocalizerProcessorJob::start
void start(std::vector< std::string > objectClassNames)
Start a localization job for the given objectClassName.
Definition: ObjectLocalizerProcessorJob.cpp:41
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:207
visionx::ObjectLocalizerProcessor::onInitImageProcessor
void onInitImageProcessor() override
Called from framework.
Definition: ObjectLocalizerProcessor.cpp:60
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
memoryx::EarlyVisionConverters::convertToMemoryX_MULTI
MultivariateNormalDistributionPtr convertToMemoryX_MULTI(const Gaussian &gaussian)
Definition: EarlyVisionConverters.cpp:61
visionx::ObjectLocalizerProcessor::calculateLocalizationUncertainty
memoryx::MultivariateNormalDistributionPtr calculateLocalizationUncertainty(Vec2d left_point, Vec2d right_point)
Calculate 3D uncertainty from two 2d points in left and right camera.
Definition: ObjectLocalizerProcessor.cpp:221
Gaussian
Definition: Gaussian.h:50
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:157
visionx::ObjectLocalizerProcessor::cameraImagesData
CByteImage cameraImagesData[2]
Definition: ObjectLocalizerProcessor.h:428
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:154
visionx::ObjectLocalizerProcessor::numberOfResultImages
int numberOfResultImages
Definition: ObjectLocalizerProcessor.h:433
Exception.h
visionx::ObjectLocalizerProcessorJob::process
void process()
Processing method.
Definition: ObjectLocalizerProcessorJob.cpp:75
visionx::ObjectLocalizerProcessor::ObjectLocalizerProcessor
ObjectLocalizerProcessor()
Definition: ObjectLocalizerProcessor.cpp:52