Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

WIP on camshift re #22 - Got a working example but still unreliable

This is a combination of 4 commits.
WIP on camshift - need to focus the histogram on the ROI

Weird fringing issue, but otherwise tracking objects successfully

motion track example

WIP on camshift

WIP on camshift - have a smoke example, but bad results are coming back.
  • Loading branch information...
commit 6df8bbbb9b0c95cc34d4d1e95942ed0b5e9c9ad0 1 parent e33afd9
@peterbraden authored
View
24 examples/motion-track.js
@@ -0,0 +1,24 @@
+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 x = 0;
+ var iter = function(){
+ vid.read(function(m2){
+ x++;
+ var rec = track.track(m2)
+ console.log(">>", x, ":" , rec)
+ if (x % 10 == 0){
+ m2.rectangle([rec[0], rec[1]], [rec[2], rec[3]])
+ m2.save('./out' + x + '.jpg')
+ }
+ if (x<100)
+ iter();
+ })
+ }
+ iter();
+})
+
View
4 smoke/smoke.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-node-gyp rebuild && echo '-- Compiled OK --
+node-gyp build && echo '-- Compiled OK --
-' && node smoke/smoketest.js && echo '-- Smoke Done, running tests --
+' && node examples/motion-track.js && 0 && node smoke/smoketest.js && echo '-- Smoke Done, running tests --
' && npm test
View
15 smoke/smoketest.js
@@ -1,4 +1,7 @@
var cv = require('../lib/opencv')
+
+
+
/*
new cv.VideoCapture(0).read(function(mat){
@@ -33,15 +36,3 @@ cv.readImage("./examples/stuff.png", function(err, im){
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")
-})
View
67 src/CamShift.cc
@@ -25,11 +25,24 @@ Handle<Value>
TrackedObject::New(const Arguments &args) {
HandleScope scope;
- if (args.This()->InternalFieldCount() == 0)
- return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));
-
+ if (args.This()->InternalFieldCount() == 0){
+ JSTHROW_TYPE("Cannot Instantiate without new")
+ }
+
Matrix* m = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
- cv::Rect r = cv::Rect(0, 0, 50, 50);
+ cv::Rect r;
+
+ if (args[1]->IsArray()){
+ Local<Object> v8rec = args[1]->ToObject();
+ r = cv::Rect(
+ v8rec->Get(0)->IntegerValue(),
+ v8rec->Get(1)->IntegerValue(),
+ v8rec->Get(2)->IntegerValue() - v8rec->Get(0)->IntegerValue(),
+ v8rec->Get(3)->IntegerValue() - v8rec->Get(1)->IntegerValue());
+ } else {
+ JSTHROW_TYPE("Must pass rectangle to track")
+ }
+
TrackedObject *to = new TrackedObject(m->mat, r);
to->Wrap(args.This());
@@ -58,6 +71,7 @@ void update_hue_image(TrackedObject* t, cv::Mat image){
TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect){
update_hue_image(this, image);
+ prev_rect = rect;
// Calculate Histogram
int hbins = 30, sbins = 32;
@@ -67,11 +81,12 @@ TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect){
// 255 (pure spectrum color)
float sranges[] = { 0, 256 };
const float* ranges[] = { sranges };
+
+ cv::Mat hue_roi = hue(rect);
+ cv::Mat mask_roi = mask(rect);
- cv::calcHist(&hue, 1, 0, mask, hist, 1, histSizes, ranges, true, false);
-
-
- prev_rect = rect;
+ cv::calcHist(&hue_roi, 1, 0, mask_roi, hist, 1, histSizes, ranges, true, false);
+
}
@@ -88,8 +103,21 @@ TrackedObject::Track(const v8::Arguments& args){
Matrix *im = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
cv::RotatedRect r;
+
+ if (self->prev_rect.x <0 ||
+ self->prev_rect.y <0 ||
+ self->prev_rect.width <= 1 ||
+ self->prev_rect.height <= 1){
+ return v8::ThrowException(v8::Exception::TypeError(v8::String::New("OPENCV ERROR: prev rectangle is illogical")));
+ }
update_hue_image(self, im->mat);
+
+ cv::Rect backup_prev_rect = cv::Rect(
+ self->prev_rect.x,
+ self->prev_rect.y,
+ self->prev_rect.width,
+ self->prev_rect.height);
float sranges[] = { 0, 256 };
const float* ranges[] = { sranges };
@@ -99,8 +127,27 @@ TrackedObject::Track(const v8::Arguments& args){
r = cv::CamShift(self->prob, self->prev_rect,
cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1));
+ cv::Rect bounds = r.boundingRect();
+ if (bounds.x >=0 && bounds.y >=0 && bounds.width > 1 && bounds.height > 1){
+ self->prev_rect = bounds;
+ } else {
+ //printf("CRAP> %i %i %i %i ;", self->prev_rect.x, self->prev_rect.y, self->prev_rect.width, self->prev_rect.height);
+
+ // We have encountered a bug in opencv. Somehow the prev_rect has got mangled, so we
+ // must reset it to a good value.
+ self->prev_rect = backup_prev_rect;
+ }
+
+
v8::Local<v8::Array> arr = v8::Array::New(4);
-
+
+
+ arr->Set(0, Number::New(bounds.x));
+ arr->Set(1, Number::New(bounds.y));
+ arr->Set(2, Number::New(bounds.x + bounds.width));
+ arr->Set(3, Number::New(bounds.y + bounds.height));
+
+ /*
cv::Point2f pts[4];
r.points(pts);
@@ -108,6 +155,8 @@ TrackedObject::Track(const v8::Arguments& args){
arr->Set(i, Number::New(pts[i].x));
arr->Set(i+1, Number::New(pts[i].y));
}
+*/
+
return scope.Close(arr);
}
View
1  src/CamShift.h
@@ -10,7 +10,6 @@ class TrackedObject: public node::ObjectWrap {
cv::Mat hist;
cv::Rect prev_rect;
- // cv::Box2D curr_box;
static Persistent<FunctionTemplate> constructor;
static void Init(Handle<Object> target);
View
2  src/OpenCV.h
@@ -27,6 +27,8 @@ using namespace node;
#define JSFUNC(NAME) \
static Handle<Value> NAME(const Arguments& args);
+#define JSTHROW_TYPE(ERR) \
+ return v8::ThrowException(v8::Exception::TypeError(v8::String::New(ERR)));
class OpenCV: public node::ObjectWrap{
View
15 src/VideoCaptureWrap.cc
@@ -46,7 +46,10 @@ VideoCaptureWrap::New(const Arguments &args) {
if (args[0]->IsNumber()){
v = new VideoCaptureWrap(args[0]->NumberValue());
- } else {}
+ } else {
+ //TODO - assumes that we have string, verify
+ v = new VideoCaptureWrap(std::string(*v8::String::AsciiValue(args[0]->ToString())));
+ }
v->Wrap(args.This());
@@ -64,6 +67,16 @@ VideoCaptureWrap::VideoCaptureWrap(int device){
}
}
+VideoCaptureWrap::VideoCaptureWrap(const string& filename){
+ HandleScope scope;
+ cap.open(filename);
+ // TODO! At the moment this only takes a full path - do relative too.
+ if(!cap.isOpened()){
+ v8::ThrowException(v8::Exception::Error(String::New("Video file could not be opened (opencv reqs. non relative paths)")));
+ }
+
+}
+
Handle<Value>
VideoCaptureWrap::Read(const Arguments &args) {
Please sign in to comment.
Something went wrong with that request. Please try again.