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
27
28using namespace armarx;
29
36
37void
39{
40 providerName = getProperty<std::string>("providerName").getValue();
41 usingImageProvider(providerName);
42
43 offeringTopic(getProperty<std::string>("TrackingErrorTopicName").getValue());
44
45 offeringTopic(getProperty<std::string>("DebugObserverName").getValue());
46
47 frameRate = getProperty<float>("Framerate").getValue();
48
49 useChessboard = getProperty<bool>("UseChessBoard").getValue();
50
51 chessboardWidth = getProperty<int>("Chessboard.Width").getValue();
52 chessboardHeight = getProperty<int>("Chessboard.Height").getValue();
53}
54
55void
57{
58 std::unique_lock lock(imageMutex);
59
60 visionx::ImageProviderInfo imageProviderInfo = getImageProvider(providerName);
61 imageProviderPrx = getProxy<visionx::ImageProviderInterfacePrx>(providerName);
62
63 cameraImages = new CByteImage*[2];
64 cameraImages[0] = visionx::tools::createByteImage(imageProviderInfo);
65 cameraImages[1] = visionx::tools::createByteImage(imageProviderInfo);
66
67
69 getProperty<std::string>("DebugObserverName").getValue());
70
72 getProperty<std::string>("TrackingErrorTopicName").getValue());
73
74 imageWidth = imageProviderPrx->getImageFormat().dimension.width;
75 imageHeight = imageProviderPrx->getImageFormat().dimension.height;
76
78 1, imageProviderPrx->getImageFormat().dimension, imageProviderPrx->getImageFormat().type);
79}
80
81void
85
86void
88{
89 std::unique_lock lock(imageMutex);
90
91 if (!waitForImages(getProperty<std::string>("providerName").getValue(), 1000))
92 {
93 ARMARX_WARNING << "Timeout while waiting for camera images (>1000ms)";
94 return;
95 }
96
97 int numImages = getImages(cameraImages);
98
99 if (numImages == 0)
100 {
101 ARMARX_WARNING << "Didn't receive one image! Aborting!";
102 return;
103 }
104
105 IplImage* ppIplImages[1] = {IplImageAdaptor::Adapt(cameraImages[0])};
106
107 // convert to gray
108 cv::Mat grayImage;
109 cv::Mat resultImage = cv::cvarrToMat(ppIplImages[0]);
110 cv::cvtColor(resultImage, grayImage, cv::COLOR_BGR2GRAY);
111
112 std::vector<cv::Point2f> features;
113
114 cv::Size size = cv::Size(chessboardWidth, chessboardHeight);
115
116
117 if (useChessboard)
118 {
119 // + cv::CALIB_CB_FAST_CHECK)
120 bool foundCorners = cv::findChessboardCorners(
121 grayImage, size, features, cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE);
122
123 if (foundCorners)
124 {
125 float avgX = 0.f, avgY = 0.f;
126 for (cv::Point2f point : features)
127 {
128 avgX += point.x;
129 avgY += point.y;
130 }
131 avgX /= features.size();
132 avgY /= features.size();
133
134 cv::Point2f imgCenter(imageWidth / 2, imageHeight / 2);
135 cv::Point2f chessboardCenter(avgX, avgY);
136 cv::Point2f point(avgX, imageHeight / 2);
137 cv::circle(resultImage, chessboardCenter, 2, CV_RGB(255, 0, 0), -1);
138 cv::circle(resultImage, imgCenter, 2, CV_RGB(255, 0, 0), -1);
139 cv::line(resultImage, chessboardCenter, imgCenter, CV_RGB(0, 0, 255), 1);
140 cv::line(resultImage, chessboardCenter, point, CV_RGB(0, 255, 0), 1);
141 cv::line(resultImage, imgCenter, point, CV_RGB(0, 255, 0), 1);
142
143 float trackingErrorX = avgX - (imageWidth / 2);
144 float trackingErrorY = avgY - (imageHeight / 2);
145
146 float angleX = (trackingErrorX / imageWidth) * 59.7;
147 float angleY = (trackingErrorY / imageHeight) * 44.775;
148
149
150 StringVariantBaseMap debugValues;
151 debugValues["trackingErrorX"] = new Variant(trackingErrorX);
152 debugValues["trackingErrorY"] = new Variant(trackingErrorY);
153 debugValues["angleX"] = new Variant(angleX);
154 debugValues["angleY"] = new Variant(angleY);
155
156
157 debugObserver->setDebugChannel("TrackingError", debugValues);
158
159
160 prx->reportNewTrackingError(trackingErrorX, trackingErrorY, angleX, angleY);
161 }
162 else
163 {
164 ARMARX_WARNING << deactivateSpam(3) << "Chessboard NOT found!";
165 return;
166 }
167 }
168 else
169 {
170 //TODO: calculate tracking error with vectors
171 }
172
173
174 CByteImage* resultImages[1] = {IplImageAdaptor::Adapt(ppIplImages[0])};
175 provideResultImages(resultImages);
176
177 if (frameRate > 0.0)
178 {
179 fpsCounter.assureFPS(frameRate);
180 }
181}
182
183namespace armarx
184{
186} // namespace armarx
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
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)
Brief description of class TrackingError.
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.
static std::string GetDefaultName()
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.