From e33afd97efbcb356bcc43a667bbfb90516795787 Mon Sep 17 00:00:00 2001 From: Peter Braden Date: Mon, 12 Nov 2012 13:30:26 -0800 Subject: [PATCH] WIP on TrackedObject re #22 --- smoke/smoketest.js | 15 ++++++++++++++- src/CamShift.cc | 43 ++++++++++++++++++++++++++++++------------- src/init.cc | 4 +++- test/unit.js | 29 +++++++++++++++++------------ 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/smoke/smoketest.js b/smoke/smoketest.js index de8b7a3..3acdd15 100755 --- a/smoke/smoketest.js +++ b/smoke/smoketest.js @@ -15,7 +15,7 @@ new cv.VideoCapture(0).read(function(mat){ }) }) -*/ + cv.readImage("./examples/stuff.png", function(err, im){ @@ -32,3 +32,16 @@ cv.readImage("./examples/stuff.png", function(err, im){ console.log(features) im.save('./out.jpg'); }); +*/ + +cv.readImage("./examples/stuff.png", function(err, im){ + console.log("1") + var track = new cv.TrackedObject(im, [0,0,50,50]); + console.log("2") + console.log(track) + console.log("3") + console.log(track.track) + console.log("4") + console.log(track.track(im)); + console.log("5") +}) diff --git a/src/CamShift.cc b/src/CamShift.cc index 219b059..19444ed 100644 --- a/src/CamShift.cc +++ b/src/CamShift.cc @@ -16,8 +16,8 @@ TrackedObject::Init(Handle target) { // Prototype //Local proto = constructor->PrototypeTemplate(); - target->Set(String::NewSymbol("TrackedObject"), constructor->GetFunction()); NODE_SET_PROTOTYPE_METHOD(constructor, "track", Track); + target->Set(String::NewSymbol("TrackedObject"), constructor->GetFunction()); }; @@ -29,39 +29,49 @@ TrackedObject::New(const Arguments &args) { return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new"))); Matrix* m = ObjectWrap::Unwrap(args[0]->ToObject()); - cv::Rect r; + cv::Rect r = cv::Rect(0, 0, 50, 50); TrackedObject *to = new TrackedObject(m->mat, r); + to->Wrap(args.This()); return args.This(); } -TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect){ - +void update_hue_image(TrackedObject* t, cv::Mat image){ // Store HSV Hue Image - cv::cvtColor(image, hsv, CV_BGR2HSV); // convert to HSV space + cv::cvtColor(image, t->hsv, CV_BGR2HSV); // convert to HSV space //mask out-of-range values int vmin = 65, vmax = 256, smin = 55; - cv::inRange(hsv, //source + cv::inRange(t->hsv, //source cv::Scalar(0, smin, MIN(vmin, vmax), 0), //lower bound cv::Scalar(180, 256, MAX(vmin, vmax) ,0), //upper bound - mask); //destination + t->mask); //destination //extract the hue channel, split: src, dest channels - int from_to[] = { 0,0, 1,-1, 2,-1, 3,-1}; - cv::mixChannels(&hsv, 1, &hue, 1, from_to, 4); + vector hsvplanes; + cv::split(t->hsv, hsvplanes); + t->hue = hsvplanes[0]; + + +} + +TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect){ + + update_hue_image(this, image); // Calculate Histogram int hbins = 30, sbins = 32; int histSizes[] = {hbins, sbins}; - float hranges[] = { 0, 180 }; + //float hranges[] = { 0, 180 }; // saturation varies from 0 (black-gray-white) to // 255 (pure spectrum color) float sranges[] = { 0, 256 }; - const float* ranges[] = { hranges, sranges }; + const float* ranges[] = { sranges }; - cv::calcHist(&hue, 1, 0, mask, hist, 2, histSizes, ranges, true, false); + cv::calcHist(&hue, 1, 0, mask, hist, 1, histSizes, ranges, true, false); + + prev_rect = rect; } @@ -75,10 +85,17 @@ TrackedObject::Track(const v8::Arguments& args){ return Undefined(); } + Matrix *im = ObjectWrap::Unwrap(args[0]->ToObject()); - cv::RotatedRect r; + update_hue_image(self, im->mat); + + float sranges[] = { 0, 256 }; + const float* ranges[] = { sranges }; + int channel = 0; + cv::calcBackProject(&self->hue, 1, &channel, self->hist, self->prob, ranges); + r = cv::CamShift(self->prob, self->prev_rect, cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1)); diff --git a/src/init.cc b/src/init.cc index 1e3bf9f..9e4494a 100755 --- a/src/init.cc +++ b/src/init.cc @@ -4,6 +4,7 @@ #include "CascadeClassifierWrap.h" #include "VideoCaptureWrap.h" #include "Contours.h" +#include "CamShift.h" extern "C" void @@ -14,7 +15,8 @@ init(Handle target) { Matrix::Init(target); CascadeClassifierWrap::Init(target); VideoCaptureWrap::Init(target); - Contour::Init(target); + Contour::Init(target); + TrackedObject::Init(target); }; NODE_MODULE(opencv, init) diff --git a/test/unit.js b/test/unit.js index 3013469..614ba9c 100755 --- a/test/unit.js +++ b/test/unit.js @@ -258,21 +258,26 @@ vows.describe('Smoke Tests OpenCV').addBatch({ } , "CamShift" : { - topic : require('../lib/opencv') - - , "create TrackedObject" : function(cv){ - var im = fs.readFileSync('./examples/mona.png') - , track = new cv.TrackedObject(im, [10,10, 50,50]); - assert.ok(track); - } + "Can Create and Track" : { + topic : function(){ + var cv = require('../lib/opencv') + , self = this - , "use TrackedObject.track" : function(cv){ - var im = fs.readFileSync('./examples/mona.png') - , im2 = fs.readFileSync('./examples/mona.png') - , tracked = new cv.TrackedObject(im, [10,10, 50,50]); + var im = cv.readImage('./examples/mona.png', function(e, im){ + self.callback(im, cv) + }) + } + + , "create TrackedObject" : function(im, cv){ + var tracked = new cv.TrackedObject(im, [0, 0, 50, 50]); + assert.ok(tracked); + } - assert.equal(tracked.track(im2), [10, 10, 50, 50]); + , "use TrackedObject.track" : function(im,cv){ + var tracked = new cv.TrackedObject(im, [0, 0, 50, 50]); + assert.equal(tracked.track(im), [10, 10, 50, 50]); + } } }