-
Notifications
You must be signed in to change notification settings - Fork 40
add legacy object detection cocossd code and example from p5js #257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
80c35b2
4db442f
7deb4c8
ce82f51
9375570
49b2e8e
bcd1788
cdaa7c7
8864cb5
02bdb6d
946b084
d8ed389
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!-- | ||
👋 Hello! This is an ml5.js example made and shared with ❤️. | ||
Learn more about the ml5.js project: https://ml5js.org/ | ||
ml5.js license and Code of Conduct: https://github.com/ml5js/ml5-next-gen/blob/main/LICENSE.md | ||
|
||
This example demonstrates object detection on a single image through ml5.objectDetector. | ||
--> | ||
|
||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>ml5.js objectDetector Example - Single Image</title> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script> | ||
<script src="../../dist/ml5.js"></script> | ||
</head> | ||
<body> | ||
<main> | ||
</main> | ||
<script src="sketch.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* 👋 Hello! This is an ml5.js example made and shared with ❤️. | ||
* Learn more about the ml5.js project: https://ml5js.org/ | ||
* ml5.js license and Code of Conduct: https://github.com/ml5js/ml5-next-gen/blob/main/LICENSE.md | ||
* | ||
* This example demonstrates detecting objects in a live video through ml5.imageClassifier. | ||
*/ | ||
|
||
let img; | ||
let detector; | ||
let detections = []; | ||
|
||
function preload(){ | ||
detector = ml5.objectDetector("cocossd"); | ||
img = loadImage('dog_cat.jpg'); | ||
} | ||
|
||
function setup() { | ||
createCanvas(640, 480); | ||
image(img, 0, 0); | ||
detector.detectStart(img, gotDetections); | ||
} | ||
|
||
// Callback function is called each time the object detector finishes processing a frame. | ||
function gotDetections(results) { | ||
// Update detections array with the new results | ||
detections = results; | ||
|
||
for (let i = 0; i < detections.length; i += 1) { | ||
let detection = detections[i]; | ||
|
||
// Draw bounding box | ||
stroke(0, 255, 0); | ||
strokeWeight(4); | ||
noFill(); | ||
rect(detection.x, detection.y, detection.width, detection.height); | ||
|
||
// Draw label | ||
noStroke(); | ||
fill(255); | ||
textSize(24); | ||
text(detection.label, detection.x + 10, detection.y + 24); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!-- | ||
👋 Hello! This is an ml5.js example made and shared with ❤️. | ||
Learn more about the ml5.js project: https://ml5js.org/ | ||
ml5.js license and Code of Conduct: https://github.com/ml5js/ml5-next-gen/blob/main/LICENSE.md | ||
|
||
This example demonstrates object detection on a video through ml5.objectDetector. | ||
--> | ||
|
||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>ml5.js objectDetector Example - Video</title> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script> | ||
<script src="../../dist/ml5.js"></script> | ||
</head> | ||
<body> | ||
<main> | ||
</main> | ||
<script src="sketch.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* 👋 Hello! This is an ml5.js example made and shared with ❤️. | ||
* Learn more about the ml5.js project: https://ml5js.org | ||
* ml5.js license and Code of Conduct: https://github.com/ml5js/ml5-next-gen/blob/main/LICENSE.md | ||
* | ||
* This example demonstrates detecting objects in a video file through ml5.objectDetector. | ||
*/ | ||
|
||
let video; | ||
let detector; | ||
let detections = []; | ||
let canvasElement; | ||
|
||
function preload(){ | ||
detector = ml5.objectDetector("cocossd"); | ||
} | ||
|
||
function setup() { | ||
// Create canvas with initial size - will be resized later | ||
canvasElement = createCanvas(640, 480); | ||
canvasElement.position(0, 0); | ||
|
||
// Create video element (paused by default) | ||
video = createVideo('test.mov'); | ||
video.position(0, 0); | ||
video.volume(0); | ||
video.showControls(); | ||
|
||
// Make canvas transparent and on top | ||
canvasElement.style('z-index', '1'); | ||
canvasElement.style('pointer-events', 'none'); // Allow clicks to pass through to video | ||
video.style('z-index', '-1'); | ||
|
||
// Set up video event listeners | ||
video.elt.addEventListener('loadedmetadata', () => { | ||
console.log('Video metadata loaded'); | ||
|
||
// Resize canvas to match video size | ||
resizeCanvas(video.elt.videoWidth, video.elt.videoHeight); | ||
}); | ||
|
||
video.elt.addEventListener('play', () => { | ||
console.log('Video started playing'); | ||
|
||
// Start detection | ||
detector.detectStart(video, gotDetections); | ||
}); | ||
|
||
video.elt.addEventListener('pause', () => { | ||
console.log('Video paused'); | ||
|
||
// Stop detection when video is paused | ||
detector.detectStop(); | ||
}); | ||
|
||
video.elt.addEventListener('ended', () => { | ||
console.log('Video ended'); | ||
|
||
// Stop detection when video ends | ||
detector.detectStop(); | ||
}); | ||
} | ||
|
||
function draw(){ | ||
// Clear the canvas (this acts as the transparent overlay) | ||
clear(); | ||
|
||
for (let i = 0; i < detections.length; i += 1) { | ||
let detection = detections[i]; | ||
|
||
// Draw bounding box | ||
stroke(0, 255, 0); | ||
strokeWeight(4); | ||
noFill(); | ||
rect(detection.x, detection.y, detection.width, detection.height); | ||
|
||
// Draw label | ||
noStroke(); | ||
fill(255); | ||
textSize(24); | ||
text(detection.label, detection.x + 10, detection.y + 24); | ||
} | ||
} | ||
|
||
// Callback function is called each time the object detector finishes processing a frame. | ||
function gotDetections(results) { | ||
// Update detections array with the new results | ||
detections = results; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!-- | ||
👋 Hello! This is an ml5.js example made and shared with ❤️. | ||
Learn more about the ml5.js project: https://ml5js.org/ | ||
ml5.js license and Code of Conduct: https://github.com/ml5js/ml5-next-gen/blob/main/LICENSE.md | ||
|
||
This example demonstrates object detection on live video through ml5.objectDetector. | ||
--> | ||
|
||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>ml5.js objectDetector Example - Webcam</title> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script> | ||
<script src="../../dist/ml5.js"></script> | ||
</head> | ||
<body> | ||
<main> | ||
</main> | ||
<script src="sketch.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* 👋 Hello! This is an ml5.js example made and shared with ❤️. | ||
* Learn more about the ml5.js project: https://ml5js.org/ | ||
* ml5.js license and Code of Conduct: https://github.com/ml5js/ml5-next-gen/blob/main/LICENSE.md | ||
* | ||
* This example demonstrates detecting objects in a live video through ml5.imageClassifier. | ||
*/ | ||
|
||
let video; | ||
let detector; | ||
let detections = []; | ||
|
||
function preload(){ | ||
detector = ml5.objectDetector("cocossd"); | ||
} | ||
|
||
function setup() { | ||
createCanvas(640, 480); | ||
|
||
// Using webcam feed as video input, hiding html element to avoid duplicate with canvas | ||
video = createCapture(VIDEO); | ||
video.size(width, height); | ||
Comment on lines
+18
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I just tested and confirm that the #264 applies here too! If I change the webcam to |
||
video.hide(); | ||
|
||
detector.detectStart(video, gotDetections); | ||
} | ||
|
||
// Callback function is called each time the object detector finishes processing a frame. | ||
function gotDetections(results) { | ||
// Update detections array with the new results | ||
detections = results; | ||
} | ||
|
||
function draw() { | ||
// Draw the current video frame onto the canvas. | ||
image(video, 0, 0); | ||
|
||
for (let i = 0; i < detections.length; i += 1) { | ||
let detection = detections[i]; | ||
|
||
// Draw bounding box | ||
stroke(0, 255, 0); | ||
strokeWeight(4); | ||
noFill(); | ||
rect(detection.x, detection.y, detection.width, detection.height); | ||
|
||
// Draw label | ||
noStroke(); | ||
fill(255); | ||
textSize(24); | ||
text(detection.label, detection.x + 10, detection.y + 24); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright (c) 2019 ml5 | ||
// | ||
// This software is released under the MIT License. | ||
// https://opensource.org/licenses/MIT | ||
|
||
/* | ||
COCO-SSD Object detection model | ||
Wraps the coco-ssd model in tfjs to be used in ml5 | ||
*/ | ||
import * as tf from "@tensorflow/tfjs"; | ||
import * as cocoSsd from "@tensorflow-models/coco-ssd"; | ||
import { mediaReady } from "../utils/imageUtilities"; | ||
|
||
const DEFAULTS = { | ||
base: "lite_mobilenet_v2", | ||
modelUrl: undefined, | ||
}; | ||
|
||
export class CocoSsd { | ||
constructor(options = {}) { | ||
this.model = null; | ||
this.config = { | ||
base: options.base || DEFAULTS.base, | ||
modelUrl: options.modelUrl || DEFAULTS.modelUrl, | ||
}; | ||
} | ||
|
||
async load() { | ||
await tf.setBackend("webgl"); // this line resolves warning : performance is poor on webgpu backend | ||
await tf.ready(); | ||
|
||
this.model = await cocoSsd.load(this.config); | ||
return this; | ||
} | ||
|
||
/** | ||
* Detect objects that are in the image/video/canvas | ||
* @param {HTMLVideoElement|HTMLImageElement|HTMLCanvasElement|ImageData} imgToPredict - Subject of the detection. | ||
* @returns {Array} Array of detection detections | ||
*/ | ||
async detect(imgToPredict) { | ||
mediaReady(imgToPredict, true); | ||
|
||
await tf.nextFrame(); | ||
|
||
const detections = await this.model.detect(imgToPredict); | ||
const formattedDetections = detections.map(prediction => { | ||
return { | ||
label: prediction.class, | ||
confidence: prediction.score, | ||
x: prediction.bbox[0], | ||
y: prediction.bbox[1], | ||
width: prediction.bbox[2], | ||
height: prediction.bbox[3], | ||
normalized: { | ||
x: prediction.bbox[0] / imgToPredict.width, | ||
y: prediction.bbox[1] / imgToPredict.height, | ||
width: prediction.bbox[2] / imgToPredict.width, | ||
height: prediction.bbox[3] / imgToPredict.height, | ||
}, | ||
}; | ||
}); | ||
|
||
return formattedDetections; | ||
} | ||
} | ||
|
||
export async function load(modelConfig = {}) { | ||
const cocoSsdInstance = new CocoSsd(modelConfig); | ||
await cocoSsdInstance.load(); | ||
return cocoSsdInstance; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I woudl avoid all this extra code if you can! You can treat the video just like the webcam, have it auto-start and loop. Here's an example from BlazePose you can use as a model:
https://editor.p5js.org/codingtrain/sketches/ftALPDieT
But yours can be simpler b/c you can hide the video element and draw it on the canvas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh okay! I will forget about showControls and try video.hide + video.loop(). Thank you 🙏