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/core/DataTypes.h>
29 #include <VisionX/interface/components/PointCloudAndImageAndCalibrationProviderInterface.h>
30 
31 // VisionXTools
34 
35 // MemoryX
41 
42 // ArmarXCore
44 
45 // IVT
46 #include "Calibration/Calibration.h"
47 
48 namespace visionx
49 {
50 
52  : resultImagesEnabled(true)
53  , imagesAreUndistorted(false)
54  , numberOfResultImages(2)
55  , job(this)
56  {
59  }
60 
62  {
63  ARMARX_VERBOSE << "Number of result images: " << numberOfResultImages;
64  resultImagesData.clear();
65  resultImagesData.resize(numberOfResultImages, nullptr);
66  // HACK: boost::ptr_vector::c_array() is broken if the value type is nullable (check in new boost version)
67  void* firstEntry = &resultImagesData.begin().base()[0];
68  resultImages = static_cast<CByteImage**>(firstEntry);
69 
70  // get properties
71  priorKnowledgeProxyName = getProperty<std::string>("PriorKnowledgeProxyName").getValue();
72  imageProviderName = getProperty<std::string>("ImageProviderName").getValue();
73 
74  resultImagesEnabled = getProperty<bool>("EnableResultImages").getValue();
75 
76  useResultImageMask = getProperty<bool>("useResultImageMask").getValue();
77  colorMask = getProperty<Eigen::Vector3i>("colorMask").getValue();
78 
79  // setup proxy
82  usingTopic(getProperty<std::string>("CalibrationUpdateTopicName").getValue());
83 
84  // setup noise
85  imageNoiseLeft(0) = imageNoiseLeft(1) = getProperty<float>("2DLocalizationNoise").getValue();
86  imageNoiseRight(0) = imageNoiseRight(1) = getProperty<float>("2DLocalizationNoise").getValue();
87 
88  // subclass initialization
90  }
91 
93  {
94  // retrieve proxies and required parameters
95  ImageProviderInfo imageProviderInfo = getImageProvider(imageProviderName, visionx::eRgb);
96  imageFormat = imageProviderInfo.imageFormat;
97 
98  imageProviderPrx = getProxy<ImageProviderInterfacePrx>(imageProviderName);
99 
100  // retrieve stereo information
101 
102  StereoCalibrationInterfacePrx calibrationProvider = StereoCalibrationInterfacePrx::checkedCast(imageProviderPrx);
103 
104  if (calibrationProvider)
105  {
106  stereoCalibration.reset(visionx::tools::convert(calibrationProvider->getStereoCalibration()));
107  imagesAreUndistorted = calibrationProvider->getImagesAreUndistorted();
108  referenceFrameName = calibrationProvider->getReferenceFrame();
109  }
110 
111  else
112  {
113  ARMARX_ERROR << "Unable to get calibration data. The image provider is not a StereoCalibrationProvider";
114  }
115 
116 
117  if (resultImagesEnabled)
118  {
119  ARMARX_INFO << "Enabeling Visualization with " << numberOfResultImages << " images." << std::endl;
120  enableResultImages(numberOfResultImages, ImageDimension(imageFormat.dimension.width, imageFormat.dimension.height), visionx::eRgb);
121  }
122  job.reset();
123  setupImages(imageFormat.dimension.width, imageFormat.dimension.height);
124 
126  }
127 
128  void ObjectLocalizerProcessor::initObjectClasses()
129  {
130  ARMARX_VERBOSE_S << "Initializing object classes";
131 
132  // init proxies
133  priorKnowledgePrx = getProxy<memoryx::PriorKnowledgeInterfacePrx>(priorKnowledgeProxyName);
134  classesSegmentPrx = priorKnowledgePrx->getObjectClassesSegment();
135  databasePrx = priorKnowledgePrx->getCommonStorage();
136 
137  fileManager.reset(new memoryx::GridFileManager(databasePrx));
138 
139  // retrieve object classes suitable for this recognizer type
140  memoryx::CollectionInterfacePrx coll = databasePrx->requestCollection(getProperty<std::string>("DataBaseObjectCollectionName").getValue());
141  classesSegmentPrx->addReadCollection(coll);
142  // classesSegmentPrx->setWriteCollection(coll);
143 
144  memoryx::EntityIdList idList = classesSegmentPrx->getAllEntityIds();
145 
146  ARMARX_INFO << "Found " << idList.size() << " object classes in the class segments: " << classesSegmentPrx->getReadCollectionsNS();
147 
148  int classesUsed = 0;
149 
150  for (memoryx::EntityIdList::iterator iter = idList.begin(); iter != idList.end(); iter++)
151  {
152  memoryx::EntityPtr entity = memoryx::EntityPtr::dynamicCast(classesSegmentPrx->getEntityById(*iter));
153 
154  if (!entity)
155  {
156  ARMARX_IMPORTANT << "RECEIVED NULL Entity";
157  continue;
158  }
159 
161 
162  if (recognitionWrapper->getRecognitionMethod() == getName())
163  {
164  if (addObjectClass(entity, fileManager))
165  {
166  std::string className = entity->getName();
167  ARMARX_INFO << "Adding class " << className << " to " << getDefaultName();
168  classesUsed++;
169  }
170  }
171  }
172 
173  ARMARX_INFO << getDefaultName() << " is available using " << classesUsed << " object classes";
174  }
175 
176  memoryx::ObjectLocalizationResultList ObjectLocalizerProcessor::localizeObjectClasses(const memoryx::ObjectClassNameList& objectClassNames, const Ice::Current& c)
177  {
178  // assure processor thread is started and ManagedIceObject is fully connected
179  // getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted);
180  memoryx::ObjectLocalizationResultList result;
181 
182  // start localization job in a separate thread
183  try
184  {
185  job.start(objectClassNames);
186  result = job.waitForResult();
187  }
188  catch (std::exception& e)
189  {
191  }
192 
193  return result;
194  }
195 
197  {
198  job.process();
199  }
200 
202  {
203  // initialize noise
205 
206  Eigen::MatrixXd combinedNoise(4, 4);
207  combinedNoise.setZero();
208  combinedNoise(0, 0) = imageNoiseLeft(0);
209  combinedNoise(1, 1) = imageNoiseLeft(1);
210  combinedNoise(2, 2) = imageNoiseRight(0);
211  combinedNoise(3, 3) = imageNoiseRight(1);
212 
213  Eigen::VectorXd mean(4);
214  mean << left_point.x, left_point.y, right_point.x, right_point.y;
215 
216  Gaussian imageSpaceNoise(4);
217  imageSpaceNoise.setCovariance(combinedNoise);
218  imageSpaceNoise.setMean(mean);
219 
220  // calculate sigma points
221  Eigen::MatrixXd sigmapoints = ut.getSigmaPoints(imageSpaceNoise);
222 
223  // pass sigma points through system
224  Vec2d l, r;
225  Vec3d w;
226  Eigen::VectorXd base(4);
227  Eigen::VectorXd world(4);
228 
229  Eigen::MatrixXd processedpoints(3, sigmapoints.cols());
230 
231  for (int n = 0 ; n < sigmapoints.cols() ; n++)
232  {
233 
234  Math2d::SetVec(l, sigmapoints(0, n), sigmapoints(1, n));
235  Math2d::SetVec(r, sigmapoints(2, n), sigmapoints(3, n));
236 
237  // calc 3d point (2D points are rectified but not distorted)
238  stereoCalibration->Calculate3DPoint(l, r, w, true, true);
239  world << w.x, w.y, w.z, 1.0f;
240 
241  processedpoints(0, n) = world(0);
242  processedpoints(1, n) = world(1);
243  processedpoints(2, n) = world(2);
244  }
245 
246  // recover covariance
247  Gaussian worldSpaceNoise = ut.extractGaussian(processedpoints);
248 
249  // manual hack: avoid underestimation of noise
250  worldSpaceNoise.setCovariance(4.0f * worldSpaceNoise.getCovariance());
251 
253  }
254 
256  {
257  // calculate 2d points for localization uncerainty
258  Vec2d left2d, right2d;
259  Vec3d pos;
260  Math3d::SetVec(pos, position(0), position(1), position(2));
261 
262  getStereoCalibration()->GetLeftCalibration()->WorldToImageCoordinates(pos, left2d);
263  getStereoCalibration()->GetRightCalibration()->WorldToImageCoordinates(pos, right2d);
264 
265  // transform to rectified coordinates
266  Mat3d inverseHLeft, inverseHRight;
267  Math3d::Invert(getStereoCalibration()->rectificationHomographyLeft, inverseHLeft);
268  Math3d::Invert(getStereoCalibration()->rectificationHomographyRight, inverseHRight);
269  Math2d::ApplyHomography(inverseHLeft, left2d, left2d);
270  Math2d::ApplyHomography(inverseHRight, right2d, right2d);
271 
272  return calculateLocalizationUncertainty(left2d, right2d);
273  }
274 
275 
276  void ObjectLocalizerProcessor::setupImages(int width, int height)
277  {
278  ARMARX_IMPORTANT << "Setting up images";
279 
280  for (CByteImage& cameraImage : cameraImagesData)
281  {
282  cameraImage.Set(width, height, CByteImage::eRGB24);
283  }
284 
285  for (int i = 0; i < numberOfResultImages; i++)
286  {
287  resultImagesData.replace(i, new CByteImage(width, height, CByteImage::eRGB24));
288  }
289  }
290 }
Gaussian::getCovariance
const covariance_type & getCovariance() const
Definition: Gaussian.h:77
visionx::ObjectLocalizerProcessor::onConnectObjectLocalizerProcessor
virtual void onConnectObjectLocalizerProcessor()
ObjectLocalizerProcessor interface: subclass hook.
Definition: ObjectLocalizerProcessor.h:234
UnscentedTransform
Definition: UnscentedTransform.h:18
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
visionx::ObjectLocalizerProcessor::resultImages
CByteImage ** resultImages
Definition: ObjectLocalizerProcessor.h:374
UnscentedTransform::getSigmaPoints
Eigen::MatrixXd getSigmaPoints(const Gaussian &gaussian)
Definition: UnscentedTransform.cpp:23
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:176
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
visionx::ObjectLocalizerProcessor::referenceFrameName
std::string referenceFrameName
Definition: ObjectLocalizerProcessor.h:368
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:152
GfxTL::Vec2d
VectorXD< 2, double > Vec2d
Definition: VectorXD.h:694
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
ObjectRecognitionWrapper.h
visionx::ImageProviderInfo::imageFormat
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
Definition: ImageProcessor.h:496
visionx::ObjectLocalizerProcessorJob::waitForResult
memoryx::ObjectLocalizationResultList waitForResult()
Wait for the localization result.
Definition: ObjectLocalizerProcessorJob.cpp:56
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:466
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:95
ObjectLocalizerProcessor.h
visionx::ObjectLocalizerProcessor::process
void process() override
The process method is inherited from ImageProcessor.
Definition: ObjectLocalizerProcessor.cpp:196
UnscentedTransform::extractGaussian
Gaussian extractGaussian(Eigen::MatrixXd processedSigmaPoints)
Definition: UnscentedTransform.cpp:75
armarx::mean
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
Definition: KinematicUnitGuiPlugin.cpp:1615
visionx::ObjectLocalizerProcessor::cameraImages
CByteImage * cameraImages[2]
Definition: ObjectLocalizerProcessor.h:372
GfxTL::Vec3d
VectorXD< 3, double > Vec3d
Definition: VectorXD.h:695
Gaussian::setMean
void setMean(const value_type &mean)
Definition: Gaussian.cpp:245
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:117
visionx::ObjectLocalizerProcessor::priorKnowledgeProxyName
std::string priorKnowledgeProxyName
Definition: ObjectLocalizerProcessor.h:367
visionx::ObjectLocalizerProcessor::onConnectImageProcessor
void onConnectImageProcessor() override
Called from framework.
Definition: ObjectLocalizerProcessor.cpp:92
Gaussian::setCovariance
void setCovariance(const covariance_type &cov)
Definition: Gaussian.cpp:261
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
visionx::ObjectLocalizerProcessorJob::reset
void reset()
Definition: ObjectLocalizerProcessorJob.cpp:51
visionx::ObjectLocalizerProcessor::imageProviderName
std::string imageProviderName
Definition: ObjectLocalizerProcessor.h:366
visionx::ObjectLocalizerProcessor::resultImagesData
boost::ptr_vector< boost::nullable< CByteImage > > resultImagesData
Definition: ObjectLocalizerProcessor.h:373
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:227
ProbabilityMeasures.h
armarx::ManagedIceObject::usingTopic
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Definition: ManagedIceObject.cpp:248
visionx::ObjectLocalizerProcessor::getStereoCalibration
CStereoCalibration * getStereoCalibration() const
Retrieve stereo calibration corresponding to image provider.
Definition: ObjectLocalizerProcessor.h:334
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
Entity.h
visionx::ImageProcessor::enableResultImages
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
Definition: ImageProcessor.cpp:227
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:42
visionx::ObjectLocalizerProcessorJob::start
void start(std::vector< std::string > objectClassNames)
Start a localization job for the given objectClassName.
Definition: ObjectLocalizerProcessorJob.cpp:42
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:200
visionx::ObjectLocalizerProcessor::onInitImageProcessor
void onInitImageProcessor() override
Called from framework.
Definition: ObjectLocalizerProcessor.cpp:61
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
memoryx::EarlyVisionConverters::convertToMemoryX_MULTI
MultivariateNormalDistributionPtr convertToMemoryX_MULTI(const Gaussian &gaussian)
Definition: EarlyVisionConverters.cpp:59
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:201
Gaussian
Definition: Gaussian.h:46
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
visionx::ObjectLocalizerProcessor::cameraImagesData
CByteImage cameraImagesData[2]
Definition: ObjectLocalizerProcessor.h:371
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:151
visionx::ObjectLocalizerProcessor::numberOfResultImages
int numberOfResultImages
Definition: ObjectLocalizerProcessor.h:376
Exception.h
visionx::ObjectLocalizerProcessorJob::process
void process()
Processing method.
Definition: ObjectLocalizerProcessorJob.cpp:72
visionx::ObjectLocalizerProcessor::ObjectLocalizerProcessor
ObjectLocalizerProcessor()
Definition: ObjectLocalizerProcessor.cpp:51