mirror of
https://github.com/opencv/opencv.git
synced 2025-07-26 07:07:37 +08:00
Merge pull request #16841 from TolyaTalamanov:at/warp-perspective
G-API: Implement WarpPerspective * Implement WarpPerspective kernel * Fix comment to review
This commit is contained in:
parent
b0563ce368
commit
c303aaa94d
@ -486,10 +486,18 @@ namespace core {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
G_TYPED_KERNEL(GWarpPerspective, <GMat(GMat, const Mat&, Size, int, int, const cv::Scalar&)>, "org.opencv.core.warpPerspective") {
|
||||||
|
static GMatDesc outMeta(GMatDesc in, const Mat&, Size dsize, int, int borderMode, const cv::Scalar&) {
|
||||||
|
GAPI_Assert((borderMode == cv::BORDER_CONSTANT || borderMode == cv::BORDER_REPLICATE) &&
|
||||||
|
"cv::gapi::warpPerspective supports only cv::BORDER_CONSTANT and cv::BORDER_REPLICATE border modes");
|
||||||
|
return in.withType(in.depth, in.chan).withSize(dsize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
G_TYPED_KERNEL(GWarpAffine, <GMat(GMat, const Mat&, Size, int, int, const cv::Scalar&)>, "org.opencv.core.warpAffine") {
|
G_TYPED_KERNEL(GWarpAffine, <GMat(GMat, const Mat&, Size, int, int, const cv::Scalar&)>, "org.opencv.core.warpAffine") {
|
||||||
static GMatDesc outMeta(GMatDesc in, const Mat&, Size dsize, int, int border_mode, const cv::Scalar&) {
|
static GMatDesc outMeta(GMatDesc in, const Mat&, Size dsize, int, int border_mode, const cv::Scalar&) {
|
||||||
GAPI_Assert(border_mode != cv::BORDER_TRANSPARENT &&
|
GAPI_Assert(border_mode != cv::BORDER_TRANSPARENT &&
|
||||||
"cv::BORDER_TRANSPARENT mode isn't support in G-API");
|
"cv::BORDER_TRANSPARENT mode is not supported in cv::gapi::warpAffine");
|
||||||
return in.withType(in.depth, in.chan).withSize(dsize);
|
return in.withType(in.depth, in.chan).withSize(dsize);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1662,6 +1670,30 @@ number of channels as src and the depth =ddepth.
|
|||||||
GAPI_EXPORTS GMat normalize(const GMat& src, double alpha, double beta,
|
GAPI_EXPORTS GMat normalize(const GMat& src, double alpha, double beta,
|
||||||
int norm_type, int ddepth = -1);
|
int norm_type, int ddepth = -1);
|
||||||
|
|
||||||
|
/** @brief Applies a perspective transformation to an image.
|
||||||
|
|
||||||
|
The function warpPerspective transforms the source image using the specified matrix:
|
||||||
|
|
||||||
|
\f[\texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} ,
|
||||||
|
\frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right )\f]
|
||||||
|
|
||||||
|
when the flag #WARP_INVERSE_MAP is set. Otherwise, the transformation is first inverted with invert
|
||||||
|
and then put in the formula above instead of M. The function cannot operate in-place.
|
||||||
|
|
||||||
|
@param src input image.
|
||||||
|
@param M \f$3\times 3\f$ transformation matrix.
|
||||||
|
@param dsize size of the output image.
|
||||||
|
@param flags combination of interpolation methods (#INTER_LINEAR or #INTER_NEAREST) and the
|
||||||
|
optional flag #WARP_INVERSE_MAP, that sets M as the inverse transformation (
|
||||||
|
\f$\texttt{dst}\rightarrow\texttt{src}\f$ ).
|
||||||
|
@param borderMode pixel extrapolation method (#BORDER_CONSTANT or #BORDER_REPLICATE).
|
||||||
|
@param borderValue value used in case of a constant border; by default, it equals 0.
|
||||||
|
|
||||||
|
@sa warpAffine, resize, remap, getRectSubPix, perspectiveTransform
|
||||||
|
*/
|
||||||
|
GAPI_EXPORTS GMat warpPerspective(const GMat& src, const Mat& M, const Size& dsize, int flags = cv::INTER_LINEAR,
|
||||||
|
int borderMode = cv::BORDER_CONSTANT, const Scalar& borderValue = Scalar());
|
||||||
|
|
||||||
/** @brief Applies an affine transformation to an image.
|
/** @brief Applies an affine transformation to an image.
|
||||||
|
|
||||||
The function warpAffine transforms the source image using the specified matrix:
|
The function warpAffine transforms the source image using the specified matrix:
|
||||||
|
@ -371,6 +371,12 @@ GMat normalize(const GMat& _src, double a, double b,
|
|||||||
return core::GNormalize::on(_src, a, b, norm_type, ddepth);
|
return core::GNormalize::on(_src, a, b, norm_type, ddepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GMat warpPerspective(const GMat& src, const Mat& M, const Size& dsize, int flags,
|
||||||
|
int borderMode, const Scalar& borderValue)
|
||||||
|
{
|
||||||
|
return core::GWarpPerspective::on(src, M, dsize, flags, borderMode, borderValue);
|
||||||
|
}
|
||||||
|
|
||||||
GMat warpAffine(const GMat& src, const Mat& M, const Size& dsize, int flags,
|
GMat warpAffine(const GMat& src, const Mat& M, const Size& dsize, int flags,
|
||||||
int borderMode, const Scalar& borderValue)
|
int borderMode, const Scalar& borderValue)
|
||||||
{
|
{
|
||||||
|
@ -558,6 +558,15 @@ GAPI_OCV_KERNEL(GCPUNormalize, cv::gapi::core::GNormalize)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GAPI_OCV_KERNEL(GCPUWarpPerspective, cv::gapi::core::GWarpPerspective)
|
||||||
|
{
|
||||||
|
static void run(const cv::Mat& src, const cv::Mat& M, const cv::Size& dsize,
|
||||||
|
int flags, int borderMode, const cv::Scalar& borderValue, cv::Mat& out)
|
||||||
|
{
|
||||||
|
cv::warpPerspective(src, out, M, dsize, flags, borderMode, borderValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
GAPI_OCV_KERNEL(GCPUWarpAffine, cv::gapi::core::GWarpAffine)
|
GAPI_OCV_KERNEL(GCPUWarpAffine, cv::gapi::core::GWarpAffine)
|
||||||
{
|
{
|
||||||
static void run(const cv::Mat& src, const cv::Mat& M, const cv::Size& dsize,
|
static void run(const cv::Mat& src, const cv::Mat& M, const cv::Size& dsize,
|
||||||
@ -636,6 +645,7 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels()
|
|||||||
, GCPUConvertTo
|
, GCPUConvertTo
|
||||||
, GCPUSqrt
|
, GCPUSqrt
|
||||||
, GCPUNormalize
|
, GCPUNormalize
|
||||||
|
, GCPUWarpPerspective
|
||||||
, GCPUWarpAffine
|
, GCPUWarpAffine
|
||||||
>();
|
>();
|
||||||
return pkg;
|
return pkg;
|
||||||
|
@ -142,8 +142,13 @@ struct BackendOutputAllocationTest : TestWithParamBase<>
|
|||||||
struct BackendOutputAllocationLargeSizeWithCorrectSubmatrixTest : BackendOutputAllocationTest {};
|
struct BackendOutputAllocationLargeSizeWithCorrectSubmatrixTest : BackendOutputAllocationTest {};
|
||||||
GAPI_TEST_FIXTURE(ReInitOutTest, initNothing, <cv::Size>, 1, out_sz)
|
GAPI_TEST_FIXTURE(ReInitOutTest, initNothing, <cv::Size>, 1, out_sz)
|
||||||
|
|
||||||
GAPI_TEST_FIXTURE(WarpAffineTest, initMatrixRandU, FIXTURE_API(CompareMats, double , double, int, int, cv::Scalar), 6,
|
GAPI_TEST_FIXTURE(WarpPerspectiveTest, initMatrixRandU,
|
||||||
cmpF, angle, scale, flags, border_mode, border_value)
|
FIXTURE_API(CompareMats, double , double, int, int, cv::Scalar),
|
||||||
|
6, cmpF, angle, scale, flags, border_mode, border_value)
|
||||||
|
|
||||||
|
GAPI_TEST_FIXTURE(WarpAffineTest, initMatrixRandU,
|
||||||
|
FIXTURE_API(CompareMats, double , double, int, int, cv::Scalar),
|
||||||
|
6, cmpF, angle, scale, flags, border_mode, border_value)
|
||||||
} // opencv_test
|
} // opencv_test
|
||||||
|
|
||||||
#endif //OPENCV_GAPI_CORE_TESTS_HPP
|
#endif //OPENCV_GAPI_CORE_TESTS_HPP
|
||||||
|
@ -1266,6 +1266,30 @@ TEST_P(SqrtTest, AccuracyTest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(WarpPerspectiveTest, AccuracyTest)
|
||||||
|
{
|
||||||
|
cv::Point center{in_mat1.size() / 2};
|
||||||
|
cv::Mat xy = cv::getRotationMatrix2D(center, angle, scale);
|
||||||
|
cv::Matx13d z (0, 0, 1);
|
||||||
|
cv::Mat transform_mat;
|
||||||
|
cv::vconcat(xy, z, transform_mat);
|
||||||
|
|
||||||
|
// G-API code //////////////////////////////////////////////////////////////
|
||||||
|
cv::GMat in;
|
||||||
|
auto out = cv::gapi::warpPerspective(in, transform_mat, in_mat1.size(), flags, border_mode, border_value);
|
||||||
|
|
||||||
|
cv::GComputation c(in, out);
|
||||||
|
c.apply(in_mat1, out_mat_gapi, getCompileArgs());
|
||||||
|
|
||||||
|
// OpenCV code /////////////////////////////////////////////////////////////
|
||||||
|
cv::warpPerspective(in_mat1, out_mat_ocv, cv::Mat(transform_mat), in_mat1.size(), flags, border_mode, border_value);
|
||||||
|
|
||||||
|
// Comparison //////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(WarpAffineTest, AccuracyTest)
|
TEST_P(WarpAffineTest, AccuracyTest)
|
||||||
{
|
{
|
||||||
cv::Point center{in_mat1.size() / 2};
|
cv::Point center{in_mat1.size() / 2};
|
||||||
|
@ -435,6 +435,19 @@ INSTANTIATE_TEST_CASE_P(ConcatHorVecTestCPU, ConcatHorVecTest,
|
|||||||
Values(-1),
|
Values(-1),
|
||||||
Values(CORE_CPU)));
|
Values(CORE_CPU)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(WarpPerspectiveTestCPU, WarpPerspectiveTest,
|
||||||
|
Combine(Values(CV_8UC1, CV_8UC3),
|
||||||
|
Values(cv::Size(1280, 720),
|
||||||
|
cv::Size(640, 480)),
|
||||||
|
Values(-1),
|
||||||
|
Values(CORE_CPU),
|
||||||
|
Values(AbsExact().to_compare_obj()),
|
||||||
|
Values(-50.0, 90.0),
|
||||||
|
Values(0.6),
|
||||||
|
Values(cv::INTER_LINEAR),
|
||||||
|
Values(cv::BORDER_CONSTANT),
|
||||||
|
Values(cv::Scalar())));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(WarpAffineTestCPU, WarpAffineTest,
|
INSTANTIATE_TEST_CASE_P(WarpAffineTestCPU, WarpAffineTest,
|
||||||
Combine(Values(CV_8UC1, CV_8UC3),
|
Combine(Values(CV_8UC1, CV_8UC3),
|
||||||
Values(cv::Size(1280, 720),
|
Values(cv::Size(1280, 720),
|
||||||
|
Loading…
Reference in New Issue
Block a user