NexusCS

Tracking.js

JavaScript
Tracking.js is a lightweight browser computer vision library (~7KB) providing color tracking, face/eye/mouth detection, and feature detection. Note: This library is unmaintained since 2016.
computer-vision
face-detection
color-tracking
image-processing

Getting started

Installation

npm install tracking

Basic setup

<!-- Core library -->
<script src="tracking-min.js"></script>

<!-- Optional: Object detection classifiers (~60KB each) -->
<script src="build/data/face-min.js"></script>
<script src="build/data/eye-min.js"></script>
<script src="build/data/mouth-min.js"></script>

Classifier data files must be loaded separately for face/eye/mouth detection.

Quick example

var tracker = new tracking.ColorTracker(["magenta"]);

tracker.on("track", function (event) {
  event.data.forEach(function (rect) {
    console.log(rect.x, rect.y, rect.width, rect.height);
  });
});

tracking.track("#myVideo", tracker, { camera: true });

Library info

Property Value
Size ~7 KB minified
Version 1.1.3 (Sep 2016)
Status ⚠️ Unmaintained
License MIT

Uses Viola-Jones for object detection, FAST for corners, BRIEF for descriptors.

Color tracking

Basic color detection

var tracker = new tracking.ColorTracker(["magenta", "cyan", "yellow"]);

tracker.on("track", function (event) {
  if (event.data.length === 0) {
    // No colors detected
  } else {
    event.data.forEach(function (rect) {
      console.log(rect.x, rect.y, rect.width, rect.height);
      console.log("Color:", rect.color);
    });
  }
});

tracking.track("#myImage", tracker);

Tracks built-in colors: magenta, cyan, yellow.

Live camera tracking

var tracker = new tracking.ColorTracker(["magenta", "cyan", "yellow"]);
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

tracker.on("track", function (event) {
  context.clearRect(0, 0, canvas.width, canvas.height);

  event.data.forEach(function (rect) {
    context.strokeStyle = rect.color;
    context.lineWidth = 2;
    context.strokeRect(rect.x, rect.y, rect.width, rect.height);
  });
});

tracking.track("#myVideo", tracker, { camera: true });

Use { camera: true } to access webcam. Triggers browser permission prompt.

Custom colors

tracking.ColorTracker.registerColor("green", function (r, g, b) {
  if (r < 50 && g > 200 && b < 50) {
    return true;
  }
  return false;
});

var tracker = new tracking.ColorTracker(["green"]);

Callback runs per pixel per frame - keep it fast.

ColorTracker configuration

var tracker = new tracking.ColorTracker();

tracker.setColors(["magenta", "cyan"]);
tracker.setMinDimension(30); // Min rect dimension
tracker.setMinGroupSize(50); // Min group size
Method Default Description
setColors(array) [] Set tracked colors
setMinDimension(n) 20 Minimum rectangle size
setMinGroupSize(n) 30 Minimum pixel cluster

Object tracking

Face detection

var tracker = new tracking.ObjectTracker("face");

tracker.on("track", function (event) {
  event.data.forEach(function (rect) {
    console.log("Face at", rect.x, rect.y);
    console.log("Size:", rect.width, "x", rect.height);
  });
});

tracking.track("#myImage", tracker);

Requires face-min.js classifier loaded via script tag.

Live face tracking

var tracker = new tracking.ObjectTracker("face");
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

tracker.setInitialScale(4);
tracker.setStepSize(2);
tracker.setEdgesDensity(0.1);

tracker.on("track", function (event) {
  context.clearRect(0, 0, canvas.width, canvas.height);

  event.data.forEach(function (rect) {
    context.strokeStyle = "#a64ceb";
    context.lineWidth = 2;
    context.strokeRect(rect.x, rect.y, rect.width, rect.height);
  });
});

tracking.track("#video", tracker, { camera: true });

Multiple classifiers

var tracker = new tracking.ObjectTracker(["face", "eye", "mouth"]);

tracker.on("track", function (event) {
  console.log("Detected", event.data.length, "objects");
  // Note: Can't distinguish which type each detection is
});

⚠️ Each classifier script must be loaded. Event data doesn't indicate detection type.

ObjectTracker options

tracker.setInitialScale(4); // Starting scale
tracker.setScaleFactor(1.25); // Scale increment
tracker.setStepSize(2); // Step size
tracker.setEdgesDensity(0.1); // Edge threshold
Method Default Description
setInitialScale(n) 1.0 Starting feature block scale
setScaleFactor(n) 1.25 Scale factor between passes
setStepSize(n) 1.5 Block step size
setEdgesDensity(n) 0.2 Edges density threshold

Tracker control

Start/stop tracking

var trackerTask = tracking.track("#video", tracker, { camera: true });

// Later...
trackerTask.stop(); // Stop tracking
trackerTask.run(); // Resume tracking

Track different elements

// Track image
tracking.track("#myImage", tracker);

// Track video
tracking.track("#myVideo", tracker);

