Commit d3118ad0 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #1408 from VenkateshVijaykumar:ridge_filter

parents 4a066317 17ffd282
......@@ -62,7 +62,7 @@ $ cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules -D BUILD_opencv_<r
- **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.
- **ximgproc**: Extended Image Processing -- Structured Forests / Domain Transform Filter / Guided Filter / Adaptive Manifold Filter / Joint Bilateral Filter / Superpixels.
- **ximgproc**: Extended Image Processing -- Structured Forests / Domain Transform Filter / Guided Filter / Adaptive Manifold Filter / Joint Bilateral Filter / Superpixels / Ridge Detection Filter.
- **xobjdetect**: Boosted 2D Object Detection -- Uses a Waldboost cascade and local binary patterns computed as integral features for 2D object detection.
......
......@@ -14,3 +14,4 @@ Extended Image Processing
- Fast Line Detector
- Deriche Filter
- Pei&Lin Normalization
- Ridge Detection Filter
......@@ -54,6 +54,7 @@
#include "ximgproc/deriche_filter.hpp"
#include "ximgproc/peilin.hpp"
#include "ximgproc/fourier_descriptors.hpp"
#include "ximgproc/ridgefilter.hpp"
/** @defgroup ximgproc Extended Image Processing
......
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
/*
Ridge Detection Filter.
OpenCV port by : Kushal Vyas (@kushalvyas), Venkatesh Vijaykumar(@venkateshvijaykumar)
*/
#ifndef __OPENCV_XIMGPROC_RIDGEFILTER_HPP__
#define __OPENCV_XIMGPROC_RIDGEFILTER_HPP__
#include <opencv2/core.hpp>
namespace cv { namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/** @brief Applies Ridge Detection Filter to an input image.
Implements Ridge detection similar to the one in [Mathematica](http://reference.wolfram.com/language/ref/RidgeFilter.html)
using the eigen values from the Hessian Matrix of the input image using Sobel Derivatives.
Additional refinement can be done using Skeletonization and Binarization.
*/
class CV_EXPORTS_W RidgeDetectionFilter : public Algorithm
{
public:
/**
@brief Create pointer to the Ridge detection filter.
@param ddepth Specifies output image depth. Defualt is CV_32FC1
@param dx Order of derivative x, default is 1
@param dy Order of derivative y, default is 1
@param ksize Sobel kernel size , default is 3
@param out_dtype Converted format for output, default is CV_8UC1
@param scale Optional scale value for derivative values, default is 1
@param delta Optional bias added to output, default is 0
@param borderType Pixel extrapolation method, default is BORDER_DEFAULT
@see Sobel, threshold, getStructuringElement, morphologyEx.( for additional refinement)
*/
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);
/**
@brief Apply Ridge detection filter on input image.
@param _img InputArray as supported by Sobel. img can be 1-Channel or 3-Channels.
@param out OutputAray of structure as RidgeDetectionFilter::ddepth. Output image with ridges.
*/
CV_WRAP virtual void getRidgeFilteredImage(InputArray _img, OutputArray out) = 0;
};
//! @}
}} // namespace
#endif
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace cvtest {
using namespace perf;
using namespace testing;
using namespace cv;
using namespace cv::ximgproc;
typedef tuple<MatDepth, int, Size> RDFParams;
typedef TestBaseWithParam<RDFParams> RidgeDetectionFilterPerfTest;
PERF_TEST_P(RidgeDetectionFilterPerfTest, perf, Combine(
Values((MatDepth)CV_32F),
Values(3),
SZ_TYPICAL
))
{
RDFParams params = GetParam();
int ddepth = get<0>(params);
int ksize = get<1>(params);
Size sz = get<2>(params);
Mat src(sz, ddepth);
Mat out(sz, src.type());
declare.in(src).out(out);
Ptr<RidgeDetectionFilter> rdf = RidgeDetectionFilter::create(ddepth,1, 1, ksize);
TEST_CYCLE() rdf->getRidgeFilteredImage(src, out);
SANITY_CHECK_NOTHING();
}
} // namespace
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc/ridgefilter.hpp"
namespace cv { namespace ximgproc {
class RidgeDetectionFilterImpl : public RidgeDetectionFilter
{
public:
int _ddepth, _dx, _dy, _ksize;
double _scale, _delta;
int _borderType;
int _out_dtype;
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)
{
CV_Assert((ksize == 1 || ksize == 3 || ksize == 5 || ksize == 7));
CV_Assert((ddepth == CV_32FC1 || ddepth == CV_64FC1));
_ddepth = ddepth;
_dx = dx;
_dy = dy;
_ksize = ksize;
_scale = scale;
_delta = delta;
_borderType = borderType;
_out_dtype = out_dtype;
}
virtual void getRidgeFilteredImage(InputArray _img, OutputArray out);
};
void RidgeDetectionFilterImpl::getRidgeFilteredImage(InputArray _img, OutputArray out)
{
Mat img = _img.getMat();
CV_Assert(img.channels() == 1 || img.channels() == 3);
if(img.channels() == 3)
cvtColor(img, img, COLOR_BGR2GRAY);
Mat sbx, sby;
Sobel(img, sbx, _ddepth, _dx, 0, _ksize, _scale, _delta, _borderType);
Sobel(img, sby, _ddepth, 0, _dy, _ksize, _scale, _delta, _borderType);
Mat sbxx, sbyy, sbxy;
Sobel(sbx, sbxx, _ddepth, _dx, 0, _ksize, _scale, _delta, _borderType);
Sobel(sby, sbyy, _ddepth, 0, _dy, _ksize, _scale, _delta, _borderType);
Sobel(sbx, sbxy, _ddepth, 0, _dy, _ksize, _scale, _delta, _borderType);
Mat sb2xx, sb2yy, sb2xy;
multiply(sbxx, sbxx, sb2xx);
multiply(sbyy, sbyy, sb2yy);
multiply(sbxy, sbxy, sb2xy);
Mat sbxxyy;
multiply(sbxx, sbyy, sbxxyy);
Mat rootex;
rootex = (sb2xx + (sb2xy + sb2xy + sb2xy + sb2xy) - (sbxxyy + sbxxyy) + sb2xy );
Mat root;
sqrt(rootex, root);
Mat ridgexp;
ridgexp = ( (sbxx + sbyy) + root );
ridgexp.convertTo(out, _out_dtype, 0.5);
}
Ptr<RidgeDetectionFilter> RidgeDetectionFilter::create(int ddepth, int dx, int dy, int ksize, int out_dtype, double scale, double delta, int borderType)
{
return makePtr<RidgeDetectionFilterImpl>(ddepth, dx, dy, ksize, out_dtype, scale, delta, borderType);
}
}} // namespace
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace cvtest {
using namespace cv;
using namespace cv::ximgproc;
TEST(ximgproc_ridgedetectionfilter, ReferenceAccuracy)
{
String openCVExtraDir = cvtest::TS::ptr()->get_data_path();
String srcImgPath = "cv/ximgproc/sources/04.png";
String refPath = "cv/ximgproc/results/ridge_filter_test_ref/04.png";
Mat src = imread(openCVExtraDir + srcImgPath);
Mat ref = imread(openCVExtraDir + refPath, 0);
Mat n_ref;
ref.convertTo(n_ref, CV_8UC1);
Ptr<RidgeDetectionFilter> rdf = RidgeDetectionFilter::create();
Mat out;
rdf->getRidgeFilteredImage(src, out);
Mat out_cmp;
out.convertTo(out_cmp, CV_8UC1);
Mat sb;
subtract(out_cmp, n_ref, sb);
int zeros = countNonZero(sb);
EXPECT_EQ(zeros, 0);
}
} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment