TrackingError.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package VisionX::ArmarXObjects::TrackingError
17 * @author David Sippel ( uddoe at student dot kit dot edu )
18 * @date 2016
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "TrackingError.h"
24
26
27using namespace armarx;
28
35
36void
38{
39 providerName = getProperty<std::string>("providerName").getValue();
40 usingImageProvider(providerName);
41
42 offeringTopic(getProperty<std::string>("TrackingErrorTopicName").getValue());
43
44 offeringTopic(getProperty<std::string>("DebugObserverName").getValue());
45
46 frameRate = getProperty<float>("Framerate").getValue();
47
48 useChessboard = getProperty<bool>("UseChessBoard").getValue();
49
50 chessboardWidth = getProperty<int>("Chessboard.Width").getValue();
51 chessboardHeight = getProperty<int>("Chessboard.Height").getValue();
52}
53
54void
56{
57 std::unique_lock lock(imageMutex);
58
59 visionx::ImageProviderInfo imageProviderInfo = getImageProvider(providerName);
60 imageProviderPrx = getProxy<visionx::ImageProviderInterfacePrx>(providerName);
61
62 cameraImages = new CByteImage*[2];
63 cameraImages[0] = visionx::tools::createByteImage(imageProviderInfo);
64 cameraImages[1] = visionx::tools::createByteImage(imageProviderInfo);
65
66
68 getProperty<std::string>("DebugObserverName").getValue());
69
71 getProperty<std::string>("TrackingErrorTopicName").getValue());
72
73 imageWidth = imageProviderPrx->getImageFormat().dimension.width;
74 imageHeight = imageProviderPrx->getImageFormat().dimension.height;
75
77 1, imageProviderPrx->getImageFormat().dimension, imageProviderPrx->getImageFormat().type);
78}
79
80void
84
85void
87{
88 std::unique_lock lock(imageMutex);
89
90 if (!waitForImages(getProperty<std::string>("providerName").getValue(), 1000))
91 {
92 ARMARX_WARNING << "Timeout while waiting for camera images (>1000ms)";
93 return;
94 }
95
96 int numImages = getImages(cameraImages);
97
98 if (numImages == 0)
99 {
100 ARMARX_WARNING << "Didn't receive one image! Aborting!";
101 return;
102 }
103
104 IplImage* ppIplImages[1] = {IplImageAdaptor::Adapt(cameraImages[0])};
105
106 // convert to gray
107 cv::Mat grayImage;
108 cv::Mat resultImage = cv::cvarrToMat(ppIplImages[0]);
109 cv::cvtColor(resultImage, grayImage, cv::COLOR_BGR2GRAY);
110
111 std::vector<cv::Point2f> features;
112
113 cv::Size size = cv::Size(chessboardWidth, chessboardHeight);
114
115
116 if (useChessboard)
117 {
118 // + cv::CALIB_CB_FAST_CHECK)
119 bool foundCorners = cv::findChessboardCorners(
120 grayImage, size, features, cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE);
121
122 if (foundCorners)
123 {
124 float avgX = 0.f, avgY = 0.f;
125 for (cv::Point2f point : features)
126 {
127 avgX += point.x;
128 avgY += point.y;
129 }
130 avgX /= features.size();
131 avgY /= features.size();
132
133 cv::Point2f imgCenter(imageWidth / 2, imageHeight / 2);
134 cv::Point2f chessboardCenter(avgX, avgY);
135 cv::Point2f point(avgX, imageHeight / 2);
136 cv::circle(resultImage, chessboardCenter, 2, CV_RGB(255, 0, 0), -1);
137 cv::circle(resultImage, imgCenter, 2, CV_RGB(255, 0, 0), -1);
138 cv::line(resultImage, chessboardCenter, imgCenter, CV_RGB(0, 0, 255), 1);
139 cv::line(resultImage, chessboardCenter, point, CV_RGB(0, 255, 0), 1);
140 cv::line(resultImage, imgCenter, point, CV_RGB(0, 255, 0), 1);
141
142 float trackingErrorX = avgX - (imageWidth / 2);
143 float trackingErrorY = avgY - (imageHeight / 2);
144
145 float angleX = (trackingErrorX / imageWidth) * 59.7;
146 float angleY = (trackingErrorY / imageHeight) * 44.775;
147
148
149 StringVariantBaseMap debugValues;
150 debugValues["trackingErrorX"] = new Variant(trackingErrorX);
151 debugValues["trackingErrorY"] = new Variant(trackingErrorY);
152 debugValues["angleX"] = new Variant(angleX);
153 debugValues["angleY"] = new Variant(angleY);
154
155
156 debugObserver->setDebugChannel("TrackingError", debugValues);
157
158
159 prx->reportNewTrackingError(trackingErrorX, trackingErrorY, angleX, angleY);
160 }
161 else
162 {
163 ARMARX_WARNING << deactivateSpam(3) << "Chessboard NOT found!";
164 return;
165 }
166 }
167 else
168 {
169 //TODO: calculate tracking error with vectors
170 }
171
172
173 CByteImage* resultImages[1] = {IplImageAdaptor::Adapt(ppIplImages[0])};
174 provideResultImages(resultImages);
175
176 if (frameRate > 0.0)
177 {
178 fpsCounter.assureFPS(frameRate);
179 }
180}
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
void onExitImageProcessor() override
Exit the ImapeProcessor component.
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void process() override
Process the vision component.
void onInitImageProcessor() override
Setup the vision component.
The Variant class is described here: Variants.
Definition Variant.h:224
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
bool waitForImages(int milliseconds=1000)
Wait for new images.
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
int getImages(CByteImage **ppImages)
Poll images from provider.
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.