From d0400ec5aed2f29398551da797737727ac3ddda4 Mon Sep 17 00:00:00 2001 From: Max Ehrlich Date: Mon, 9 Feb 2015 18:19:00 -0500 Subject: [PATCH] Added graph-cut stereo algorithm --- src/Stereo.cc | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Stereo.h | 15 +++++++++ 2 files changed, 105 insertions(+) diff --git a/src/Stereo.cc b/src/Stereo.cc index 454fb6a..54da7af 100644 --- a/src/Stereo.cc +++ b/src/Stereo.cc @@ -1,5 +1,6 @@ #include "Stereo.h" #include "Matrix.h" +#include // Block matching @@ -231,3 +232,92 @@ NAN_METHOD(StereoSGBM::Compute) } }; + +// Graph cut + +v8::Persistent StereoGC::constructor; + +void +StereoGC::Init(Handle target) { + NanScope(); + + Local ctor = NanNew(StereoGC::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("StereoGC")); + + NODE_SET_PROTOTYPE_METHOD(ctor, "compute", Compute); + + target->Set(NanNew("StereoGC"), ctor->GetFunction()); +} + +NAN_METHOD(StereoGC::New) { + NanScope(); + + if (args.This()->InternalFieldCount() == 0) + NanThrowTypeError("Cannot instantiate without new"); + + StereoGC *stereo; + + if (args.Length() == 0) + { + stereo = new StereoGC(); + } + else if (args.Length() == 1) + { + stereo = new StereoGC(args[0]->IntegerValue()); // numberOfDisparities + } + else + { + stereo = new StereoGC(args[0]->IntegerValue(), args[1]->IntegerValue()); // max iterations + } + + stereo->Wrap(args.Holder()); + NanReturnValue(args.Holder()); +} + +StereoGC::StereoGC(int numberOfDisparities, int maxIters) +: ObjectWrap() +{ + stereo = cvCreateStereoGCState(numberOfDisparities, maxIters); +} + +// TODO make this async +NAN_METHOD(StereoGC::Compute) +{ + SETUP_FUNCTION(StereoGC) + + try { + // Get the arguments + + // Arg 0, the 'left' image + Matrix* m0 = ObjectWrap::Unwrap(args[0]->ToObject()); + cv::Mat left = m0->mat; + + // Arg 1, the 'right' image + Matrix* m1 = ObjectWrap::Unwrap(args[1]->ToObject()); + cv::Mat right = m1->mat; + + // Compute stereo using the block matching algorithm + CvMat left_leg = left, right_leg = right; + CvMat *disp_left = cvCreateMat(left.rows, left.cols, CV_16S), *disp_right = cvCreateMat(right.rows, right.cols, CV_16S); + cvFindStereoCorrespondenceGC(&left_leg, &right_leg, disp_left, disp_right, self->stereo, 0); + + cv::Mat disp16 = disp_left; + cv::Mat disparity(disp16.rows, disp16.cols, CV_8U); + disp16.convertTo(disparity, CV_8U, -16); + + // Wrap the returned disparity map + Local disparityWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *disp = ObjectWrap::Unwrap(disparityWrap); + disp->mat = disparity; + + NanReturnValue(disparityWrap); + + } catch (cv::Exception &e) { + const char *err_msg = e.what(); + NanThrowError(err_msg); + NanReturnUndefined(); + } + +}; diff --git a/src/Stereo.h b/src/Stereo.h index c144989..569a6d6 100644 --- a/src/Stereo.h +++ b/src/Stereo.h @@ -40,4 +40,19 @@ public: JSFUNC(Compute); }; +struct CvStereoGCState; + +class StereoGC: public node::ObjectWrap { +public: + CvStereoGCState *stereo; + + static Persistent constructor; + static void Init(Handle target); + static NAN_METHOD(New); + + StereoGC(int numberOfDisparities = 16, int maxIterations = 2); + + JSFUNC(Compute); +}; + #endif