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) 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); } @@ -183,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"); } @@ -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(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); + } else { + JSTHROW_TYPE("Must pass original image 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(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); + } else { + JSTHROW_TYPE("Must pass new image 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 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); } diff --git a/src/ImgProc.cc b/src/ImgProc.cc new file mode 100644 index 0000000..d3210fd --- /dev/null +++ b/src/ImgProc.cc @@ -0,0 +1,169 @@ +#include "ImgProc.h" +#include "Matrix.h" + +void ImgProc::Init(Handle target) +{ + Persistent inner; + Local obj = NanNew(); + NanAssignPersistent(inner, obj); + + NODE_SET_METHOD(obj, "undistort", Undistort); + NODE_SET_METHOD(obj, "initUndistortRectifyMap", InitUndistortRectifyMap); + NODE_SET_METHOD(obj, "remap", Remap); + + 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(); + } +} + +// 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(1)->IntegerValue(), v8sz->Get(0)->IntegerValue()); + } else { + JSTHROW_TYPE("Must pass image size"); + } + + // Arg 5 is the first map type, skip for now + int m1type = args[5]->IntegerValue(); + + // 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(); + } +} + +// 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 new file mode 100644 index 0000000..6d26458 --- /dev/null +++ b/src/ImgProc.h @@ -0,0 +1,19 @@ +#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); + + static NAN_METHOD(Undistort); + + static NAN_METHOD(InitUndistortRectifyMap); + + static NAN_METHOD(Remap); +}; + +#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