@@ -39,6 +39,29 @@ static void getInvertMatrix(Mat& src, Size dstSize, Mat& M)
39
39
invert (M,M);
40
40
}
41
41
42
+ static cv::Mat getInverseAffine (const cv::Mat& affine)
43
+ {
44
+ // Extract the 2x2 part
45
+ cv::Mat rotationScaling = affine (cv::Rect (0 , 0 , 2 , 2 ));
46
+
47
+ // Invert the 2x2 part
48
+ cv::Mat inverseRotationScaling;
49
+ cv::invert (rotationScaling, inverseRotationScaling);
50
+
51
+ // Extract the translation part
52
+ cv::Mat translation = affine (cv::Rect (2 , 0 , 1 , 2 ));
53
+
54
+ // Compute the new translation
55
+ cv::Mat inverseTranslation = -inverseRotationScaling * translation;
56
+
57
+ // Construct the inverse affine matrix
58
+ cv::Mat inverseAffine = cv::Mat::zeros (2 , 3 , CV_32F);
59
+ inverseRotationScaling.copyTo (inverseAffine (cv::Rect (0 , 0 , 2 , 2 )));
60
+ inverseTranslation.copyTo (inverseAffine (cv::Rect (2 , 0 , 1 , 2 )));
61
+
62
+ return inverseAffine;
63
+ }
64
+
42
65
typedef perf::TestBaseWithParam<Size> WarpPerspective2PlanePerfTest;
43
66
44
67
PERF_TEST_P (WarpPerspective2PlanePerfTest, run,
@@ -93,4 +116,113 @@ PERF_TEST_P(WarpPerspectivePerfTest, run,
93
116
SANITY_CHECK_NOTHING ();
94
117
}
95
118
119
+ typedef TestBaseWithParam< tuple<MatType, Size> > WarpAffine3ChannelPerf;
120
+
121
+ PERF_TEST_P (WarpAffine3ChannelPerf, run, Combine(
122
+ Values (CV_8UC3),
123
+ Values( szVGA, sz720p, sz1080p)
124
+ ))
125
+ {
126
+ Size sz, szSrc (512 , 512 );
127
+ int dataType;
128
+ dataType = get<0 >(GetParam ());
129
+ sz = get<1 >(GetParam ());
130
+
131
+ cv::Mat src (szSrc, dataType), dst (sz, dataType);
132
+
133
+ cvtest::fillGradient (src);
134
+
135
+ // Affine matrix
136
+ float angle = 30.0 ; // Rotation angle in degrees
137
+ float scale = 2.2 ; // Scale factor
138
+ cv::Mat affine = cv::getRotationMatrix2D (cv::Point2f (100 , 100 ), angle, scale);
139
+
140
+ // Compute the inverse affine matrix
141
+ cv::Mat inverseAffine = getInverseAffine (affine);
142
+
143
+ // Create the dstBorder array
144
+ Mat dstBorder;
145
+
146
+ declare.in (src).out (dst);
147
+
148
+ while (next ())
149
+ {
150
+ startTimer ();
151
+ cv::fastcv::warpAffine3Channel (src, dst, inverseAffine, sz, dstBorder);
152
+ stopTimer ();
153
+ }
154
+
155
+ SANITY_CHECK_NOTHING ();
156
+ }
157
+
158
+ typedef perf::TestBaseWithParam<std::tuple<cv::Size, cv::Point2f, cv::Mat>> WarpAffineROIPerfTest;
159
+
160
+ PERF_TEST_P (WarpAffineROIPerfTest, run, ::testing::Combine(
161
+ ::testing::Values (cv::Size(50 , 50 ), cv::Size(100 , 100 )), // patch size
162
+ ::testing::Values(cv::Point2f(50 .0f , 50 .0f ), cv::Point2f(100 .0f , 100 .0f )), // position
163
+ ::testing::Values((cv::Mat_<float >(2 , 2 ) << 1, 0, 0, 1), // identity matrix
164
+ (cv::Mat_<float >(2 , 2 ) << cos(CV_PI), -sin(CV_PI), sin(CV_PI), cos(CV_PI))) // rotation matrix
165
+ ))
166
+ {
167
+ cv::Size patchSize = std::get<0 >(GetParam ());
168
+ cv::Point2f position = std::get<1 >(GetParam ());
169
+ cv::Mat affine = std::get<2 >(GetParam ());
170
+
171
+ cv::Mat src = cv::imread (cvtest::findDataFile (" cv/shared/baboon.png" ), cv::IMREAD_GRAYSCALE);
172
+ cv::Mat patch;
173
+
174
+ while (next ())
175
+ {
176
+ startTimer ();
177
+ cv::fastcv::warpAffineROI (src, position, affine, patch, patchSize);
178
+ stopTimer ();
179
+ }
180
+
181
+ SANITY_CHECK_NOTHING ();
182
+ }
183
+
184
+ typedef TestBaseWithParam<tuple<int , int > > WarpAffinePerfTest;
185
+
186
+ PERF_TEST_P (WarpAffinePerfTest, run, ::testing::Combine(
187
+ ::testing::Values (cv::InterpolationFlags::INTER_NEAREST, cv::InterpolationFlags::INTER_LINEAR, cv::InterpolationFlags::INTER_AREA),
188
+ ::testing::Values(0 , 255 ) // Black and white borders
189
+ ))
190
+ {
191
+ // Load the source image
192
+ cv::Mat src = cv::imread (cvtest::findDataFile (" cv/shared/baboon.png" ), cv::IMREAD_GRAYSCALE);
193
+ ASSERT_FALSE (src.empty ());
194
+
195
+ // Generate random values for the affine matrix
196
+ std::srand (std::time (0 ));
197
+ float angle = static_cast <float >(std::rand () % 360 ); // Random angle between 0 and 360 degrees
198
+ float scale = static_cast <float >(std::rand () % 200 ) / 100 .0f + 0 .5f ; // Random scale between 0.5 and 2.5
199
+ float tx = static_cast <float >(std::rand () % 100 ) - 50 ; // Random translation between -50 and 50
200
+ float ty = static_cast <float >(std::rand () % 100 ) - 50 ; // Random translation between -50 and 50
201
+ float radians = angle * CV_PI / 180.0 ;
202
+ cv::Mat affine = (cv::Mat_<float >(2 , 3 ) << scale * cos (radians), -scale * sin (radians), tx,
203
+ scale * sin (radians), scale * cos (radians), ty);
204
+
205
+ // Compute the inverse affine matrix
206
+ cv::Mat inverseAffine = getInverseAffine (affine);
207
+
208
+ // Define the destination size
209
+ cv::Size dsize (src.cols , src.rows );
210
+
211
+ // Define the output matrix
212
+ cv::Mat dst;
213
+
214
+ // Get the parameters
215
+ int interpolation = std::get<0 >(GetParam ());
216
+ int borderValue = std::get<1 >(GetParam ());
217
+
218
+ while (next ())
219
+ {
220
+ startTimer ();
221
+ cv::fastcv::warpAffine (src, dst, inverseAffine, dsize, interpolation, borderValue);
222
+ stopTimer ();
223
+ }
224
+
225
+ SANITY_CHECK_NOTHING ();
226
+ }
227
+
96
228
} // namespace
0 commit comments