Merge pull request #18652 from OrestChura:oc/morphologyEx
[G-API]: morphologyEx() Standard Kernel Implementation * cv::gapi::morphologyEx() kernel - implemented (without separate 3x3 version) - tests added: check only different operations, not kernels/borders * Address comments: add `const` where needed * Replaced fundamental tyeps -> enums where needed - added operator<< overload for cv::MorphTypes for tests output
This commit is contained in:
parent
e12adcdf08
commit
5f1ca33c6f
@ -78,6 +78,14 @@ namespace imgproc {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
G_TYPED_KERNEL(GMorphologyEx, <GMat(GMat,MorphTypes,Mat,Point,int,BorderTypes,Scalar)>,
|
||||||
|
"org.opencv.imgproc.filters.morphologyEx") {
|
||||||
|
static GMatDesc outMeta(const GMatDesc &in, MorphTypes, Mat, Point, int,
|
||||||
|
BorderTypes, Scalar) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
G_TYPED_KERNEL(GSobel, <GMat(GMat,int,int,int,int,double,double,int,Scalar)>, "org.opencv.imgproc.filters.sobel") {
|
G_TYPED_KERNEL(GSobel, <GMat(GMat,int,int,int,int,double,double,int,Scalar)>, "org.opencv.imgproc.filters.sobel") {
|
||||||
static GMatDesc outMeta(GMatDesc in, int ddepth, int, int, int, double, double, int, Scalar) {
|
static GMatDesc outMeta(GMatDesc in, int ddepth, int, int, int, double, double, int, Scalar) {
|
||||||
return in.withDepth(ddepth);
|
return in.withDepth(ddepth);
|
||||||
@ -521,7 +529,7 @@ anchor is at the element center.
|
|||||||
@param iterations number of times erosion is applied.
|
@param iterations number of times erosion is applied.
|
||||||
@param borderType pixel extrapolation method, see cv::BorderTypes
|
@param borderType pixel extrapolation method, see cv::BorderTypes
|
||||||
@param borderValue border value in case of a constant border
|
@param borderValue border value in case of a constant border
|
||||||
@sa dilate
|
@sa dilate, morphologyEx
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS GMat erode(const GMat& src, const Mat& kernel, const Point& anchor = Point(-1,-1), int iterations = 1,
|
GAPI_EXPORTS GMat erode(const GMat& src, const Mat& kernel, const Point& anchor = Point(-1,-1), int iterations = 1,
|
||||||
int borderType = BORDER_CONSTANT,
|
int borderType = BORDER_CONSTANT,
|
||||||
@ -596,6 +604,37 @@ GAPI_EXPORTS GMat dilate3x3(const GMat& src, int iterations = 1,
|
|||||||
int borderType = BORDER_CONSTANT,
|
int borderType = BORDER_CONSTANT,
|
||||||
const Scalar& borderValue = morphologyDefaultBorderValue());
|
const Scalar& borderValue = morphologyDefaultBorderValue());
|
||||||
|
|
||||||
|
/** @brief Performs advanced morphological transformations.
|
||||||
|
|
||||||
|
The function can perform advanced morphological transformations using an erosion and dilation as
|
||||||
|
basic operations.
|
||||||
|
|
||||||
|
Any of the operations can be done in-place. In case of multi-channel images, each channel is
|
||||||
|
processed independently.
|
||||||
|
|
||||||
|
@note Function textual ID is "org.opencv.imgproc.filters.morphologyEx"
|
||||||
|
|
||||||
|
@param src Input image.
|
||||||
|
@param op Type of a morphological operation, see #MorphTypes
|
||||||
|
@param kernel Structuring element. It can be created using #getStructuringElement.
|
||||||
|
@param anchor Anchor position within the element. Both negative values mean that the anchor is at
|
||||||
|
the kernel center.
|
||||||
|
@param iterations Number of times erosion and dilation are applied.
|
||||||
|
@param borderType Pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not supported.
|
||||||
|
@param borderValue Border value in case of a constant border. The default value has a special
|
||||||
|
meaning.
|
||||||
|
@sa dilate, erode, getStructuringElement
|
||||||
|
@note The number of iterations is the number of times erosion or dilatation operation will be
|
||||||
|
applied. For instance, an opening operation (#MORPH_OPEN) with two iterations is equivalent to
|
||||||
|
apply successively: erode -> erode -> dilate -> dilate
|
||||||
|
(and not erode -> dilate -> erode -> dilate).
|
||||||
|
*/
|
||||||
|
GAPI_EXPORTS GMat morphologyEx(const GMat &src, const MorphTypes op, const Mat &kernel,
|
||||||
|
const Point &anchor = Point(-1,-1),
|
||||||
|
const int iterations = 1,
|
||||||
|
const BorderTypes borderType = BORDER_CONSTANT,
|
||||||
|
const Scalar &borderValue = morphologyDefaultBorderValue());
|
||||||
|
|
||||||
/** @brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator.
|
/** @brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator.
|
||||||
|
|
||||||
In all cases except one, the \f$\texttt{ksize} \times \texttt{ksize}\f$ separable kernel is used to
|
In all cases except one, the \f$\texttt{ksize} \times \texttt{ksize}\f$ separable kernel is used to
|
||||||
|
|||||||
@ -73,6 +73,13 @@ GMat dilate3x3(const GMat& src, int iterations,
|
|||||||
return dilate(src, cv::Mat(), cv::Point(-1,-1), iterations, borderType, borderValue);
|
return dilate(src, cv::Mat(), cv::Point(-1,-1), iterations, borderType, borderValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GMat morphologyEx(const GMat &src, const MorphTypes op, const Mat &kernel, const Point &anchor,
|
||||||
|
const int iterations, const BorderTypes borderType, const Scalar &borderValue)
|
||||||
|
{
|
||||||
|
return imgproc::GMorphologyEx::on(src, op, kernel, anchor, iterations,
|
||||||
|
borderType, borderValue);
|
||||||
|
}
|
||||||
|
|
||||||
GMat Sobel(const GMat& src, int ddepth, int dx, int dy, int ksize,
|
GMat Sobel(const GMat& src, int ddepth, int dx, int dy, int ksize,
|
||||||
double scale, double delta,
|
double scale, double delta,
|
||||||
int borderType, const Scalar& bordVal)
|
int borderType, const Scalar& bordVal)
|
||||||
|
|||||||
@ -145,6 +145,16 @@ GAPI_OCV_KERNEL(GCPUDilate, cv::gapi::imgproc::GDilate)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GAPI_OCV_KERNEL(GCPUMorphologyEx, cv::gapi::imgproc::GMorphologyEx)
|
||||||
|
{
|
||||||
|
static void run(const cv::Mat &in, const cv::MorphTypes op, const cv::Mat &kernel,
|
||||||
|
const cv::Point &anchor, const int iterations,
|
||||||
|
const cv::BorderTypes borderType, const cv::Scalar &borderValue, cv::Mat &out)
|
||||||
|
{
|
||||||
|
cv::morphologyEx(in, out, op, kernel, anchor, iterations, borderType, borderValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
GAPI_OCV_KERNEL(GCPUSobel, cv::gapi::imgproc::GSobel)
|
GAPI_OCV_KERNEL(GCPUSobel, cv::gapi::imgproc::GSobel)
|
||||||
{
|
{
|
||||||
static void run(const cv::Mat& in, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType,
|
static void run(const cv::Mat& in, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType,
|
||||||
@ -478,6 +488,7 @@ cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels()
|
|||||||
, GCPUMedianBlur
|
, GCPUMedianBlur
|
||||||
, GCPUErode
|
, GCPUErode
|
||||||
, GCPUDilate
|
, GCPUDilate
|
||||||
|
, GCPUMorphologyEx
|
||||||
, GCPUSobel
|
, GCPUSobel
|
||||||
, GCPUSobelXY
|
, GCPUSobelXY
|
||||||
, GCPULaplacian
|
, GCPULaplacian
|
||||||
|
|||||||
@ -46,6 +46,8 @@ GAPI_TEST_FIXTURE(Erode3x3Test, initMatrixRandN, FIXTURE_API(CompareMats,int), 2
|
|||||||
GAPI_TEST_FIXTURE(DilateTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int), 3,
|
GAPI_TEST_FIXTURE(DilateTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int), 3,
|
||||||
cmpF, kernSize, kernType)
|
cmpF, kernSize, kernType)
|
||||||
GAPI_TEST_FIXTURE(Dilate3x3Test, initMatrixRandN, FIXTURE_API(CompareMats,int), 2, cmpF, numIters)
|
GAPI_TEST_FIXTURE(Dilate3x3Test, initMatrixRandN, FIXTURE_API(CompareMats,int), 2, cmpF, numIters)
|
||||||
|
GAPI_TEST_FIXTURE(MorphologyExTest, initMatrixRandN, FIXTURE_API(CompareMats,MorphTypes),
|
||||||
|
2, cmpF, op)
|
||||||
GAPI_TEST_FIXTURE(SobelTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int,int), 4,
|
GAPI_TEST_FIXTURE(SobelTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int,int), 4,
|
||||||
cmpF, kernSize, dx, dy)
|
cmpF, kernSize, dx, dy)
|
||||||
GAPI_TEST_FIXTURE(SobelXYTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int,int,int), 5,
|
GAPI_TEST_FIXTURE(SobelXYTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int,int,int), 5,
|
||||||
|
|||||||
@ -290,6 +290,29 @@ TEST_P(Dilate3x3Test, AccuracyTest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(MorphologyExTest, AccuracyTest)
|
||||||
|
{
|
||||||
|
MorphShapes defShape = cv::MORPH_RECT;
|
||||||
|
int defKernSize = 3;
|
||||||
|
cv::Mat kernel = cv::getStructuringElement(defShape, cv::Size(defKernSize, defKernSize));
|
||||||
|
|
||||||
|
// G-API code //////////////////////////////////////////////////////////////
|
||||||
|
cv::GMat in;
|
||||||
|
auto out = cv::gapi::morphologyEx(in, op, kernel);
|
||||||
|
|
||||||
|
cv::GComputation c(in, out);
|
||||||
|
c.apply(in_mat1, out_mat_gapi, getCompileArgs());
|
||||||
|
// OpenCV code /////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
cv::morphologyEx(in_mat1, out_mat_ocv, op, kernel);
|
||||||
|
}
|
||||||
|
// Comparison //////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
|
||||||
|
EXPECT_EQ(out_mat_gapi.size(), sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(SobelTest, AccuracyTest)
|
TEST_P(SobelTest, AccuracyTest)
|
||||||
{
|
{
|
||||||
// G-API code //////////////////////////////////////////////////////////////
|
// G-API code //////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -848,6 +848,25 @@ inline std::ostream& operator<<(std::ostream& os, NormTypes op)
|
|||||||
#undef CASE
|
#undef CASE
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, MorphTypes op)
|
||||||
|
{
|
||||||
|
#define CASE(v) case MorphTypes::v: os << #v; break
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
CASE(MORPH_ERODE);
|
||||||
|
CASE(MORPH_DILATE);
|
||||||
|
CASE(MORPH_OPEN);
|
||||||
|
CASE(MORPH_CLOSE);
|
||||||
|
CASE(MORPH_GRADIENT);
|
||||||
|
CASE(MORPH_TOPHAT);
|
||||||
|
CASE(MORPH_BLACKHAT);
|
||||||
|
CASE(MORPH_HITMISS);
|
||||||
|
default: GAPI_Assert(false && "unknown MorphTypes value");
|
||||||
|
}
|
||||||
|
#undef CASE
|
||||||
|
return os;
|
||||||
|
}
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|
||||||
#endif //OPENCV_GAPI_TESTS_COMMON_HPP
|
#endif //OPENCV_GAPI_TESTS_COMMON_HPP
|
||||||
|
|||||||
@ -130,6 +130,30 @@ INSTANTIATE_TEST_CASE_P(Dilate3x3TestCPU, Dilate3x3Test,
|
|||||||
Values(AbsExact().to_compare_obj()),
|
Values(AbsExact().to_compare_obj()),
|
||||||
Values(1,2,4)));
|
Values(1,2,4)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(MorphologyExTestCPU, MorphologyExTest,
|
||||||
|
Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
|
||||||
|
Values(cv::Size(1280, 720),
|
||||||
|
cv::Size(640, 480)),
|
||||||
|
Values(-1),
|
||||||
|
Values(IMGPROC_CPU),
|
||||||
|
Values(AbsExact().to_compare_obj()),
|
||||||
|
Values(cv::MorphTypes::MORPH_ERODE,
|
||||||
|
cv::MorphTypes::MORPH_DILATE,
|
||||||
|
cv::MorphTypes::MORPH_OPEN,
|
||||||
|
cv::MorphTypes::MORPH_CLOSE,
|
||||||
|
cv::MorphTypes::MORPH_GRADIENT,
|
||||||
|
cv::MorphTypes::MORPH_TOPHAT,
|
||||||
|
cv::MorphTypes::MORPH_BLACKHAT)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(MorphologyExHitMissTestCPU, MorphologyExTest,
|
||||||
|
Combine(Values(CV_8UC1),
|
||||||
|
Values(cv::Size(1280, 720),
|
||||||
|
cv::Size(640, 480)),
|
||||||
|
Values(-1),
|
||||||
|
Values(IMGPROC_CPU),
|
||||||
|
Values(AbsExact().to_compare_obj()),
|
||||||
|
Values(cv::MorphTypes::MORPH_HITMISS)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SobelTestCPU, SobelTest,
|
INSTANTIATE_TEST_CASE_P(SobelTestCPU, SobelTest,
|
||||||
Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1),
|
Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1),
|
||||||
Values(cv::Size(1280, 720),
|
Values(cv::Size(1280, 720),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user