Skip to content

Commit d3118ad

Browse files
committed
Merge pull request #1408 from VenkateshVijaykumar:ridge_filter
2 parents 4a06631 + 17ffd28 commit d3118ad

File tree

7 files changed

+198
-1
lines changed

7 files changed

+198
-1
lines changed

modules/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ $ cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules -D BUILD_opencv_<r
6262

6363
- **xfeatures2d**: Features2D extra -- Extra 2D Features Framework containing experimental and non-free 2D feature detector/descriptor algorithms. SURF, SIFT, BRIEF, Censure, Freak, LUCID, Daisy, Self-similar.
6464

65-
- **ximgproc**: Extended Image Processing -- Structured Forests / Domain Transform Filter / Guided Filter / Adaptive Manifold Filter / Joint Bilateral Filter / Superpixels.
65+
- **ximgproc**: Extended Image Processing -- Structured Forests / Domain Transform Filter / Guided Filter / Adaptive Manifold Filter / Joint Bilateral Filter / Superpixels / Ridge Detection Filter.
6666

6767
- **xobjdetect**: Boosted 2D Object Detection -- Uses a Waldboost cascade and local binary patterns computed as integral features for 2D object detection.
6868

modules/ximgproc/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Extended Image Processing
1414
- Fast Line Detector
1515
- Deriche Filter
1616
- Pei&Lin Normalization
17+
- Ridge Detection Filter

modules/ximgproc/include/opencv2/ximgproc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "ximgproc/deriche_filter.hpp"
5555
#include "ximgproc/peilin.hpp"
5656
#include "ximgproc/fourier_descriptors.hpp"
57+
#include "ximgproc/ridgefilter.hpp"
5758

5859

