diff --git a/binding.gyp b/binding.gyp index 38e47d7a5..2f87172a7 100644 --- a/binding.gyp +++ b/binding.gyp @@ -27,6 +27,7 @@ "cc/core/core.cc", "cc/core/Mat.cc", "cc/core/MatImgproc.cc", + "cc/core/MatXimgproc.cc", "cc/core/MatCalib3d.cc", "cc/core/Point.cc", "cc/core/Vec.cc", diff --git a/cc/core/Mat.cc b/cc/core/Mat.cc index 033c69dd2..49b055ff0 100644 --- a/cc/core/Mat.cc +++ b/cc/core/Mat.cc @@ -3,6 +3,10 @@ #include "MatCalib3d.h" #include "MatBindings.h" +#ifdef HAVE_XIMGPROC +#include "MatXimgproc.h" +#endif // HAVE_XIMGPROC + Nan::Persistent Mat::constructor; NAN_MODULE_INIT(Mat::Init) { @@ -112,6 +116,9 @@ NAN_MODULE_INIT(Mat::Init) { MatImgproc::Init(ctor); MatCalib3d::Init(ctor); + #ifdef HAVE_XIMGPROC + MatXimgproc::Init(ctor); + #endif // HAVE_XIMGPROC target->Set(Nan::New("Mat").ToLocalChecked(), ctor->GetFunction()); }; diff --git a/cc/core/MatXimgproc.cc b/cc/core/MatXimgproc.cc new file mode 100644 index 000000000..b2298485a --- /dev/null +++ b/cc/core/MatXimgproc.cc @@ -0,0 +1,27 @@ +#ifdef HAVE_XIMGPROC + +#include "MatXimgproc.h" +#include "MatXimgprocBindings.h" + +void MatXimgproc::Init(v8::Local ctor) { + Nan::SetPrototypeMethod(ctor, "guidedFilter", GuidedFilter); + Nan::SetPrototypeMethod(ctor, "guidedFilterAsync", GuidedFilterAsync); +}; + +NAN_METHOD(MatXimgproc::GuidedFilter) { + FF::SyncBinding( + std::make_shared(Mat::Converter::unwrap(info.This())), + "Mat::GuidedFilter", + info + ); +} + +NAN_METHOD(MatXimgproc::GuidedFilterAsync) { + FF::AsyncBinding( + std::make_shared(Mat::Converter::unwrap(info.This())), + "Mat::GuidedFilterAsync", + info + ); +} + +#endif // HAVE_XIMGPROC diff --git a/cc/core/MatXimgproc.h b/cc/core/MatXimgproc.h new file mode 100644 index 000000000..8e1a59622 --- /dev/null +++ b/cc/core/MatXimgproc.h @@ -0,0 +1,16 @@ +#include "Mat.h" +#include + +#ifndef __FF_MATXIMGPROC_H__ +#define __FF_MATXIMGPROC_H__ + +class MatXimgproc { +public: + static void Init(v8::Local ctor); + + static NAN_METHOD(GuidedFilter); + static NAN_METHOD(GuidedFilterAsync); + +}; + +#endif \ No newline at end of file diff --git a/cc/core/MatXimgprocBindings.h b/cc/core/MatXimgprocBindings.h new file mode 100644 index 000000000..c154772b1 --- /dev/null +++ b/cc/core/MatXimgprocBindings.h @@ -0,0 +1,59 @@ +#include "MatXimgproc.h" + +#ifndef __FF_MATXIMGPROCBINDINGS_H__ +#define __FF_MATXIMGPROCBINDINGS_H__ + +namespace MatXimgprocBindings { + + struct GuidedFilterWorker : public CatchCvExceptionWorker { + public: + cv::Mat self; + GuidedFilterWorker(cv::Mat self) { + this->self = self; + } + + cv::Mat guide; + int radius; + double eps; + int ddepth = -1; + + cv::Mat dst; + + std::string executeCatchCvExceptionWorker() { + cv::ximgproc::guidedFilter(guide, self, dst, radius, eps, ddepth); + return ""; + } + + v8::Local getReturnValue() { + return Mat::Converter::wrap(dst); + } + + bool unwrapRequiredArgs(Nan::NAN_METHOD_ARGS_TYPE info) { + return ( + Mat::Converter::arg(0, &guide, info) || + IntConverter::arg(1, &radius, info) || + DoubleConverter::arg(2, &eps, info) + ); + } + + bool unwrapOptionalArgs(Nan::NAN_METHOD_ARGS_TYPE info) { + return ( + IntConverter::optArg(3, &ddepth, info) + ); + } + + bool hasOptArgsObject(Nan::NAN_METHOD_ARGS_TYPE info) { + return FF_ARG_IS_OBJECT(3); + } + + bool unwrapOptionalArgsFromOpts(Nan::NAN_METHOD_ARGS_TYPE info) { + v8::Local opts = info[3]->ToObject(); + return ( + IntConverter::optProp(&ddepth, "ddepth", opts) + ); + } + }; + +} + +#endif \ No newline at end of file diff --git a/examples/guidedFilter.js b/examples/guidedFilter.js new file mode 100644 index 000000000..890511d51 --- /dev/null +++ b/examples/guidedFilter.js @@ -0,0 +1,8 @@ +const path = require('path'); +const cv = require('../'); + +const image = cv.imread(path.resolve(__dirname, '../data/Lenna.png')); + +const dst = image.guidedFilter(image, 10, 500, -1); + +cv.imshowWait("dst", dst); \ No newline at end of file diff --git a/lib/typings/Mat.d.ts b/lib/typings/Mat.d.ts index 07148f959..932d5dd7c 100644 --- a/lib/typings/Mat.d.ts +++ b/lib/typings/Mat.d.ts @@ -179,6 +179,8 @@ export class Mat { goodFeaturesToTrackAsync(maxCorners: number, qualityLevel: number, minDistance: number, mask?: Mat, blockSize?: number, gradientSize?: number, useHarrisDetector?: boolean, harrisK?: number): Promise; grabCut(mask: Mat, rect: Rect, bgdModel: Mat, fgdModel: Mat, iterCount: number, mode: number): void; grabCutAsync(mask: Mat, rect: Rect, bgdModel: Mat, fgdModel: Mat, iterCount: number, mode: number): Promise; + guidedFilter(guide: Mat, radius: number, eps: number, ddepth?: number): Mat; + guidedFilterAsync(guide: Mat, radius: number, eps: number, ddepth?: number): Promise; hDiv(otherMat: Mat): Mat; hMul(otherMat: Mat): Mat; houghCircles(method: number, dp: number, minDist: number, param1?: number, param2?: number, minRadius?: number, maxRadius?: number): Vec3[]; diff --git a/test/tests/core/Mat/Mat.test.js b/test/tests/core/Mat/Mat.test.js index 30fb3f3af..daf0bc654 100644 --- a/test/tests/core/Mat/Mat.test.js +++ b/test/tests/core/Mat/Mat.test.js @@ -18,6 +18,7 @@ const constructorTestsFromJsArray = require('./constructorTestsFromJsArray'); const constructorTestsFromFillVector = require('./constructorTestsFromFillVector'); const operatorTests = require('./operatorTests'); const imgprocTests = require('./imgprocTests'); +const ximgprocTests = require('./ximgprocTests'); const calib3dTests = require('./calib3dTests'); const { doubleMin, doubleMax } = require('./typeRanges'); @@ -48,6 +49,7 @@ describe('Mat', () => { accessorTests(); describe('imgproc methods', () => imgprocTests(getTestImg)); + describe('ximgproc methods', () => ximgprocTests()); describe('calib3d methods', () => calib3dTests()); describe('constructor from channels', () => { diff --git a/test/tests/core/Mat/ximgprocTests.js b/test/tests/core/Mat/ximgprocTests.js new file mode 100644 index 000000000..b018caf50 --- /dev/null +++ b/test/tests/core/Mat/ximgprocTests.js @@ -0,0 +1,38 @@ +const cv = global.dut; + +const { + generateAPITests, + assertMetaData, +} = global.utils; + +module.exports = () => { + describe('guidedFilter', () => { + if (!cv.xmodules.ximgproc) { + it('compiled without ximgproc'); + return; + } + + const getDut = () => new cv.Mat(100, 100, cv.CV_8UC3); + + const guide = new cv.Mat(100, 100, cv.CV_8UC3); + const radius = 3; + const eps = 100; + const ddepth = -1; + generateAPITests({ + getDut, + methodName: 'guidedFilter', + methodNameSpace: 'Mat', + getRequiredArgs: () => ([ + guide, + radius, + eps + ]), + getOptionalArgs: () => ([ + ddepth + ]), + expectOutput: (res) => { + assertMetaData(res)(100, 100, cv.CV_8UC3); + } + }); + }); +} \ No newline at end of file