26 #define SMOOTHING_RADIUS 3
32 providerName = getProperty<std::string>(
"providerName").getValue();
33 usingImageProvider(providerName);
35 frameRate = getProperty<float>(
"Framerate").getValue();
36 drawFeatures = getProperty<bool>(
"drawFeatures").getValue();
41 std::unique_lock lock(imageMutex);
44 imageProviderPrx = getProxy<visionx::ImageProviderInterfacePrx>(providerName);
46 cameraImages =
new CByteImage*[2];
51 enableResultImages(1, imageProviderPrx->getImageFormat().dimension, imageProviderPrx->getImageFormat().type);
57 std::unique_lock lock(imageMutex);
58 while (oldImages.size() != 0)
60 oldImages.front().release();
63 deltaTransformations.clear();
67 prevTransform.release();
72 std::unique_lock lock(imageMutex);
74 if (!waitForImages(getProperty<std::string>(
"providerName").getValue(), 1000))
76 ARMARX_WARNING <<
"Timeout while waiting for camera images (>1000ms)";
80 armarx::MetaInfoSizeBasePtr info;
81 int numImages = getImages(getProperty<std::string>(
"providerName").getValue(), cameraImages, info);
89 IplImage* ppIplImages[1] = { IplImageAdaptor::Adapt(cameraImages[0]) };
93 cv::Mat curr = cv::cvarrToMat(ppIplImages[0]);
94 cv::cvtColor(curr, currGrey, cv::COLOR_BGR2GRAY);
96 cv::Mat tmpImg(curr.size(), curr.type());
100 int maxCorners = 100;
101 double qualityLevel = 0.01;
102 double minDistance = 5.0;
105 bool useHarrisDetector =
true;
107 std::vector< cv::Point2f > currFeatures;
109 cv::goodFeaturesToTrack(currGrey, currFeatures, maxCorners, qualityLevel, minDistance, mask, blockSize, useHarrisDetector, k);
112 if (prev.data == NULL || prevGrey.data == NULL)
117 prevFeatures = currFeatures;
121 std::vector<uchar>
status;
122 std::vector<float> error;
124 cv::calcOpticalFlowPyrLK(prevGrey, currGrey, prevFeatures, currFeatures,
status, error, cv::Size(21, 21), cv::OPTFLOW_USE_INITIAL_FLOW);
127 std::vector< cv::Point2f > prevOverlapFeatures, currOverlapFeatures;
128 for (
unsigned int i = 0; i <
status.size(); i++)
130 if (
status[i] && error[i] < 25.f)
132 prevOverlapFeatures.push_back(prevFeatures[i]);
133 currOverlapFeatures.push_back(currFeatures[i]);
138 cv::Mat currTransform = cv::estimateRigidTransform(prevOverlapFeatures, currOverlapFeatures,
false);
141 if (currTransform.data == NULL)
147 oldImages.push(tmpImg);
149 currTransform.copyTo(prevTransform);
152 double dx = currTransform.at<
double>(0, 2);
153 double dy = currTransform.at<
double>(1, 2);
154 double da = atan2(currTransform.at<
double>(1, 0), currTransform.at<
double>(0, 0));
156 deltaTransformations.push_back(
cv::Vec3d(dx, dy, da));
177 newTransformation += -deltaTransformations[currFrameIndex + i];
184 transform.at<
double>(0, 0) = cos(newTransformation[2]);
185 transform.at<
double>(0, 1) = -sin(newTransformation[2]);
186 transform.at<
double>(1, 0) = sin(newTransformation[2]);
187 transform.at<
double>(1, 1) = cos(newTransformation[2]);
189 transform.at<
double>(0, 2) = newTransformation[0];
190 transform.at<
double>(1, 2) = newTransformation[1];
192 cv::Mat currImage = oldImages.front();
197 cv::warpAffine(currImage, result,
transform, currImage.size());
201 for (
const cv::Point2f& p : prevOverlapFeatures)
203 cv::circle(result, p, 2, CV_RGB(0, 255, 0), -1);
208 CByteImage* output_cimage =
new CByteImage();
211 CByteImage* resultImages[1] = {output_cimage};
212 provideResultImages(std::move(resultImages));
224 std::unique_lock lock(imageMutex);
225 ARMARX_LOG <<
"Resetting OpenCV stabilization!";
226 while (oldImages.size() != 0)
230 deltaTransformations.clear();
231 prevFeatures.clear();
233 prevGrey.data = NULL;
234 prevTransform.data = NULL;