5960
/** @defgroup ximgproc Extended Image Processing
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
/*
6+
Ridge Detection Filter.
7+
OpenCV port by : Kushal Vyas (@kushalvyas), Venkatesh Vijaykumar(@venkateshvijaykumar)
8+
*/
9+
10+
#ifndef __OPENCV_XIMGPROC_RIDGEFILTER_HPP__
11+
#define __OPENCV_XIMGPROC_RIDGEFILTER_HPP__
12+
13+
#include <opencv2/core.hpp>
14+
15+
namespace cv { namespace ximgproc {
16+
17+
//! @addtogroup ximgproc_filters
18+
//! @{
19+
20+
/** @brief Applies Ridge Detection Filter to an input image.
21+
Implements Ridge detection similar to the one in [Mathematica](http://reference.wolfram.com/language/ref/RidgeFilter.html)
22+
using the eigen values from the Hessian Matrix of the input image using Sobel Derivatives.
23+
Additional refinement can be done using Skeletonization and Binarization.
24+
*/
25+
class CV_EXPORTS_W RidgeDetectionFilter : public Algorithm
26+
{
27+
public:
28+
/**
29+
@brief Create pointer to the Ridge detection filter.
30+
@param ddepth Specifies output image depth. Defualt is CV_32FC1
31+
@param dx Order of derivative x, default is 1
32+
@param dy Order of derivative y, default is 1
33+
@param ksize Sobel kernel size , default is 3
34+
@param out_dtype Converted format for output, default is CV_8UC1
35+
@param scale Optional scale value for derivative values, default is 1
36+
@param delta Optional bias added to output, default is 0
37+
@param borderType Pixel extrapolation method, default is BORDER_DEFAULT
38+
@see Sobel, threshold, getStructuringElement, morphologyEx.( for additional refinement)
39+
*/
40+
CV_WRAP static Ptr<RidgeDetectionFilter> create(int ddepth = CV_32FC1, int dx=1, int dy=1, int ksize = 3, int out_dtype=CV_8UC1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT);
41+
/**
42+
@brief Apply Ridge detection filter on input image.
43+
@param _img InputArray as supported by Sobel. img can be 1-Channel or 3-Channels.
44+
@param out OutputAray of structure as RidgeDetectionFilter::ddepth. Output image with ridges.
45+
*/
46+
CV_WRAP virtual void getRidgeFilteredImage(InputArray _img, OutputArray out) = 0;
47+
};
48+
49+
//! @}
50+
}} // namespace
51+
#endif
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
#include "perf_precomp.hpp"
5+
6+
namespace cvtest {
7+
8+
using namespace perf;
9+
using namespace testing;
10+
using namespace cv;
11+
using namespace cv::ximgproc;
12+
13+
typedef tuple<MatDepth, int, Size> RDFParams;
14+
typedef TestBaseWithParam<RDFParams> RidgeDetectionFilterPerfTest;
15+
16+
PERF_TEST_P(RidgeDetectionFilterPerfTest, perf, Combine(
17+
Values((MatDepth)CV_32F),
18+
Values(3),
19+
SZ_TYPICAL
20+
))
21+
{
22+
RDFParams params = GetParam();
23+
int ddepth = get<0>(params);
24+
int ksize = get<1>(params);
25+
Size sz = get<2>(params);
26+
27+
Mat src(sz, ddepth);
28+
Mat out(sz, src.type());
29+
30+
declare.in(src).out(out);
31+
32+
Ptr<RidgeDetectionFilter> rdf = RidgeDetectionFilter::create(ddepth,1, 1, ksize);
33+
34+
TEST_CYCLE() rdf->getRidgeFilteredImage(src, out);
35+
36+
SANITY_CHECK_NOTHING();
37+
}
38+
39+
} // namespace
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
#include "precomp.hpp"
6+
#include "opencv2/imgproc.hpp"
7+
#include "opencv2/ximgproc/ridgefilter.hpp"
8+
9+
namespace cv { namespace ximgproc {
10+
11+
class RidgeDetectionFilterImpl : public RidgeDetectionFilter
12+
{
13+
public:
14+
int _ddepth, _dx, _dy, _ksize;
15+
double _scale, _delta;
16+
int _borderType;
17+
int _out_dtype;
18+
RidgeDetectionFilterImpl(int ddepth=CV_32FC1, int dx=1, int dy=1, int ksize = 3, int out_dtype=CV_8UC1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)
19+
{
20+
CV_Assert((ksize == 1 || ksize == 3 || ksize == 5 || ksize == 7));
21+
CV_Assert((ddepth == CV_32FC1 || ddepth == CV_64FC1));
22+
_ddepth = ddepth;
23+
_dx = dx;
24+
_dy = dy;
25+
_ksize = ksize;
26+
_scale = scale;
27+
_delta = delta;
28+
_borderType = borderType;
29+
_out_dtype = out_dtype;
30+
}
31+
virtual void getRidgeFilteredImage(InputArray _img, OutputArray out);
32+
};
33+
34+
void RidgeDetectionFilterImpl::getRidgeFilteredImage(InputArray _img, OutputArray out)
35+
{
36+
Mat img = _img.getMat();
37+
CV_Assert(img.channels() == 1 || img.channels() == 3);
38+
39+
if(img.channels() == 3)
40+
cvtColor(img, img, COLOR_BGR2GRAY);
41+
42+
Mat sbx, sby;
43+
Sobel(img, sbx, _ddepth, _dx, 0, _ksize, _scale, _delta, _borderType);
44+
Sobel(img, sby, _ddepth, 0, _dy, _ksize, _scale, _delta, _borderType);
45+
46+
Mat sbxx, sbyy, sbxy;
47+
Sobel(sbx, sbxx, _ddepth, _dx, 0, _ksize, _scale, _delta, _borderType);
48+
Sobel(sby, sbyy, _ddepth, 0, _dy, _ksize, _scale, _delta, _borderType);
49+
Sobel(sbx, sbxy, _ddepth, 0, _dy, _ksize, _scale, _delta, _borderType);
50+
51+
Mat sb2xx, sb2yy, sb2xy;
52+
multiply(sbxx, sbxx, sb2xx);
53+
multiply(sbyy, sbyy, sb2yy);
54+
multiply(sbxy, sbxy, sb2xy);
55+
56+
Mat sbxxyy;
57+
multiply(sbxx, sbyy, sbxxyy);
58+
59+
Mat rootex;
60+
rootex = (sb2xx + (sb2xy + sb2xy + sb2xy + sb2xy) - (sbxxyy + sbxxyy) + sb2xy );
61+
Mat root;
62+
sqrt(rootex, root);
63+
Mat ridgexp;
64+
ridgexp = ( (sbxx + sbyy) + root );
65+
ridgexp.convertTo(out, _out_dtype, 0.5);
66+
}
67+
68+
Ptr<RidgeDetectionFilter> RidgeDetectionFilter::create(int ddepth, int dx, int dy, int ksize, int out_dtype, double scale, double delta, int borderType)
69+
{
70+
return makePtr<RidgeDetectionFilterImpl>(ddepth, dx, dy, ksize, out_dtype, scale, delta, borderType);
71+
}
72+
73+
}} // namespace
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
#include "test_precomp.hpp"
6+
7+
namespace cvtest {
8+
9+
using namespace cv;
10+
using namespace cv::ximgproc;
11+
12+
TEST(ximgproc_ridgedetectionfilter, ReferenceAccuracy)
13+
{
14+
String openCVExtraDir = cvtest::TS::ptr()->get_data_path();
15+
String srcImgPath = "cv/ximgproc/sources/04.png";
16+
String refPath = "cv/ximgproc/results/ridge_filter_test_ref/04.png";
17+
Mat src = imread(openCVExtraDir + srcImgPath);
18+
Mat ref = imread(openCVExtraDir + refPath, 0);
19+
Mat n_ref;
20+
ref.convertTo(n_ref, CV_8UC1);
21+
Ptr<RidgeDetectionFilter> rdf = RidgeDetectionFilter::create();
22+
Mat out;
23+
rdf->getRidgeFilteredImage(src, out);
24+
Mat out_cmp;
25+
out.convertTo(out_cmp, CV_8UC1);
26+
Mat sb;
27+
subtract(out_cmp, n_ref, sb);
28+
int zeros = countNonZero(sb);
29+
EXPECT_EQ(zeros, 0);
30+
}
31+
32+
} // namespace

0 commit comments

Comments
 (0)