@@ -121,11 +121,13 @@ void ImageProcessing::calculateLaplacianImage(
121
121
bool ImageProcessing::findBestMatch (
122
122
const Image& sourceImage,
123
123
const Image& templateImage,
124
- cv::Point2d & matchedPosition,
124
+ cv::Point3d & matchedPosition,
125
125
double matchAcceptanceThreshold,
126
+ double matchYawRange,
127
+ double matchYawStep,
126
128
bool matchImageGradients,
127
129
bool displayMatch) {
128
- Image sourceInput, templateInput, resultOutput ;
130
+ Image sourceInput, templateInput;
129
131
130
132
if (matchImageGradients) {
131
133
calculateGradientImage (sourceImage, sourceInput);
@@ -138,19 +140,33 @@ bool ImageProcessing::findBestMatch(
138
140
replaceNanWithZero (sourceInput);
139
141
replaceNanWithZero (templateInput);
140
142
141
- const auto method = CV_TM_CCORR_NORMED;
142
- cv::matchTemplate (sourceInput, templateInput, resultOutput, method);
143
+ constexpr int method = CV_TM_CCORR_NORMED;
143
144
145
+ Image warpedTemplate, resultMatrix, bestResultMatrix;
146
+ cv::Point3d bestPosition;
144
147
cv::Point2i maxPosition;
145
148
double maxValue;
146
- cv::minMaxLoc (resultOutput, nullptr , &maxValue, nullptr , &maxPosition);
149
+ double bestValue = 0 .;
150
+
151
+ for (double yaw = - matchYawRange / 2 .; yaw <= matchYawRange / 2 ;
152
+ yaw += matchYawStep) {
153
+ warpImage (templateInput, warpedTemplate, yaw);
154
+
155
+ cv::matchTemplate (sourceInput, warpedTemplate, resultMatrix, method);
156
+ cv::minMaxLoc (resultMatrix, nullptr , &maxValue, nullptr , &maxPosition);
157
+
158
+ if (maxValue > bestValue) {
159
+ bestPosition = cv::Point3d (maxPosition.x , maxPosition.y , yaw);
160
+ bestResultMatrix = resultMatrix;
161
+ }
162
+ }
147
163
148
164
const bool matchFound = maxValue > matchAcceptanceThreshold;
149
- if (matchFound) matchedPosition = cv::Point2d (maxPosition. x , maxPosition. y ) ;
165
+ if (matchFound) matchedPosition = bestPosition ;
150
166
151
167
if (displayMatch && matchFound)
152
- displayMatchedPosition (sourceInput, templateInput, resultOutput ,
153
- matchedPosition);
168
+ displayMatchedPosition (sourceInput, warpedTemplate, bestResultMatrix ,
169
+ cv::Point2d ( matchedPosition. x , matchedPosition. y ) );
154
170
155
171
return matchFound;
156
172
}
@@ -179,7 +195,7 @@ void ImageProcessing::displayMatchedPosition(
179
195
}
180
196
181
197
void ImageProcessing::convertPositionToMapCoordinates (
182
- cv::Point2d & imagePosition,
198
+ cv::Point3d & imagePosition,
183
199
const Image& image,
184
200
double mapResolution) {
185
201
double mapPositionX = std::round (image.rows / 2 .) - imagePosition.y ;
@@ -193,5 +209,15 @@ void ImageProcessing::replaceNanWithZero(Image& image) {
193
209
image.setTo (0 ., image != image);
194
210
}
195
211
212
+ void ImageProcessing::warpImage (
213
+ const Image& inputImage,
214
+ Image& outputImage,
215
+ double angle) {
216
+ const cv::Point2f center (inputImage.cols / 2 .f , inputImage.rows / 2 .f );
217
+ Image rotationMatrix = cv::getRotationMatrix2D (center, angle, 1 .);
218
+
219
+ cv::warpAffine (inputImage, outputImage, rotationMatrix, inputImage.size ());
220
+ }
221
+
196
222
} // namespace ga_slam
197
223
0 commit comments