From c4aac1d20185d1207227894233105c9b0c5c291b Mon Sep 17 00:00:00 2001 From: Peter Braden Date: Tue, 27 Nov 2012 16:08:58 -0800 Subject: [PATCH] Allow specifying which image channel to use for the back projection --- examples/motion-track.js | 2 +- src/CamShift.cc | 43 +++++++++++++++++++++++++++++++++------- src/CamShift.h | 3 ++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/examples/motion-track.js b/examples/motion-track.js index 309a825..89b4c1c 100644 --- a/examples/motion-track.js +++ b/examples/motion-track.js @@ -4,7 +4,7 @@ var cv = require('../lib/opencv') var vid = new cv.VideoCapture("/Users/peterbraden/Desktop/repos/node-opencv/examples/motion.avi") vid.read(function(mat){ - var track = new cv.TrackedObject(mat, [420, 110, 490, 170]); + var track = new cv.TrackedObject(mat, [420, 110, 490, 170], {channel: "value"}); var x = 0; var iter = function(){ vid.read(function(m2){ diff --git a/src/CamShift.cc b/src/CamShift.cc index b4d8399..c44a40b 100644 --- a/src/CamShift.cc +++ b/src/CamShift.cc @@ -2,6 +2,12 @@ #include "OpenCV.h" #include "Matrix.h" + +#define CHANNEL_HUE 0 +#define CHANNEL_SATURATION 1 +#define CHANNEL_VALUE 2 + + Persistent TrackedObject::constructor; void @@ -31,6 +37,7 @@ TrackedObject::New(const Arguments &args) { Matrix* m = ObjectWrap::Unwrap(args[0]->ToObject()); cv::Rect r; + int channel = CHANNEL_HUE; if (args[1]->IsArray()){ Local v8rec = args[1]->ToObject(); @@ -42,15 +49,37 @@ TrackedObject::New(const Arguments &args) { } else { JSTHROW_TYPE("Must pass rectangle to track") } + + if (args[2]->IsObject()){ + Local opts = args[2]->ToObject(); - TrackedObject *to = new TrackedObject(m->mat, r); + if (opts->Get(String::New("channel"))->IsString()){ + v8::String::Utf8Value c(opts->Get(String::New("channel"))->ToString()); + std::string cc = std::string(*c); + + if (cc == "hue" || cc == "h"){ + channel = CHANNEL_HUE; + } + + if (cc == "saturation" || cc == "s"){ + channel = CHANNEL_SATURATION; + } + + if (cc == "value" || cc == "v"){ + channel = CHANNEL_VALUE; + } + } + } + + TrackedObject *to = new TrackedObject(m->mat, r, channel); + to->Wrap(args.This()); return args.This(); } -void update_hue_image(TrackedObject* t, cv::Mat image){ +void update_chann_image(TrackedObject* t, cv::Mat image){ // Store HSV Hue Image cv::cvtColor(image, t->hsv, CV_BGR2HSV); // convert to HSV space //mask out-of-range values @@ -63,14 +92,14 @@ void update_hue_image(TrackedObject* t, cv::Mat image){ //extract the hue channel, split: src, dest channels vector hsvplanes; cv::split(t->hsv, hsvplanes); - t->hue = hsvplanes[0]; + t->hue = hsvplanes[t->channel]; } -TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect){ - - update_hue_image(this, image); +TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect, int chan){ + channel = chan; + update_chann_image(this, image); prev_rect = rect; // Calculate Histogram @@ -111,7 +140,7 @@ TrackedObject::Track(const v8::Arguments& args){ return v8::ThrowException(v8::Exception::TypeError(v8::String::New("OPENCV ERROR: prev rectangle is illogical"))); } - update_hue_image(self, im->mat); + update_chann_image(self, im->mat); cv::Rect backup_prev_rect = cv::Rect( self->prev_rect.x, diff --git a/src/CamShift.h b/src/CamShift.h index ab97a39..649a65f 100644 --- a/src/CamShift.h +++ b/src/CamShift.h @@ -3,6 +3,7 @@ class TrackedObject: public node::ObjectWrap { public: + int channel; cv::Mat hsv; cv::Mat hue; cv::Mat mask; @@ -15,7 +16,7 @@ class TrackedObject: public node::ObjectWrap { static void Init(Handle target); static Handle New(const Arguments &args); - TrackedObject(cv::Mat image, cv::Rect rect); + TrackedObject(cv::Mat image, cv::Rect rect, int channel); JSFUNC(Track);