From 96068dd7a935f37bac8a42fef31dc6e7fff92e9f Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 10:53:06 -0500 Subject: [PATCH 1/8] Added stub imgproc source file --- binding.gyp | 1 + src/ImgProc.cc | 10 ++++++++++ src/ImgProc.h | 13 +++++++++++++ src/init.cc | 2 ++ 4 files changed, 26 insertions(+) create mode 100644 src/ImgProc.cc create mode 100644 src/ImgProc.h diff --git a/binding.gyp b/binding.gyp index 6e56fc9..449c088 100755 --- a/binding.gyp +++ b/binding.gyp @@ -15,6 +15,7 @@ , "src/BackgroundSubtractor.cc" , "src/Constants.cc" , "src/Calib3D.cc" + , "src/ImgProc.cc" ] , 'libraries': [ ' target) +{ + Persistent inner; + Local obj = NanNew(); + NanAssignPersistent(inner, obj); + + target->Set(NanNew("imgproc"), obj); +} diff --git a/src/ImgProc.h b/src/ImgProc.h new file mode 100644 index 0000000..140b056 --- /dev/null +++ b/src/ImgProc.h @@ -0,0 +1,13 @@ +#ifndef __NODE_IMGPROC_H +#define __NODE_IMGPROC_H + +#include "OpenCV.h" + +// Implementation of imgproc.hpp functions + +class ImgProc: public node::ObjectWrap { +public: + static void Init(Handle target); +}; + +#endif diff --git a/src/init.cc b/src/init.cc index 2486e07..95eef1a 100755 --- a/src/init.cc +++ b/src/init.cc @@ -10,6 +10,7 @@ #include "FaceRecognizer.h" #include "Constants.h" #include "Calib3D.h" +#include "ImgProc.h" extern "C" void init(Handle target) { @@ -25,6 +26,7 @@ init(Handle target) { NamedWindow::Init(target); Constants::Init(target); Calib3D::Init(target); + ImgProc::Init(target); #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4 From 92f0bf80e575376b74d766d2699baef81d37be96 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 11:16:36 -0500 Subject: [PATCH 2/8] Added cv::undistort --- src/ImgProc.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/ImgProc.h | 2 ++ 2 files changed, 46 insertions(+) diff --git a/src/ImgProc.cc b/src/ImgProc.cc index 7945d93..d0b1ea6 100644 --- a/src/ImgProc.cc +++ b/src/ImgProc.cc @@ -1,4 +1,5 @@ #include "ImgProc.h" +#include "Matrix.h" void ImgProc::Init(Handle target) { @@ -6,5 +7,48 @@ void ImgProc::Init(Handle target) Local obj = NanNew(); NanAssignPersistent(inner, obj); + NODE_SET_METHOD(obj, "undistort", Undistort); + target->Set(NanNew("imgproc"), obj); } + +// cv::undistort +NAN_METHOD(ImgProc::Undistort) +{ + NanEscapableScope(); + + try { + // Get the arguments + + // Arg 0 is the image + Matrix* m0 = ObjectWrap::Unwrap(args[0]->ToObject()); + cv::Mat inputImage = m0->mat; + + // Arg 1 is the camera matrix + Matrix* m1 = ObjectWrap::Unwrap(args[1]->ToObject()); + cv::Mat K = m1->mat; + + // Arg 2 is the distortion coefficents + Matrix* m2 = ObjectWrap::Unwrap(args[2]->ToObject()); + cv::Mat dist = m2->mat; + + // Make an mat to hold the result image + cv::Mat outputImage; + + // Undistort + cv::undistort(inputImage, outputImage, K, dist); + + // Wrap the output image + Local outMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *outMatrix = ObjectWrap::Unwrap(outMatrixWrap); + outMatrix->mat = outputImage; + + // Return the output image + NanReturnValue(outMatrixWrap); + + } catch (cv::Exception &e) { + const char *err_msg = e.what(); + NanThrowError(err_msg); + NanReturnUndefined(); + } +} diff --git a/src/ImgProc.h b/src/ImgProc.h index 140b056..c00393f 100644 --- a/src/ImgProc.h +++ b/src/ImgProc.h @@ -8,6 +8,8 @@ class ImgProc: public node::ObjectWrap { public: static void Init(Handle target); + + static NAN_METHOD(Undistort); }; #endif From b76c39a42e090d6adaf951f4d6c00250bbe5396a Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 11:49:01 -0500 Subject: [PATCH 3/8] Added getOptimalNewCameraMatrix --- src/Calib3D.cc | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Calib3D.h | 2 ++ 2 files changed, 63 insertions(+) diff --git a/src/Calib3D.cc b/src/Calib3D.cc index 6f078a8..274844e 100644 --- a/src/Calib3D.cc +++ b/src/Calib3D.cc @@ -11,6 +11,7 @@ void Calib3D::Init(Handle target) NODE_SET_METHOD(obj, "drawChessboardCorners", DrawChessboardCorners); NODE_SET_METHOD(obj, "calibrateCamera", CalibrateCamera); NODE_SET_METHOD(obj, "solvePnP", SolvePnP); + NODE_SET_METHOD(obj, "getOptimalNewCameraMatrix", GetOptimalNewCameraMatrix); target->Set(NanNew("calib3d"), obj); } @@ -312,3 +313,63 @@ NAN_METHOD(Calib3D::SolvePnP) NanReturnUndefined(); } } + +// cv::solvePnP +NAN_METHOD(Calib3D::GetOptimalNewCameraMatrix) +{ + NanEscapableScope(); + + try { + // Get the arguments + + // Arg 0 is the original camera matrix + Matrix* m0 = ObjectWrap::Unwrap(args[0]->ToObject()); + cv::Mat Kin = m0->mat; + + // Arg 1 is the distortion coefficients + Matrix* m1 = ObjectWrap::Unwrap(args[1]->ToObject()); + cv::Mat dist = m1->mat; + + // Arg 2, the image size + cv::Size imageSize; + if (args[2]->IsArray()) { + Local v8sz = args[2]->ToObject(); + + imageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + } else { + JSTHROW_TYPE("Must pass pattern size"); + } + + // Arg 3 is the alpha free scaling parameter + double alpha = args[3]->ToNumber()->Value(); + + // Arg 4, the new image size + cv::Size newImageSize; + if (args[4]->IsArray()) { + Local v8sz = args[4]->ToObject(); + + newImageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + } else { + JSTHROW_TYPE("Must pass pattern size"); + } + + // Arg 5, valid ROI, skip for now + // Arg 6, center principal point, skip for now + + // Get the optimal new camera matrix + cv::Mat Kout = cv::getOptimalNewCameraMatrix(Kin, dist, imageSize, alpha, newImageSize); + + // Wrap the output K + Local KMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *KMatrix = ObjectWrap::Unwrap(KMatrixWrap); + KMatrix->mat = Kout; + + // Return the new K matrix + NanReturnValue(KMatrixWrap); + + } catch (cv::Exception &e) { + const char *err_msg = e.what(); + NanThrowError(err_msg); + NanReturnUndefined(); + } +} diff --git a/src/Calib3D.h b/src/Calib3D.h index 67bf2c7..ab5669e 100644 --- a/src/Calib3D.h +++ b/src/Calib3D.h @@ -16,6 +16,8 @@ public: static NAN_METHOD(CalibrateCamera); static NAN_METHOD(SolvePnP); + + static NAN_METHOD(GetOptimalNewCameraMatrix); }; #endif From a66d95b53715e1bdf10ca3b49f23f29516d01af7 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 12:02:08 -0500 Subject: [PATCH 4/8] Added initUndistortRectifyMap --- src/ImgProc.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/ImgProc.h | 2 ++ 2 files changed, 70 insertions(+) diff --git a/src/ImgProc.cc b/src/ImgProc.cc index d0b1ea6..4291e17 100644 --- a/src/ImgProc.cc +++ b/src/ImgProc.cc @@ -8,6 +8,7 @@ void ImgProc::Init(Handle target) NanAssignPersistent(inner, obj); NODE_SET_METHOD(obj, "undistort", Undistort); + NODE_SET_METHOD(obj, "initUndistortRectifyMap", InitUndistortRectifyMap); target->Set(NanNew("imgproc"), obj); } @@ -52,3 +53,70 @@ NAN_METHOD(ImgProc::Undistort) NanReturnUndefined(); } } + +// cv::initUndistortRectifyMap +NAN_METHOD(ImgProc::InitUndistortRectifyMap) +{ + NanEscapableScope(); + + try { + + // Arg 0 is the camera matrix + Matrix* m0 = ObjectWrap::Unwrap(args[0]->ToObject()); + cv::Mat K = m0->mat; + + // Arg 1 is the distortion coefficents + Matrix* m1 = ObjectWrap::Unwrap(args[1]->ToObject()); + cv::Mat dist = m1->mat; + + // Arg 2 is the recification transformation + Matrix* m2 = ObjectWrap::Unwrap(args[2]->ToObject()); + cv::Mat R = m2->mat; + + // Arg 3 is the new camera matrix + Matrix* m3 = ObjectWrap::Unwrap(args[3]->ToObject()); + cv::Mat newK = m3->mat; + + // Arg 4 is the image size + cv::Size imageSize; + if (args[4]->IsArray()) { + Local v8sz = args[4]->ToObject(); + + imageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + } else { + JSTHROW_TYPE("Must pass pattern size"); + } + + // Arg 5 is the first map type, skip for now + int m1type = CV_16SC2; + + // Make matrices to hold the output maps + cv::Mat map1, map2; + + // Compute the rectification map + cv::initUndistortRectifyMap(K, dist, R, newK, imageSize, m1type, map1, map2); + + // Wrap the output maps + Local map1Wrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *map1Matrix = ObjectWrap::Unwrap(map1Wrap); + map1Matrix->mat = map1; + + Local map2Wrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *map2Matrix = ObjectWrap::Unwrap(map2Wrap); + map2Matrix->mat = map2; + + // Make a return object with the two maps + Local ret = NanNew(); + ret->Set(NanNew("map1"), map1Wrap); + ret->Set(NanNew("map2"), map2Wrap); + + // Return the maps + NanReturnValue(ret); + + + } catch (cv::Exception &e) { + const char *err_msg = e.what(); + NanThrowError(err_msg); + NanReturnUndefined(); + } +} diff --git a/src/ImgProc.h b/src/ImgProc.h index c00393f..9689403 100644 --- a/src/ImgProc.h +++ b/src/ImgProc.h @@ -10,6 +10,8 @@ public: static void Init(Handle target); static NAN_METHOD(Undistort); + + static NAN_METHOD(InitUndistortRectifyMap); }; #endif From 51be174b6e5056004f70a866d6346f50ad615718 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 12:22:05 -0500 Subject: [PATCH 5/8] Added interpolation constants --- src/Constants.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Constants.cc b/src/Constants.cc index e5b3b68..1d9696b 100644 --- a/src/Constants.cc +++ b/src/Constants.cc @@ -4,6 +4,9 @@ #define CONST(C) \ obj->Set(NanNew(#C), NanNew(C)); +#define CONST_ENUM(C) \ + obj->Set(NanNew(#C), NanNew((int)(cv::C))); + void Constants::Init(Handle target) { Persistent inner; @@ -54,6 +57,12 @@ Constants::Init(Handle target) { CONST(CV_64FC3); CONST(CV_64FC4); + CONST_ENUM(INTER_NEAREST); + CONST_ENUM(INTER_LINEAR); + CONST_ENUM(INTER_AREA); + CONST_ENUM(INTER_CUBIC); + CONST_ENUM(INTER_LANCZOS4); + target->Set(NanNew("Constants"), obj); } From 3d09bb30ea87bdd11f7fa3a30f30acc8777e57a5 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 12:55:32 -0500 Subject: [PATCH 6/8] Added remap --- src/ImgProc.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/ImgProc.h | 2 ++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/ImgProc.cc b/src/ImgProc.cc index 4291e17..4c090a6 100644 --- a/src/ImgProc.cc +++ b/src/ImgProc.cc @@ -9,6 +9,7 @@ void ImgProc::Init(Handle target) NODE_SET_METHOD(obj, "undistort", Undistort); NODE_SET_METHOD(obj, "initUndistortRectifyMap", InitUndistortRectifyMap); + NODE_SET_METHOD(obj, "remap", Remap); target->Set(NanNew("imgproc"), obj); } @@ -82,9 +83,9 @@ NAN_METHOD(ImgProc::InitUndistortRectifyMap) if (args[4]->IsArray()) { Local v8sz = args[4]->ToObject(); - imageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + imageSize = cv::Size(v8sz->Get(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); } else { - JSTHROW_TYPE("Must pass pattern size"); + JSTHROW_TYPE("Must pass image size"); } // Arg 5 is the first map type, skip for now @@ -120,3 +121,49 @@ NAN_METHOD(ImgProc::InitUndistortRectifyMap) NanReturnUndefined(); } } + +// cv::remap +NAN_METHOD(ImgProc::Remap) +{ + NanEscapableScope(); + + try { + // Get the arguments + + // Arg 0 is the image + Matrix* m0 = ObjectWrap::Unwrap(args[0]->ToObject()); + cv::Mat inputImage = m0->mat; + + // Arg 1 is the first map + Matrix* m1 = ObjectWrap::Unwrap(args[1]->ToObject()); + cv::Mat map1 = m1->mat; + + // Arg 2 is the second map + Matrix* m2 = ObjectWrap::Unwrap(args[2]->ToObject()); + cv::Mat map2 = m2->mat; + + // Arg 3 is the interpolation mode + int interpolation = args[3]->IntegerValue(); + + // Args 4, 5 border settings, skipping for now + + // Output image + cv::Mat outputImage; + + // Remap + cv::remap(inputImage, outputImage, map1, map2, interpolation); + + // Wrap the output image + Local outMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *outMatrix = ObjectWrap::Unwrap(outMatrixWrap); + outMatrix->mat = outputImage; + + // Return the image + NanReturnValue(outMatrixWrap); + + } catch (cv::Exception &e) { + const char *err_msg = e.what(); + NanThrowError(err_msg); + NanReturnUndefined(); + } +} diff --git a/src/ImgProc.h b/src/ImgProc.h index 9689403..6d26458 100644 --- a/src/ImgProc.h +++ b/src/ImgProc.h @@ -12,6 +12,8 @@ public: static NAN_METHOD(Undistort); static NAN_METHOD(InitUndistortRectifyMap); + + static NAN_METHOD(Remap); }; #endif From d9aaf529f85e913de51c7ae26ae2d032acb54149 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 12:55:42 -0500 Subject: [PATCH 7/8] Fixed bug causing image sizes to be transposed --- src/Calib3D.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Calib3D.cc b/src/Calib3D.cc index 274844e..f223fef 100644 --- a/src/Calib3D.cc +++ b/src/Calib3D.cc @@ -184,7 +184,7 @@ NAN_METHOD(Calib3D::CalibrateCamera) if (args[2]->IsArray()) { Local v8sz = args[2]->ToObject(); - imageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + imageSize = cv::Size(v8sz->Get(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); } else { JSTHROW_TYPE("Must pass pattern size"); } @@ -335,9 +335,9 @@ NAN_METHOD(Calib3D::GetOptimalNewCameraMatrix) if (args[2]->IsArray()) { Local v8sz = args[2]->ToObject(); - imageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + imageSize = cv::Size(v8sz->Get(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); } else { - JSTHROW_TYPE("Must pass pattern size"); + JSTHROW_TYPE("Must pass original image size"); } // Arg 3 is the alpha free scaling parameter @@ -348,9 +348,9 @@ NAN_METHOD(Calib3D::GetOptimalNewCameraMatrix) if (args[4]->IsArray()) { Local v8sz = args[4]->ToObject(); - newImageSize = cv::Size(v8sz->Get(0)->IntegerValue(), v8sz->Get(1)->IntegerValue()); + newImageSize = cv::Size(v8sz->Get(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); } else { - JSTHROW_TYPE("Must pass pattern size"); + JSTHROW_TYPE("Must pass new image size"); } // Arg 5, valid ROI, skip for now From 8ed5177c34f5942352e2e43be65ebd34909f31c1 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Tue, 27 Jan 2015 12:59:51 -0500 Subject: [PATCH 8/8] Added map1 type paramter to initUndistortRectifyMap --- src/ImgProc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImgProc.cc b/src/ImgProc.cc index 4c090a6..d3210fd 100644 --- a/src/ImgProc.cc +++ b/src/ImgProc.cc @@ -89,7 +89,7 @@ NAN_METHOD(ImgProc::InitUndistortRectifyMap) } // Arg 5 is the first map type, skip for now - int m1type = CV_16SC2; + int m1type = args[5]->IntegerValue(); // Make matrices to hold the output maps cv::Mat map1, map2;