Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ module.exports = {

The TypeScript type declarations may not be up to date with the latest OpenCV.js. Refer to [cvKeys.json](doc/cvKeys.json) to check the available methods and properties at runtime.

## OpenCV Contrib Modules

The default opencv.js build includes core OpenCV modules but **does not include opencv_contrib modules** (like the `face` module).

If you need opencv_contrib modules such as:
- `cv.face.createFacemarkLBF()` - Facial landmark detection
- Other face analysis features
- Extended features from opencv_contrib

You will need to build a custom opencv.js from source. See the [Face Module Guide](doc/FACE_MODULE.md) for detailed instructions.

**Available modules in default build:** calib3d, core, dnn, features2d, flann, imgproc, js, objdetect, photo, video

# Star History

[![Star History Chart](https://api.star-history.com/svg?repos=techstark/opencv-js&type=Date)](https://star-history.com/#techstark/opencv-js&Date)
183 changes: 183 additions & 0 deletions doc/FACE_MODULE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Face Module Support - createFacemarkLBF

## Overview

The `face` module in OpenCV provides facial landmark detection capabilities, including the `createFacemarkLBF` function. This document explains how to use these features with opencv-js.

## Important: Face Module Availability

**The default opencv.js binary does NOT include the face module.** The face module is part of the opencv_contrib repository and requires a custom build.

### Current opencv.js Build Includes:
- calib3d
- core
- dnn
- features2d
- flann
- imgproc
- js
- objdetect
- photo
- video

### NOT Included (requires custom build):
- **face** (contains createFacemarkLBF)
- and other opencv_contrib modules

## TypeScript Support

This package provides TypeScript type definitions for the face module, even though it's not included in the default opencv.js binary. These type definitions are available for users who build custom opencv.js with the face module enabled.

## Using createFacemarkLBF

### Option 1: Build Custom opencv.js (Recommended)

To use `cv.face.createFacemarkLBF`, you need to build opencv.js from source with opencv_contrib modules:

1. **Clone OpenCV and OpenCV Contrib repositories:**
```bash
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
```

2. **Install Emscripten SDK:**
```bash
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
```

3. **Build opencv.js with face module:**
```bash
cd opencv
python ./platforms/js/build_js.py build_js \
--cmake_option="-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules" \
--build_wasm
```

4. **Replace the opencv.js in your project** with the newly built one from `build_js/bin/opencv.js`

### Option 2: Use Alternative Face Detection Methods

If you don't need facial landmark detection specifically, consider using the built-in face detection methods:

- **FaceDetectorYN** - Available in the default opencv.js build
- **CascadeClassifier** - Haar cascade face detection (available)

Example using CascadeClassifier:
```typescript
import cv from "@techstark/opencv-js";

// Load face cascade classifier
const faceCascade = new cv.CascadeClassifier();
faceCascade.load('haarcascade_frontalface_default.xml');

// Detect faces
const gray = new cv.Mat();
cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY);

const faces = new cv.RectVector();
faceCascade.detectMultiScale(gray, faces);

console.log(`Detected ${faces.size()} faces`);

// Clean up
faces.delete();
gray.delete();
faceCascade.delete();
```

## Example Usage (with custom build)

Once you have opencv.js built with the face module, you can use it like this:

```typescript
import cv from "@techstark/opencv-js";

async function detectFacialLandmarks() {
// Create facemark instance
const facemark = cv.face.createFacemarkLBF();

// Load pre-trained model
// Download from: https://github.com/kurnianggoro/GSOC2017/tree/master/data
facemark.loadModel('lbfmodel.yaml');

// First, detect faces using a face detector
const faceCascade = new cv.CascadeClassifier();
faceCascade.load('haarcascade_frontalface_default.xml');

// Convert image to grayscale
const gray = new cv.Mat();
cv.cvtColor(image, gray, cv.COLOR_RGBA2GRAY);

// Detect faces
const faces = new cv.RectVector();
faceCascade.detectMultiScale(gray, faces);

// Detect landmarks for each face
const landmarks = new cv.MatVector();
const success = facemark.fit(gray, faces, landmarks);

if (success) {
// Process landmarks
for (let i = 0; i < landmarks.size(); i++) {
const points = landmarks.get(i);
// Each face has 68 landmark points (for LBF model)
console.log(`Face ${i} has ${points.rows} landmarks`);

// Draw landmarks on image
for (let j = 0; j < points.rows; j++) {
const x = points.floatAt(j, 0);
const y = points.floatAt(j, 1);
cv.circle(image, new cv.Point(x, y), 2, new cv.Scalar(0, 255, 0), -1);
}
}
}

// Clean up
landmarks.delete();
faces.delete();
gray.delete();
faceCascade.delete();
facemark.delete();
}
```

## FacemarkLBF Parameters

You can customize the FacemarkLBF algorithm with parameters:

```typescript
const params = new cv.face.FacemarkLBF_Params();
params.cascade_depth = 10;
params.tree_depth = 5;
params.num_trees_per_cascade_level = 500;
params.learning_rate = 0.1;

const facemark = cv.face.createFacemarkLBF(params);
```

## Pre-trained Models

To use FacemarkLBF, you need a pre-trained model file. You can download models from:

- [OpenCV Face Module Models](https://github.com/kurnianggoro/GSOC2017/tree/master/data)
- The default LBF model: `lbfmodel.yaml` (~56MB)

## Resources

- [OpenCV Face Module Documentation](https://docs.opencv.org/4.x/d1/d1d/group__face.html)
- [FacemarkLBF Paper](https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Ren_Face_Alignment_at_2014_CVPR_paper.pdf)
- [Building opencv.js](https://docs.opencv.org/4.x/d4/da1/tutorial_js_setup.html)
- [opencv_contrib Repository](https://github.com/opencv/opencv_contrib)

## Summary

1. **Type definitions are available** - This package includes TypeScript types for `cv.face.createFacemarkLBF`
2. **Runtime not available by default** - The face module is not in the default opencv.js build
3. **Custom build required** - To use face module at runtime, build opencv.js from source with opencv_contrib
4. **Alternatives exist** - Consider using FaceDetectorYN or CascadeClassifier if you only need face detection

If you have questions or need help building opencv.js with the face module, please open an issue on GitHub.
76 changes: 76 additions & 0 deletions doc/face-example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Example TypeScript code demonstrating type definitions for cv.face.createFacemarkLBF.
*
* NOTE: This code will compile with TypeScript but will NOT run with the default opencv.js
* because the face module is not included in the default build.
*
* To run this code, you need to build opencv.js from source with opencv_contrib modules.
* See doc/FACE_MODULE.md for instructions.
*/

import * as cv from "../src/types/opencv";

async function exampleFacialLandmarkDetection() {
// This example shows TypeScript type checking for face module
// The types are available, but runtime will fail unless using custom opencv.js build

// Create facemark instance with default parameters
const facemark = cv.face.createFacemarkLBF();

// Or create with custom parameters
const params = new cv.face.FacemarkLBF_Params();
params.cascade_depth = 10;
params.tree_depth = 5;
params.num_trees_per_cascade_level = 500;
const facemarkCustom = cv.face.createFacemarkLBF(params);

// Load pre-trained model
facemark.loadModel("lbfmodel.yaml");

// Create face detector
const faceCascade = new cv.CascadeClassifier();
faceCascade.load("haarcascade_frontalface_default.xml");

// Assume we have an image (this is pseudocode)
const image = new cv.Mat();
const gray = new cv.Mat();
cv.cvtColor(image, gray, cv.COLOR_RGBA2GRAY);

// Detect faces
const faces = new cv.RectVector();
faceCascade.detectMultiScale(gray, faces);

// Fit landmarks
const landmarks = new cv.MatVector();
const success: boolean = facemark.fit(gray, faces, landmarks);

if (success) {
console.log(`Detected landmarks for ${landmarks.size()} faces`);

// Process each face's landmarks
for (let i = 0; i < landmarks.size(); i++) {
const points = landmarks.get(i);
console.log(`Face ${i}: ${points.rows} landmark points`);

// Draw landmarks (68 points for LBF model)
for (let j = 0; j < points.rows; j++) {
const x = points.floatAt(j, 0);
const y = points.floatAt(j, 1);
cv.circle(image, new cv.Point(x, y), 2, new cv.Scalar(0, 255, 0), -1);
}
}
}

// Clean up
landmarks.delete();
faces.delete();
gray.delete();
image.delete();
faceCascade.delete();
facemark.delete();
facemarkCustom.delete();
}

// TypeScript type checking will pass for this file
// Runtime execution requires custom opencv.js build with face module
export { exampleFacialLandmarkDetection };
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 17 additions & 7 deletions src/types/opencv/BackgroundSubtractor.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import type { Algorithm, bool, double, InputArray, OutputArray } from "./_types";
import type {
Algorithm,
bool,
double,
InputArray,
OutputArray,
} from "./_types";

/**
* Base class for background/foreground segmentation algorithms.
*
* The class is only used to define the common interface for the whole family of background/foreground
* The class is only used to define the common interface for the whole family of background/foreground
* segmentation algorithms.
*
* Source:
Expand All @@ -17,20 +23,24 @@ export declare class BackgroundSubtractor extends Algorithm {
*
* @param image Next video frame.
* @param fgmask The output foreground mask as an 8-bit binary image.
* @param learningRate The value between 0 and 1 that indicates how fast the background model is learnt.
* @param learningRate The value between 0 and 1 that indicates how fast the background model is learnt.
* Negative parameter value makes the algorithm use some automatically chosen learning rate.
* 0 means that the background model is not updated at all, 1 means that the background model is
* 0 means that the background model is not updated at all, 1 means that the background model is
* completely reinitialized from the last frame.
*/
public apply(image: InputArray, fgmask: OutputArray, learningRate?: double): void;
public apply(
image: InputArray,
fgmask: OutputArray,
learningRate?: double,
): void;

/**
* Computes a background image.
*
* @param backgroundImage The output background image.
*
* @note Sometimes the background image can be very blurry, as it contain the average background
* @note Sometimes the background image can be very blurry, as it contain the average background
* statistics.
*/
public getBackgroundImage(backgroundImage: OutputArray): void;
}
}
16 changes: 10 additions & 6 deletions src/types/opencv/BackgroundSubtractorMOG2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { BackgroundSubtractor, bool, double, int } from "./_types";
/**
* Gaussian Mixture-based Background/Foreground Segmentation Algorithm.
*
* The class implements the Gaussian mixture model background subtraction described in [Zivkovic2004]
* The class implements the Gaussian mixture model background subtraction described in [Zivkovic2004]
* and [Zivkovic2006].
*
* Source:
Expand All @@ -12,11 +12,15 @@ import type { BackgroundSubtractor, bool, double, int } from "./_types";
export declare class BackgroundSubtractorMOG2 extends BackgroundSubtractor {
/**
* @param history Length of the history.
* @param varThreshold Threshold on the squared Mahalanobis distance between the pixel and the model
* to decide whether a pixel is well described by the background model. This parameter does not
* @param varThreshold Threshold on the squared Mahalanobis distance between the pixel and the model
* to decide whether a pixel is well described by the background model. This parameter does not
* affect the background update.
* @param detectShadows If true, the algorithm will detect shadows and mark them. It decreases the
* @param detectShadows If true, the algorithm will detect shadows and mark them. It decreases the
* speed a bit, so if you do not need this feature, set the parameter to false.
*/
public constructor(history?: int, varThreshold?: double, detectShadows?: bool);
}
public constructor(
history?: int,
varThreshold?: double,
detectShadows?: bool,
);
}
1 change: 1 addition & 0 deletions src/types/opencv/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ export * from "./video_track";
export * from "./_hacks";
export * from "./Tracker";
export * from "./TrackerMIL";
export * from "./face";
Loading