From 853de157e63b36a2288e19f87d06d3b680ad0bcf Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 26 Apr 2018 09:52:36 +0200 Subject: [PATCH] added copyMakeBorder --- cc/core/Mat.cc | 18 +++++++++ cc/core/Mat.h | 2 + cc/core/MatBindings.h | 70 +++++++++++++++++++++++++++++++++ lib/typings/Mat.d.ts | 2 + test/tests/core/Mat/Mat.test.js | 48 ++++++++++++++++++++++ 5 files changed, 140 insertions(+) diff --git a/cc/core/Mat.cc b/cc/core/Mat.cc index d22e2eac3..84a9a0dcc 100644 --- a/cc/core/Mat.cc +++ b/cc/core/Mat.cc @@ -87,6 +87,8 @@ NAN_MODULE_INIT(Mat::Init) { Nan::SetPrototypeMethod(ctor, "goodFeaturesToTrackAsync", GoodFeaturesToTrackAsync); Nan::SetPrototypeMethod(ctor, "meanStdDev", MeanStdDev); Nan::SetPrototypeMethod(ctor, "meanStdDevAsync", MeanStdDevAsync); + Nan::SetPrototypeMethod(ctor, "copyMakeBorder", CopyMakeBorder); + Nan::SetPrototypeMethod(ctor, "copyMakeBorderAsync", CopyMakeBorderAsync); #if CV_VERSION_MINOR > 1 Nan::SetPrototypeMethod(ctor, "rotate", Rotate); Nan::SetPrototypeMethod(ctor, "rotateAsync", RotateAsync); @@ -787,6 +789,22 @@ NAN_METHOD(Mat::MeanStdDevAsync) { ); } +NAN_METHOD(Mat::CopyMakeBorder) { + FF::SyncBinding( + std::make_shared(Mat::Converter::unwrap(info.This())), + "Mat::CopyMakeBorder", + info + ); +} + +NAN_METHOD(Mat::CopyMakeBorderAsync) { + FF::AsyncBinding( + std::make_shared(Mat::Converter::unwrap(info.This())), + "Mat::CopyMakeBorderAsync", + info + ); +} + #if CV_VERSION_MINOR > 1 NAN_METHOD(Mat::Rotate) { FF::SyncBinding( diff --git a/cc/core/Mat.h b/cc/core/Mat.h index 73b04d921..6100d1762 100644 --- a/cc/core/Mat.h +++ b/cc/core/Mat.h @@ -118,6 +118,8 @@ class Mat : public Nan::ObjectWrap { static NAN_METHOD(GoodFeaturesToTrackAsync); static NAN_METHOD(MeanStdDev); static NAN_METHOD(MeanStdDevAsync); + static NAN_METHOD(CopyMakeBorder); + static NAN_METHOD(CopyMakeBorderAsync); #if CV_VERSION_MINOR > 1 static NAN_METHOD(Rotate); static NAN_METHOD(RotateAsync); diff --git a/cc/core/MatBindings.h b/cc/core/MatBindings.h index 7f8a31482..a0c1905c8 100644 --- a/cc/core/MatBindings.h +++ b/cc/core/MatBindings.h @@ -732,6 +732,76 @@ namespace MatBindings { } }; + struct CopyMakeBorderWorker : public CatchCvExceptionWorker { + public: + cv::Mat self; + CopyMakeBorderWorker(cv::Mat self) { + this->self = self; + } + + cv::Mat result; + int top, bottom, left, right; + int borderType = cv::BORDER_CONSTANT; + double v1 = 0; + cv::Vec2d v2 = 0; + cv::Vec3d v3 = 0; + cv::Vec4d v4 = 0; + + std::string executeCatchCvExceptionWorker() { + if (self.channels() == 1) + cv::copyMakeBorder(self, result, top, bottom, left, right, borderType, v1); + else if (self.channels() == 2) + cv::copyMakeBorder(self, result, top, bottom, left, right, borderType, v2); + else if (self.channels() == 3) + cv::copyMakeBorder(self, result, top, bottom, left, right, borderType, v3); + else if (self.channels() == 4) + cv::copyMakeBorder(self, result, top, bottom, left, right, borderType, v4); + return ""; + } + + v8::Local getReturnValue() { + return Mat::Converter::wrap(result); + } + + bool unwrapRequiredArgs(Nan::NAN_METHOD_ARGS_TYPE info) { + return ( + IntConverter::arg(0, &top, info) || + IntConverter::arg(1, &bottom, info) || + IntConverter::arg(2, &left, info) || + IntConverter::arg(3, &right, info) + ); + } + + bool unwrapOptionalArgs(Nan::NAN_METHOD_ARGS_TYPE info) { + return ( + IntConverter::optArg(4, &borderType, info) || + ( + self.channels() == 1 && DoubleConverter::optArg(5, &v1, info) || + self.channels() == 2 && Vec2::Converter::optArg(5, &v2, info) || + self.channels() == 3 && Vec3::Converter::optArg(5, &v3, info) || + self.channels() == 4 && Vec4::Converter::optArg(5, &v4, info) + ) + ); + } + + bool hasOptArgsObject(Nan::NAN_METHOD_ARGS_TYPE info) { + return FF_ARG_IS_OBJECT(4); + } + + bool unwrapOptionalArgsFromOpts(Nan::NAN_METHOD_ARGS_TYPE info) { + v8::Local opts = info[4]->ToObject(); + return ( + IntConverter::optProp(&borderType, "borderType", opts) || + ( + self.channels() == 1 && DoubleConverter::optProp(&v1, "value", opts) || + self.channels() == 2 && Vec2::Converter::optProp(&v2, "value", opts) || + self.channels() == 3 && Vec3::Converter::optProp(&v3, "value", opts) || + self.channels() == 4 && Vec4::Converter::optProp(&v4, "value", opts) + ) + ); + } + }; + #if CV_VERSION_MINOR > 1 struct RotateWorker : public OpWithCodeWorker { public: diff --git a/lib/typings/Mat.d.ts b/lib/typings/Mat.d.ts index 837fc7743..ef0ce15a7 100644 --- a/lib/typings/Mat.d.ts +++ b/lib/typings/Mat.d.ts @@ -79,6 +79,8 @@ export class Mat { convertToAsync(type: number, alpha?: number, beta?: number): Promise; copy(mask?: Mat): Mat; copyAsync(mask?: Mat): Promise; + copyMakeBorder(top: number, bottom: number, left: number, right: number, borderType?: number, value?: number | Vec2 | Vec3 | Vec4): Mat; + copyMakeBorderAsync(top: number, bottom: number, left: number, right: number, borderType?: number, value?: number | Vec2 | Vec3 | Vec4): Promise; copyTo(dst: Mat, mask?: Mat): Mat; copyToAsync(dst: Mat, mask?: Mat): Promise; cornerEigenValsAndVecs(blockSize: number, ksize?: number, borderType?: number): Mat; diff --git a/test/tests/core/Mat/Mat.test.js b/test/tests/core/Mat/Mat.test.js index 2a530c5bc..4811dda85 100644 --- a/test/tests/core/Mat/Mat.test.js +++ b/test/tests/core/Mat/Mat.test.js @@ -827,5 +827,53 @@ describe('Mat', () => { } }); }); + + describe('copyMakeBorder', () => { + const top = 1; + const bottom = 1; + const left = 1; + const right = 1; + + const getRequiredArgs = () => ([ + top, + bottom, + left, + right + ]); + + const borderType = cv.BORDER_CONSTANT; + + const makeExpectOutput = (type, value) => (res, _, args) => { + expect(res).to.be.instanceOf(cv.Mat); + assertMetaData(res)(22, 22, type); + if (args[5] === 255 || (args[4] && args[4].value)) { + const upperLeft = res.at(0, 0); + if (typeof upperLeft === 'object') { + ['x', 'y', 'z', 'w'].forEach(k => expect(upperLeft[k]).to.eq(value[k])); + } else { + expect(upperLeft).to.equal(value); + } + } + }; + + const makeTest = (type, defaultValue, value) => () => { + generateAPITests({ + getDut: () => new cv.Mat(20, 20, type, defaultValue), + methodName: 'copyMakeBorder', + methodNameSpace: 'Mat', + getRequiredArgs, + getOptionalArgsMap: () => ([ + ['borderType', borderType], + ['value', value] + ]), + expectOutput: makeExpectOutput(type, value) + }); + }; + + describe('C1', makeTest(cv.CV_8U, 0, 255)); + describe('C2', makeTest(cv.CV_8UC2, [0, 0], new cv.Vec(255, 200))); + describe('C3', makeTest(cv.CV_8UC3, [0, 0, 0], new cv.Vec(255, 200, 100))); + describe('C4', makeTest(cv.CV_8UC4, [0, 0, 0, 0], new cv.Vec(255, 200, 100, 50))); + }); });