// Track canvas
tracking.track("#myCanvas", tracker);

// Track with camera
tracking.track("#video", tracker, { camera: true });

Works with img, video, and canvas elements.

Feature detection

FAST corner detection

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

var corners = tracking.Fast.findCorners(
  imageData.data,
  canvas.width,
  canvas.height,
);

console.log("Found", corners.length / 2, "corners");
// corners = [x1, y1, x2, y2, ...]

FAST (Features from Accelerated Segment Test) algorithm for corner detection.

BRIEF descriptors

var gray = new Uint8ClampedArray(imageData.data.length);
tracking.Image.grayscale(imageData.data, canvas.width, canvas.height, gray);

var corners1 = tracking.Fast.findCorners(gray, width, height);
var desc1 = tracking.Brief.getDescriptors(gray, width, corners1);

var corners2 = tracking.Fast.findCorners(gray2, width, height);
var desc2 = tracking.Brief.getDescriptors(gray2, width, corners2);

BRIEF (Binary Robust Independent Elementary Features) for feature descriptors.

Feature matching

var matches = tracking.Brief.reciprocalMatch(corners1, desc1, corners2, desc2);

matches.forEach(function (match) {
  console.log("Match confidence:", match.confidence);
  console.log("Index 1:", match.index1);
  console.log("Index 2:", match.index2);
});

Reciprocal matching for robust feature correspondence.

Image utilities

Grayscale conversion

var gray = new Uint8ClampedArray(imageData.data.length);

tracking.Image.grayscale(
  imageData.data, // Source pixels
  canvas.width, // Width
  canvas.height, // Height
  gray, // Output array
);

Converts RGBA image to grayscale.

Image filters

// Blur
tracking.Image.blur(pixels, width, height, diameter);

// Sobel edge detection
tracking.Image.sobel(pixels, width, height);

// Horizontal convolution
tracking.Image.horizontalConvolve(pixels, width, height, weightsVector, opaque);

// Vertical convolution
tracking.Image.verticalConvolve(pixels, width, height, weightsVector, opaque);

Separable convolution

tracking.Image.separableConvolve(
  pixels,
  width,
  height,
  horizWeights, // Horizontal kernel
  vertWeights, // Vertical kernel
  opaque, // Preserve alpha
);

Efficient 2D convolution using separable kernels.

Custom tracker

Create tracker class

var MyTracker = function () {
  MyTracker.base(this, "constructor");
};

tracking.inherits(MyTracker, tracking.Tracker);

MyTracker.prototype.track = function (pixels, width, height) {
  // Custom tracking logic
  var results = [];

  // ... process pixels ...

  this.emit("track", {
    data: results,
  });
};

Extend tracking.Tracker for custom algorithms.

Use custom tracker

var myTracker = new MyTracker();

myTracker.on("track", function (event) {
  console.log("Custom results:", event.data);
});

tracking.track("#video", myTracker, { camera: true });

Track event data

tracker.on("track", function (event) {
  event.data.forEach(function (rect) {
    console.log(rect.x); // Left position
    console.log(rect.y); // Top position
    console.log(rect.width); // Width
    console.log(rect.height); // Height
    console.log(rect.color); // Color (ColorTracker only)
  });
});
Property Type Description
x Number Left position (px)
y Number Top position (px)
width Number Rectangle width (px)
height Number Rectangle height (px)
color String Color name (ColorTracker)

Gotchas

⚠️ Unmaintained library

Tracking.js hasn't been updated since September 2016 (v1.1.3). Maintainers wanted since January 2021. Consider modern alternatives:

  • TensorFlow.js - ML models including face detection, pose estimation
  • MediaPipe - Google's cross-platform ML solutions
  • face-api.js - Face detection/recognition built on TensorFlow.js

⚠️ Camera permissions

tracking.track("#video", tracker, { camera: true });

Triggers browser permission prompt. Fails silently if user denies camera access. Always provide fallback UI.

⚠️ Classifier files required

<script src="build/data/face-min.js"></script>
<!-- ~60KB -->
<script src="build/data/eye-min.js"></script>
<!-- ~60KB -->
<script src="build/data/mouth-min.js"></script>
<!-- ~60KB -->

ObjectTracker needs separate classifier JS files loaded before use. Large file sizes (~60KB each compressed).

⚠️ Custom color performance

tracking.ColorTracker.registerColor("green", function (r, g, b) {
  // This runs for EVERY pixel in EVERY frame
  return r < 50 && g > 200 && b < 50;
});

Callback executes per-pixel per-frame. Keep logic minimal for real-time performance.

⚠️ No detection type info

var tracker = new tracking.ObjectTracker(["face", "eye", "mouth"]);

tracker.on("track", function (event) {
  // Can't tell if rect is face, eye, or mouth
  event.data.forEach(function (rect) {
    console.log("Type:", "???"); // No type property
  });
});

Multiple classifiers don't distinguish detection types in event data.

Also see