ArMarkerLocalizer.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 David Schiebener (schiebener at kit dot edu)
20  * @date 2015
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include <opencv2/calib3d.hpp>
26 
27 #include "ArMarkerLocalizer.h"
28 
29 // RobotState
31 
32 // MemoryX
35 
36 // IVT
37 #include <Calibration/Calibration.h>
38 #include <Image/IplImageAdaptor.h>
39 
40 #include <math.h>
41 
43 
44 using namespace armarx;
45 using namespace ::visionx;
46 using namespace memoryx;
47 using namespace memoryx::EntityWrappers;
48 
49 
50 
51 
52 ArMarkerLocalizerPropertyDefinitions::ArMarkerLocalizerPropertyDefinitions(std::string prefix) :
54 {
55  defineOptionalProperty<float>("MarkerSize", 40.0, "The side length of the marker(s)");
56  defineOptionalProperty<std::string>("ReferenceFrameName", "DepthCamera", "Name of the ReferenceFrameName");
57  defineOptionalProperty<std::string>("AgentName", "Armar6", "name of the agent");
58  defineOptionalProperty<std::string>("ImageProviderName", "ImageProvider", "name of the image provider to use");
59 }
60 
62 {
64 
65  defs->optional(visuEnabled, "visu.enabled", "If true, visualize marker position.");
66 
67  return defs;
68 }
69 
71 {
72  return "ArMarkerLocalizer";
73 }
74 
75 
76 
78 {
79  imageProviderName = getProperty<std::string>("ImageProviderName").getValue();
80 }
81 
82 
84 {
85  markerSize = getProperty<float>("MarkerSize").getValue();
86  ARMARX_VERBOSE << "markerSize: " << markerSize;
87 
88  visionx::ImageProviderInfo imageProviderInfo = getImageProvider(imageProviderName);
89  StereoCalibrationInterfacePrx calibrationProvider = StereoCalibrationInterfacePrx::checkedCast(imageProviderInfo.proxy);
90 
91  std::unique_ptr<CStereoCalibration> stereoCalibration(visionx::tools::convert(calibrationProvider->getStereoCalibration()));
92  CCalibration::CCameraParameters ivtCameraParameters = stereoCalibration->GetLeftCalibration()->GetCameraParameters();
93  cv::Mat cameraMatrix(3, 3, cv::DataType<float>::type);
94  cameraMatrix.at<float>(0, 0) = ivtCameraParameters.focalLength.x;
95  cameraMatrix.at<float>(0, 1) = 0;
96  cameraMatrix.at<float>(0, 2) = ivtCameraParameters.principalPoint.x;
97  cameraMatrix.at<float>(1, 0) = 0;
98  cameraMatrix.at<float>(1, 1) = ivtCameraParameters.focalLength.y;
99  cameraMatrix.at<float>(1, 2) = ivtCameraParameters.principalPoint.y;
100  cameraMatrix.at<float>(2, 0) = 0;
101  cameraMatrix.at<float>(2, 1) = 0;
102  cameraMatrix.at<float>(2, 2) = 1;
103  ARMARX_VERBOSE << "cameraMatrix: " << cameraMatrix;
104  cv::Mat distortionParameters(4, 1, cv::DataType<float>::type);
105 
106  if (!calibrationProvider->getImagesAreUndistorted())
107  {
108  distortionParameters.at<float>(0, 0) = ivtCameraParameters.distortion[0];
109  distortionParameters.at<float>(1, 0) = ivtCameraParameters.distortion[1];
110  distortionParameters.at<float>(2, 0) = ivtCameraParameters.distortion[2];
111  distortionParameters.at<float>(3, 0) = ivtCameraParameters.distortion[3];
112  }
113  else
114  {
115  distortionParameters.at<float>(0, 0) = distortionParameters.at<float>(1, 0) = distortionParameters.at<float>(2, 0) = distortionParameters.at<float>(3, 0) = 0;
116  }
117 
118  cv::Size imageSize;
119  imageSize.width = ivtCameraParameters.width;
120  imageSize.height = ivtCameraParameters.height;
121  arucoCameraParameters.setParams(cameraMatrix, distortionParameters, imageSize);
122  //markerDetector.setCornerRefinementMethod(aruco::MarkerDetector::CornerRefinementMethod::NONE);
123 
124  startingTime = IceUtil::Time::now();
125 
126  cameraImages = new CByteImage*[2];
127 
128  cameraImages[0] = tools::createByteImage(imageProviderInfo);
129  cameraImages[1] = tools::createByteImage(imageProviderInfo);
130 
133 }
134 
136 {
137  if (!waitForImages(500))
138  {
139  ARMARX_WARNING << "Timeout or error in wait for images";
140  return;
141  }
142  getImages(cameraImages);
143 
144  ArMarkerLocalizationResultList result = localizeAllMarkersInternal();
145  {
146  std::unique_lock lock(resultMutex);
147  lastLocalizationResult = result;
148  }
149  if (visuEnabled)
150  {
151  viz::Layer layer = arviz.layer("Marker Poses");
152 
153  for (const auto& r : result)
154  {
155  layer.add(viz::Pose(std::to_string(r.id))
156  .pose(FramedPosePtr::dynamicCast(r.pose)->toEigen()));
157  }
158 
159  arviz.commit(layer);
160  }
161 }
162 
163 
164 
165 ArMarkerLocalizationResultList ArMarkerLocalizer::localizeAllMarkersInternal()
166 {
167  IplImage* imageIpl = IplImageAdaptor::Adapt(cameraImages[0]);
168  cv::Mat imageOpenCV = cv::cvarrToMat(imageIpl);
169 
170  ARMARX_VERBOSE << "Calling marker detector";
171  std::vector<aruco::Marker> markers;
172  markerDetector.detect(imageOpenCV, markers, arucoCameraParameters, markerSize);
173 
174  ARMARX_INFO << deactivateSpam() << "Localized " << markers.size() << " markers: "
176  {
177  for (const auto& m : markers)
178  {
179  out << m.id << " ";
180  }
181  };
182 
183 
184  std::string refFrame = getProperty<std::string>("ReferenceFrameName").getValue();
185  const auto agentName = getProperty<std::string>("AgentName").getValue();
186 
187  visionx::ArMarkerLocalizationResultList resultList;
188 
189  for (aruco::Marker marker : markers)
190  {
191  // assemble result
192  visionx::ArMarkerLocalizationResult result;
193 
194  // position and orientation
195  marker.calculateExtrinsics(markerSize, arucoCameraParameters.CameraMatrix, arucoCameraParameters.Distorsion);
196  Eigen::Vector3f position(marker.Tvec.at<float>(0, 0), marker.Tvec.at<float>(1, 0), marker.Tvec.at<float>(2, 0));
197  Eigen::Matrix3f orientation;
198 
199 
200  cv::Matx33f cvOrientation;
201 
202  cv::Rodrigues(marker.Rvec, cvOrientation);
203 
204  // putting z column first, fixes wrong orientation.
205  orientation << cvOrientation(0, 2), cvOrientation(0, 0), cvOrientation(0, 1),
206  cvOrientation(1, 2), cvOrientation(1, 0), cvOrientation(1, 1),
207  cvOrientation(2, 2), cvOrientation(2, 0), cvOrientation(2, 1);
208 
209 
210  //result.position = new armarx::FramedPosition(position, refFrame, agentName);
211  //result.orientation = new armarx::FramedOrientation(orientation, refFrame, agentName);
212  result.pose = new armarx::FramedPose(orientation, position, refFrame, agentName);
213  result.id = marker.id;
214 
215  /*Eigen::Vector3f mean;
216  mean << 0, 0, 0;
217  Eigen::Matrix3f vars;
218  vars << 0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1;
219  result.positionNoise = memoryx::MultivariateNormalDistributionPtr(new memoryx::MultivariateNormalDistribution(mean, vars));
220 
221  // calculate recognition certainty
222  result.recognitionCertainty = 1.0;
223  result.objectClassName = "Marker_" + std::to_string(marker.id);*/
224 
225  resultList.push_back(result);
226  }
227 
228  return resultList;
229 }
230 
231 
232 
233 visionx::ArMarkerLocalizationResultList visionx::ArMarkerLocalizer::LocalizeAllMarkersNow(const Ice::Current&)
234 {
235  if (!waitForImages(500))
236  {
237  ARMARX_WARNING << "No new Images available!";
238  return visionx::ArMarkerLocalizationResultList();
239  }
240  getImages(cameraImages);
241  return localizeAllMarkersInternal();
242 }
243 
244 ArMarkerLocalizationResultList ArMarkerLocalizer::GetLatestLocalizationResult(const Ice::Current&)
245 {
246  std::unique_lock lock(resultMutex);
247  return lastLocalizationResult;
248 }
249 
250 
251 namespace visionx
252 {
253 
255  {
256  using namespace armarx::RemoteGui::Client;
257 
258  GridLayout grid;
259  int row = 0;
260 
261  tab.markerSize.setRange(1.0, 1000.0);
262  tab.markerSize.setSteps(1000);
263  tab.markerSize.setDecimals(1);
264  tab.markerSize.setValue(this->markerSize);
265 
266  grid.add(Label("Marker size:"), {row, 0}).add(tab.markerSize, {row, 1});
267  row++;
268 
269  VBoxLayout root = {grid, VSpacer()};
270  RemoteGui_createTab(getName(), root, &tab);
271  }
272 
274  {
275  if (tab.markerSize.hasValueChanged())
276  {
277  this->markerSize = tab.markerSize.getValue();
278  }
279  }
280 
281 }
282 
armarx::viz::Client::commit
CommitResult commit(StagedCommit const &commit)
Definition: Client.cpp:80
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
visionx::ArMarkerLocalizer::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: ArMarkerLocalizer.cpp:61
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:37
armarx::RemoteGui::Client::VBoxLayout
Definition: Widgets.h:167
visionx::ArMarkerLocalizer::getDefaultName
std::string getDefaultName() const override
Definition: ArMarkerLocalizer.cpp:70
armarx::RemoteGui::Client::GridLayout::add
GridLayout & add(Widget const &child, Pos pos, Span span=Span{1, 1})
Definition: Widgets.cpp:412
visionx::ImageProcessor::getImageProvider
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
Definition: ImageProcessor.cpp:152
visionx::ArMarkerLocalizer::RemoteGui_update
void RemoteGui_update() override
Definition: ArMarkerLocalizer.cpp:273
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
ObjectRecognitionWrapper.h
visionx::ArMarkerLocalizer::GetLatestLocalizationResult
visionx::ArMarkerLocalizationResultList GetLatestLocalizationResult(const Ice::Current &) override
Definition: ArMarkerLocalizer.cpp:244
visionx::ArMarkerLocalizer::process
void process() override
Process the vision component.
Definition: ArMarkerLocalizer.cpp:135
armarx::viz::Layer::add
void add(ElementT const &element)
Definition: Layer.h:29
armarx::RemoteGui::Client::VSpacer
Definition: Widgets.h:204
visionx::tools::createByteImage
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
visionx::ImageProviderInfo
Definition: ImageProcessor.h:466
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
visionx::ArMarkerLocalizer::onConnectImageProcessor
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
Definition: ArMarkerLocalizer.cpp:83
visionx::voxelgrid::Label
uint32_t Label
Type of an object label.
Definition: types.h:7
armarx::RemoteGui::Client::GridLayout
Definition: Widgets.h:186
visionx::ArMarkerLocalizerPropertyDefinitions
Definition: ArMarkerLocalizer.h:46
visionx::ArMarkerLocalizer::onInitImageProcessor
void onInitImageProcessor() override
Setup the vision component.
Definition: ArMarkerLocalizer.cpp:77
FramedPose.h
ArMarkerLocalizer.h
MemoryXCoreObjectFactories.h
armarx::viz::Pose
Definition: Elements.h:179
visionx::ImageProcessor::getImages
int getImages(CByteImage **ppImages)
Poll images from provider.
Definition: ImageProcessor.cpp:351
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::LightweightRemoteGuiComponentPluginUser::RemoteGui_startRunningTask
void RemoteGui_startRunningTask()
Definition: LightweightRemoteGuiComponentPlugin.cpp:110
visionx::ArMarkerLocalizer::LocalizeAllMarkersNow
visionx::ArMarkerLocalizationResultList LocalizeAllMarkersNow(const Ice::Current &) override
Definition: ArMarkerLocalizer.cpp:233
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
visionx::ArMarkerLocalizer::createRemoteGuiTab
void createRemoteGuiTab()
Definition: ArMarkerLocalizer.cpp:254
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:600
visionx::ImageProviderInfo::proxy
ImageProviderInterfacePrx proxy
proxy to image provider
Definition: ImageProcessor.h:472
memoryx::EntityWrappers
Definition: AbstractEntityWrapper.cpp:28
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::viz::ElementOps::pose
DerivedT & pose(Eigen::Matrix4f const &pose)
Definition: ElementOps.h:159
armarx::ArVizComponentPluginUser::arviz
armarx::viz::Client arviz
Definition: ArVizComponentPlugin.h:43
armarx::LightweightRemoteGuiComponentPluginUser::RemoteGui_createTab
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)
Definition: LightweightRemoteGuiComponentPlugin.cpp:95
IceUtil::Handle< class PropertyDefinitionContainer >
visionx::ImageProcessorPropertyDefinitions
Definition: ImageProcessor.h:61
ImageUtil.h
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::viz::Client::layer
Layer layer(std::string const &name) const
Definition: Client.cpp:73
armarx::RemoteGui::Client
Definition: EigenWidgets.cpp:8
armarx::viz::Layer
Definition: Layer.h:12
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
visionx::ImageProcessor::waitForImages
bool waitForImages(int milliseconds=1000)
Wait for new images.
Definition: ImageProcessor.cpp:275
ARMARX_STREAM_PRINTER
#define ARMARX_STREAM_PRINTER
use this macro to write output code that is executed when printed and thus not executed if the debug ...
Definition: Logging.h:304