27 #define SMOOTHING_RADIUS 3
34 providerName = getProperty<std::string>(
"providerName").getValue();
35 usingImageProvider(providerName);
37 frameRate = getProperty<float>(
"Framerate").getValue();
38 drawFeatures = getProperty<bool>(
"drawFeatures").getValue();
44 std::unique_lock lock(imageMutex);
47 imageProviderPrx = getProxy<visionx::ImageProviderInterfacePrx>(providerName);
49 cameraImages =
new CByteImage*[2];
55 1, imageProviderPrx->getImageFormat().dimension, imageProviderPrx->getImageFormat().type);
61 std::unique_lock lock(imageMutex);
62 while (oldImages.size() != 0)
64 oldImages.front().release();
67 deltaTransformations.clear();
71 prevTransform.release();
77 std::unique_lock lock(imageMutex);
79 if (!waitForImages(getProperty<std::string>(
"providerName").getValue(), 1000))
81 ARMARX_WARNING <<
"Timeout while waiting for camera images (>1000ms)";
85 armarx::MetaInfoSizeBasePtr info;
87 getImages(getProperty<std::string>(
"providerName").getValue(), cameraImages, info);
95 IplImage* ppIplImages[1] = {IplImageAdaptor::Adapt(cameraImages[0])};
99 cv::Mat curr = cv::cvarrToMat(ppIplImages[0]);
100 cv::cvtColor(curr, currGrey, cv::COLOR_BGR2GRAY);
102 cv::Mat tmpImg(curr.size(), curr.type());
106 int maxCorners = 100;
107 double qualityLevel = 0.01;
108 double minDistance = 5.0;
111 bool useHarrisDetector =
true;
113 std::vector<cv::Point2f> currFeatures;
115 cv::goodFeaturesToTrack(currGrey,
126 if (prev.data == NULL || prevGrey.data == NULL)
131 prevFeatures = currFeatures;
135 std::vector<uchar>
status;
136 std::vector<float> error;
138 cv::calcOpticalFlowPyrLK(prevGrey,
145 cv::OPTFLOW_USE_INITIAL_FLOW);
148 std::vector<cv::Point2f> prevOverlapFeatures, currOverlapFeatures;
149 for (
unsigned int i = 0; i <
status.size(); i++)
151 if (
status[i] && error[i] < 25.f)
153 prevOverlapFeatures.push_back(prevFeatures[i]);
154 currOverlapFeatures.push_back(currFeatures[i]);
159 cv::Mat currTransform =
160 cv::estimateRigidTransform(prevOverlapFeatures, currOverlapFeatures,
false);
163 if (currTransform.data == NULL)
169 oldImages.push(tmpImg);
171 currTransform.copyTo(prevTransform);
174 double dx = currTransform.at<
double>(0, 2);
175 double dy = currTransform.at<
double>(1, 2);
176 double da = atan2(currTransform.at<
double>(1, 0), currTransform.at<
double>(0, 0));
178 deltaTransformations.push_back(
cv::Vec3d(dx, dy, da));
199 newTransformation += -deltaTransformations[currFrameIndex + i];
206 transform.at<
double>(0, 0) = cos(newTransformation[2]);
207 transform.at<
double>(0, 1) = -sin(newTransformation[2]);
208 transform.at<
double>(1, 0) = sin(newTransformation[2]);
209 transform.at<
double>(1, 1) = cos(newTransformation[2]);
211 transform.at<
double>(0, 2) = newTransformation[0];
212 transform.at<
double>(1, 2) = newTransformation[1];
214 cv::Mat currImage = oldImages.front();
219 cv::warpAffine(currImage, result,
transform, currImage.size());
223 for (
const cv::Point2f& p : prevOverlapFeatures)
225 cv::circle(result, p, 2, CV_RGB(0, 255, 0), -1);
230 CByteImage* output_cimage =
new CByteImage();
233 CByteImage* resultImages[1] = {output_cimage};
234 provideResultImages(std::move(resultImages));
247 std::unique_lock lock(imageMutex);
248 ARMARX_LOG <<
"Resetting OpenCV stabilization!";
249 while (oldImages.size() != 0)
253 deltaTransformations.clear();
254 prevFeatures.clear();
256 prevGrey.data = NULL;
257 prevTransform.data = NULL;