From eccd861a8a8b8b832067e8c840e4a034ff0a2dd4 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanovm Date: Wed, 8 Mar 2017 16:08:58 -0500 Subject: [PATCH] ~cleanup --- .idea/.name | 1 + .idea/encodings.xml | 6 + .idea/jsLibraryMappings.xml | 6 + .idea/misc.xml | 13 + .idea/modules.xml | 8 + .idea/node-opencv.iml | 8 + .idea/vcs.xml | 6 + .idea/workspace.xml | 723 ++++++++++++++++++++++++++++++++++++ examples/optical-flow.js | 64 +++- src/Matrix.cc | 84 ++++- src/Matrix.h | 1 + src/OpenCV.cc | 2 + 12 files changed, 907 insertions(+), 15 deletions(-) create mode 100644 .idea/.name create mode 100644 .idea/encodings.xml create mode 100644 .idea/jsLibraryMappings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/node-opencv.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..f86a829 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +node-opencv \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..d23208f --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..72abef0 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b0727cb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/node-opencv.iml b/.idea/node-opencv.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/node-opencv.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..950cc5f --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,723 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $PROJECT_DIR$ + true + + bdd + + DIRECTORY + + false + + + + + + + + + + + 1488943347282 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/optical-flow.js b/examples/optical-flow.js index 96ce808..9efbd1c 100755 --- a/examples/optical-flow.js +++ b/examples/optical-flow.js @@ -1,20 +1,56 @@ var cv = require('../lib/opencv'); +var path = require('path'); -try { - var camera = new cv.VideoCapture(0); - var window = new cv.NamedWindow('Video', 0) - /* - setInterval(function() { - camera.read(function(err, im) { +var cap = new cv.VideoCapture(path.join(__dirname, 'files', 'motion.mov')); +var window = new cv.NamedWindow('Video', 0); + +// Parameters for lucas kanade optical flow +var lk_params = { + winSize: [15, 15], + maxLevel: 2, + criteria: [cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 30, 0.03] +}; + +feature_params = { + maxCorners: 100, + qualityLevel: 0.1, + minDistance: 10 +}; + +// Create some random colors +var color = [255, 0, 0]; + +// Take first frame and find corners in it +cap.read(function(err, firstFrame) { + if (err) throw err; + + var old_frame = firstFrame; + + // Create a mask image for drawing purposes + function read() { + var out = old_frame.copy(); + cap.read(function(err, newFrame) { if (err) throw err; - console.log(im.size()) - if (im.size()[0] > 0 && im.size()[1] > 0){ - window.show(im); + + var goodFeatures = old_frame.goodFeaturesToTrack(feature_params.maxCorners, feature_params.qualityLevel, feature_params.minDistance); + + // calculate optical flow + var flow = old_frame.calcOpticalFlowPyrLK(newFrame, goodFeatures, lk_params.winSize, lk_params.maxLevel, lk_params.criteria); + + // Select good points + + // draw the tracks + for(var i = 0; i < flow.old_points.length; i++){ + if(flow.found[i]){ + out.line(flow.old_points[i], flow.new_points[i], color); + } } + window.show(out); window.blockingWaitKey(0, 50); + old_frame = newFrame.copy(); + read(); }); - }, 20); - */ -} catch (e){ - console.log("Couldn't start camera:", e) -} + } + + read(); +}); \ No newline at end of file diff --git a/src/Matrix.cc b/src/Matrix.cc index f0134aa..cda5221 100755 --- a/src/Matrix.cc +++ b/src/Matrix.cc @@ -82,6 +82,7 @@ void Matrix::Init(Local target) { Nan::SetPrototypeMethod(ctor, "drawContour", DrawContour); Nan::SetPrototypeMethod(ctor, "drawAllContours", DrawAllContours); Nan::SetPrototypeMethod(ctor, "goodFeaturesToTrack", GoodFeaturesToTrack); + Nan::SetPrototypeMethod(ctor, "calcOpticalFlowPyrLK", CalcOpticalFlowPyrLK); Nan::SetPrototypeMethod(ctor, "houghLinesP", HoughLinesP); Nan::SetPrototypeMethod(ctor, "houghCircles", HoughCircles); Nan::SetPrototypeMethod(ctor, "inRange", inRange); @@ -1596,13 +1597,17 @@ NAN_METHOD(Matrix::GoodFeaturesToTrack) { Nan::HandleScope scope; Matrix *self = Nan::ObjectWrap::Unwrap(info.This()); + int maxCorners = info.Length() >= 1 ? info[0]->IntegerValue() : 500; + double qualityLevel = info.Length() >= 2 ? (double) info[1]->NumberValue() : 0.01; + double minDistance = info.Length() >= 3 ? (double) info[2]->NumberValue() : 10; + std::vector corners; cv::Mat gray; cvtColor(self->mat, gray, CV_BGR2GRAY); equalizeHist(gray, gray); - cv::goodFeaturesToTrack(gray, corners, 500, 0.01, 10); + cv::goodFeaturesToTrack(gray, corners, maxCorners, qualityLevel, minDistance); v8::Local arr = Nan::New(corners.size()); for (unsigned int i=0; i(info.This()); + Matrix *newMatrix = Nan::ObjectWrap::Unwrap(info[0]->ToObject()); + Local points = Local::Cast(info[1]->ToObject()); + std::vector old_points; + + for (unsigned int i=0; iLength(); i++) { + Local pt = points->Get(i)->ToObject(); + old_points.push_back(cv::Point2f(pt->Get(0)->NumberValue(), pt->Get(1)->NumberValue())); + } + + cv::Size winSize; + if (info.Length() >= 3 && info[2]->IsArray()) { + Local winSizeObj = info[2]->ToObject(); + winSize = cv::Size(winSizeObj->Get(0)->IntegerValue(), winSizeObj->Get(1)->IntegerValue()); + } else { + winSize = cv::Size(21, 21); + } + + int maxLevel = info.Length() >= 4 ? info[3]->IntegerValue() : 3; + + cv::TermCriteria criteria; + if (info.Length() >= 5 && info[4]->IsArray()) { + Local criteriaObj = info[4]->ToObject(); + criteria = cv::TermCriteria(criteriaObj->Get(0)->IntegerValue(), criteriaObj->Get(1)->IntegerValue(), (double) criteriaObj->Get(2)->NumberValue()); + } else { + criteria = cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 0.01); + } + + int flags = info.Length() >= 6 ? info[5]->IntegerValue() : 0; + double minEigThreshold = info.Length() >= 7 ? info[6]->NumberValue() : 1e-4; + + cv::Mat old_gray; + cv::cvtColor(self->mat, old_gray, CV_BGR2GRAY); + + cv::Mat new_gray; + cv::cvtColor(newMatrix->mat, new_gray, CV_BGR2GRAY); + + std::vector new_points; + std::vector status; + std::vector err; + + cv::calcOpticalFlowPyrLK(old_gray, new_gray, old_points, new_points, status, err, winSize, maxLevel, criteria, flags, minEigThreshold); + + v8::Local old_arr = Nan::New(old_points.size()); + v8::Local new_arr = Nan::New(new_points.size()); + v8::Local found = Nan::New(status.size()); + + for (unsigned int i=0; i pt = Nan::New(2); + pt->Set(0, Nan::New((double) old_points[i].x)); + pt->Set(1, Nan::New((double) old_points[i].y)); + old_arr->Set(i, pt); + } + + for (unsigned int i=0; i pt = Nan::New(2); + pt->Set(0, Nan::New((double) new_points[i].x)); + pt->Set(1, Nan::New((double) new_points[i].y)); + new_arr->Set(i, pt); + } + + for (unsigned int i=0; i pt = Nan::New((int)status[i]); + found->Set(i, pt); + } + + Local data = Nan::New(); + data->Set(Nan::New("old_points").ToLocalChecked(), old_arr); + data->Set(Nan::New("new_points").ToLocalChecked(), new_arr); + data->Set(Nan::New("found").ToLocalChecked(), found); + + info.GetReturnValue().Set(data); +} + NAN_METHOD(Matrix::HoughLinesP) { Nan::HandleScope scope; diff --git a/src/Matrix.h b/src/Matrix.h index b672879..c9a9875 100755 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -89,6 +89,7 @@ public: // Feature Detection JSFUNC(GoodFeaturesToTrack) + JSFUNC(CalcOpticalFlowPyrLK) JSFUNC(HoughLinesP) JSFUNC(HoughCircles) diff --git a/src/OpenCV.cc b/src/OpenCV.cc index c0e666b..9ac5f24 100755 --- a/src/OpenCV.cc +++ b/src/OpenCV.cc @@ -9,6 +9,8 @@ void OpenCV::Init(Local target) { char out [21]; int n = sprintf(out, "%i.%i", CV_MAJOR_VERSION, CV_MINOR_VERSION); target->Set(Nan::New("version").ToLocalChecked(), Nan::New(out, n).ToLocalChecked()); + target->Set(Nan::New("TERM_CRITERIA_EPS").ToLocalChecked(), Nan::New((int)cv::TermCriteria::EPS)); + target->Set(Nan::New("TERM_CRITERIA_COUNT").ToLocalChecked(), Nan::New((int)cv::TermCriteria::COUNT)); Nan::SetMethod(target, "readImage", ReadImage); Nan::SetMethod(target, "readImageMulti", ReadImageMulti);