🎯 Exemplos recomendados
Balanced sample collections from various categories for you to explore
Exemplos ML5.js
Exemplos de aprendizado de máquina ML5.js para programação criativa, classificação de imagem, detecção de pose e redes neurais
💻 Classificação de Imagem javascript
🟡 intermediate
⭐⭐⭐
Classificar imagens usando o modelo pré-treinado MobileNet
⏱️ 20 min
🏷️ ml5js, image classification, mobilenet
Prerequisites:
Basic JavaScript, HTML5 Canvas
// Image Classification with ML5.js
// Import ML5.js
// In browser: <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
// HTML: <div id="videoContainer"></div><canvas id="canvas"></canvas>
let model;
let video;
// 1. Setup video capture
function setupVideo() {
video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
}
// 2. Load MobileNet model
async function loadModel() {
console.log('Loading MobileNet model...');
model = await ml5.imageClassifier('MobileNet', video, () => {
console.log('Model loaded successfully!');
classifyVideo();
});
}
// 3. Classify video frame
function classifyVideo() {
model.classify((error, results) => {
if (error) {
console.error(error);
return;
}
// Display results
displayResults(results);
// Continue classifying
classifyVideo();
});
}
// 4. Display classification results
function displayResults(results) {
console.log('Classification Results:');
// Clear previous results
const resultsDiv = document.getElementById('results');
if (resultsDiv) {
resultsDiv.innerHTML = '';
results.forEach((result, index) => {
const confidence = (result.confidence * 100).toFixed(2);
const label = result.label;
console.log(`${index + 1}. ${label}: ${confidence}%`);
// Create HTML element for each result
const resultElement = document.createElement('div');
resultElement.className = 'classification-result';
resultElement.innerHTML = `
<span class="label">${label}</span>
<div class="confidence-bar">
<div class="confidence-fill" style="width: ${confidence}%"></div>
</div>
<span class="confidence-text">${confidence}%</span>
`;
resultsDiv.appendChild(resultElement);
});
}
}
// 5. Alternative: Classify still image
function classifyImage(imageElement) {
model.classify(imageElement, (error, results) => {
if (error) {
console.error(error);
return;
}
console.log('Image Classification Results:');
results.forEach((result, index) => {
const confidence = (result.confidence * 100).toFixed(2);
console.log(`${index + 1}. ${result.label}: ${confidence}%`);
});
});
}
// 6. Classify from canvas
function classifyCanvas() {
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
// Draw video frame to canvas
context.drawImage(video, 0, 0, canvas.width, canvas.height);
// Classify canvas content
model.classify(canvas, (error, results) => {
if (error) {
console.error(error);
return;
}
console.log('Canvas Classification Results:', results);
});
}
// 7. Custom classification with confidence threshold
function classifyWithThreshold(threshold = 0.5) {
model.classify((error, results) => {
if (error) {
console.error(error);
return;
}
const highConfidenceResults = results.filter(result => result.confidence > threshold);
if (highConfidenceResults.length > 0) {
console.log('High Confidence Results:');
highConfidenceResults.forEach(result => {
console.log(`${result.label}: ${(result.confidence * 100).toFixed(2)}%`);
});
} else {
console.log('No results above confidence threshold');
}
});
}
// 8. Batch classification of multiple images
async function batchClassify(imageUrls) {
console.log('Starting batch classification...');
for (let i = 0; i < imageUrls.length; i++) {
const imageUrl = imageUrls[i];
console.log(`\nClassifying image ${i + 1}: ${imageUrl}`);
try {
const results = await new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
model.classify(img, (error, results) => {
if (error) reject(error);
else resolve(results);
});
};
img.onerror = reject;
img.src = imageUrl;
});
console.log('Results:');
results.forEach((result, index) => {
console.log(` ${index + 1}. ${result.label}: ${(result.confidence * 100).toFixed(2)}%`);
});
} catch (error) {
console.error(`Error classifying image ${i + 1}:`, error);
}
}
}
// 9. Classification with custom visualization
function setupVisualization() {
function draw() {
// Draw video
image(video, 0, 0, width, height);
// Get current classification
if (model && frameCount % 30 === 0) { // Classify every 30 frames
model.classify((error, results) => {
if (!error && results.length > 0) {
// Draw top result on screen
fill(255, 255, 255);
stroke(0);
strokeWeight(3);
textSize(24);
textAlign(LEFT, TOP);
const topResult = results[0];
const confidence = (topResult.confidence * 100).toFixed(1);
const text = `${topResult.label} (${confidence}%)`;
text(text, 10, 10);
}
});
}
}
}
// 10. Export classification data
function exportClassificationData() {
model.classify((error, results) => {
if (error) {
console.error(error);
return;
}
const data = {
timestamp: new Date().toISOString(),
results: results.map(result => ({
label: result.label,
confidence: result.confidence,
confidencePercent: (result.confidence * 100).toFixed(2)
}))
};
// Download as JSON
const dataStr = JSON.stringify(data, null, 2);
const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
const exportFileDefaultName = `classification_${Date.now()}.json`;
const linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', exportFileDefaultName);
linkElement.click();
console.log('Classification data exported');
});
}
// Complete initialization
async function initializeImageClassification() {
console.log('Initializing Image Classification...');
// Create HTML elements if they don't exist
if (!document.getElementById('results')) {
const resultsDiv = document.createElement('div');
resultsDiv.id = 'results';
resultsDiv.style.position = 'absolute';
resultsDiv.style.top = '10px';
resultsDiv.style.right = '10px';
resultsDiv.style.background = 'rgba(0, 0, 0, 0.7)';
resultsDiv.style.color = 'white';
resultsDiv.style.padding = '10px';
resultsDiv.style.borderRadius = '5px';
resultsDiv.style.fontFamily = 'Arial, sans-serif';
resultsDiv.style.minWidth = '250px';
document.body.appendChild(resultsDiv);
// Add styles for confidence bars
const style = document.createElement('style');
style.textContent = `
.classification-result {
margin: 5px 0;
display: flex;
align-items: center;
}
.label {
flex: 1;
margin-right: 10px;
}
.confidence-bar {
flex: 2;
height: 20px;
background: #333;
border-radius: 10px;
overflow: hidden;
margin-right: 10px;
}
.confidence-fill {
height: 100%;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
transition: width 0.3s ease;
}
.confidence-text {
min-width: 45px;
text-align: right;
}
`;
document.head.appendChild(style);
}
setupVideo();
await loadModel();
}
// Example usage
// initializeImageClassification();
// For static image classification:
// const img = document.getElementById('myImage');
// classifyImage(img);
// For batch classification:
// const imageUrls = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
// batchClassify(imageUrls);
console.log('ML5.js Image Classification module loaded');
console.log('Call initializeImageClassification() to start');
💻 Detecção de Pose javascript
🟡 intermediate
⭐⭐⭐
Detectar poses do corpo humano usando o modelo PoseNet
⏱️ 25 min
🏷️ ml5js, pose detection, posenet, body tracking
Prerequisites:
Basic JavaScript, p5.js
// Pose Detection with ML5.js
// Import ML5.js
// In browser: <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
// Requires p5.js for visualizations
let poseNet;
let poses = [];
let video;
let skeletons = [];
// 1. Setup video capture
function setupPoseDetection() {
video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
}
// 2. Load PoseNet model
async function loadPoseNet() {
console.log('Loading PoseNet model...');
const options = {
architecture: 'MobileNetV1',
imageScaleFactor: 0.3,
outputStride: 16,
flipHorizontal: false,
minConfidence: 0.5,
maxPoseDetections: 5,
scoreThreshold: 0.5,
nmsRadius: 20,
detectionType: 'single',
multiplier: 0.75
};
poseNet = ml5.poseNet(video, options, () => {
console.log('PoseNet model loaded!');
});
// Listen for new poses
poseNet.on('pose', (results) => {
poses = results;
});
}
// 3. Draw poses
function drawPoses() {
// Draw video
image(video, 0, 0, width, height);
// Loop through all the poses detected
for (let i = 0; i < poses.length; i++) {
let pose = poses[i].pose;
// Draw skeleton
drawSkeleton(poses[i].skeleton);
// Draw keypoints
for (let j = 0; j < pose.keypoints.length; j++) {
let keypoint = pose.keypoints[j];
// Only draw a circle if the keypoint's confidence is high enough
if (keypoint.score > 0.2) {
fill(255, 0, 0);
noStroke();
ellipse(keypoint.position.x, keypoint.position.y, 20, 20);
// Draw keypoint label
fill(255);
textAlign(CENTER, CENTER);
textSize(10);
text(getKeypointName(j), keypoint.position.x, keypoint.position.y - 15);
}
}
}
}
// 4. Draw skeleton connections
function drawSkeleton(skeleton) {
stroke(0, 255, 0);
strokeWeight(5);
for (let i = 0; i < skeleton.length; i++) {
let partA = skeleton[i][0];
let partB = skeleton[i][1];
line(partA.position.x, partA.position.y, partB.position.x, partB.position.y);
}
}
// 5. Get keypoint name by index
function getKeypointName(index) {
const keypointNames = [
'nose', 'leftEye', 'rightEye', 'leftEar', 'rightEar',
'leftShoulder', 'rightShoulder', 'leftElbow', 'rightElbow',
'leftWrist', 'rightWrist', 'leftHip', 'rightHip',
'leftKnee', 'rightKnee', 'leftAnkle', 'rightAnkle'
];
return keypointNames[index] || 'unknown';
}
// 6. Calculate angle between three points
function calculateAngle(a, b, c) {
let radians = Math.atan2(c.y - b.y, c.x - b.x) - Math.atan2(a.y - b.y, a.x - b.x);
let angle = Math.abs(radians * 180.0 / Math.PI);
if (angle > 180.0) {
angle = 360 - angle;
}
return angle;
}
// 7. Get specific body angles
function getBodyAngles(pose) {
const keypoints = pose.keypoints;
// Find keypoint positions
const getKeyPoint = (name) => {
const names = ['nose', 'leftEye', 'rightEye', 'leftEar', 'rightEar',
'leftShoulder', 'rightShoulder', 'leftElbow', 'rightElbow',
'leftWrist', 'rightWrist', 'leftHip', 'rightHip',
'leftKnee', 'rightKnee', 'leftAnkle', 'rightAnkle'];
const index = names.indexOf(name);
return index >= 0 && keypoints[index].score > 0.2 ? keypoints[index].position : null;
};
const leftShoulder = getKeyPoint('leftShoulder');
const leftElbow = getKeyPoint('leftElbow');
const leftWrist = getKeyPoint('leftWrist');
const rightShoulder = getKeyPoint('rightShoulder');
const rightElbow = getKeyPoint('rightElbow');
const rightWrist = getKeyPoint('rightWrist');
const leftHip = getKeyPoint('leftHip');
const rightHip = getKeyPoint('rightHip');
const leftKnee = getKeyPoint('leftKnee');
const rightKnee = getKeyPoint('rightKnee');
const angles = {};
// Calculate arm angles
if (leftShoulder && leftElbow && leftWrist) {
angles.leftArm = calculateAngle(leftShoulder, leftElbow, leftWrist);
}
if (rightShoulder && rightElbow && rightWrist) {
angles.rightArm = calculateAngle(rightShoulder, rightElbow, rightWrist);
}
// Calculate leg angles
if (leftHip && leftKnee && leftWrist) {
angles.leftLeg = calculateAngle(leftHip, leftKnee, leftWrist);
}
if (rightHip && rightKnee && rightWrist) {
angles.rightLeg = calculateAngle(rightHip, rightKnee, rightWrist);
}
return angles;
}
// 8. Detect specific poses or gestures
function detectPose(pose) {
const angles = getBodyAngles(pose);
const keypoints = pose.keypoints;
// Get keypoint positions
const leftShoulder = keypoints.find(kp => kp.part === 'leftShoulder');
const rightShoulder = keypoints.find(kp => kp.part === 'rightShoulder');
const leftWrist = keypoints.find(kp => kp.part === 'leftWrist');
const rightWrist = keypoints.find(kp => kp.part === 'rightWrist');
const detectedPoses = [];
// Detect "T-pose" (arms horizontal)
if (leftShoulder && rightShoulder && leftWrist && rightWrist) {
const shoulderY = (leftShoulder.position.y + rightShoulder.position.y) / 2;
const wristY = (leftWrist.position.y + rightWrist.position.y) / 2;
if (Math.abs(shoulderY - wristY) < 50) {
detectedPoses.push('T-Pose');
}
}
// Detect "hands up"
if (leftShoulder && leftWrist && rightShoulder && rightWrist) {
if (leftWrist.position.y < leftShoulder.position.y &&
rightWrist.position.y < rightShoulder.position.y) {
detectedPoses.push('Hands Up');
}
}
// Detect "arms crossed" (approximate)
if (leftWrist && rightWrist) {
if (leftWrist.position.x > rightWrist.position.x) {
detectedPoses.push('Arms Crossed');
}
}
// Check specific angles for exercise detection
if (angles.leftArm !== undefined) {
if (angles.leftArm > 160) {
detectedPoses.push('Left Arm Extended');
}
if (angles.leftArm < 90 && angles.leftArm > 70) {
detectedPoses.push('Left Arm 90 Degrees');
}
}
return detectedPoses;
}
// 9. Track pose over time
class PoseTracker {
constructor() {
this.poseHistory = [];
this.maxHistory = 30; // Track last 30 frames
}
update(poses) {
if (poses && poses.length > 0) {
const pose = poses[0];
const poseData = {
timestamp: Date.now(),
keypoints: pose.keypoints,
angles: getBodyAngles(pose),
detectedPoses: detectPose(pose)
};
this.poseHistory.push(poseData);
if (this.poseHistory.length > this.maxHistory) {
this.poseHistory.shift();
}
}
}
getCurrentPose() {
return this.poseHistory.length > 0 ? this.poseHistory[this.poseHistory.length - 1] : null;
}
getRecentPoses(frames = 10) {
return this.poseHistory.slice(-frames);
}
detectExercise() {
const recentPoses = this.getRecentPoses(20);
if (recentPoses.length < 10) return null;
// Simple exercise detection: arm curl
const armAngles = recentPoses.map(p => p.angles.leftArm).filter(a => a !== undefined);
if (armAngles.length > 0) {
const minAngle = Math.min(...armAngles);
const maxAngle = Math.max(...armAngles);
if (maxAngle - minAngle > 90) {
return 'Arm Curl';
}
}
return null;
}
}
// 10. Pose visualization with exercise tracking
const poseTracker = new PoseTracker();
function drawPoseVisualization() {
// Draw video and poses
drawPoses();
// Update pose tracker
poseTracker.update(poses);
// Display detected poses
if (poses.length > 0) {
const currentPose = poseTracker.getCurrentPose();
if (currentPose && currentPose.detectedPoses.length > 0) {
fill(255, 255, 0);
noStroke();
textSize(24);
textAlign(LEFT, TOP);
text(`Detected: ${currentPose.detectedPoses.join(', ')}`, 10, 30);
}
// Display exercise
const exercise = poseTracker.detectExercise();
if (exercise) {
fill(0, 255, 0);
textSize(32);
text(`Exercise: ${exercise}`, 10, 70);
}
// Display body angles
if (currentPose && currentPose.angles) {
fill(255);
textSize(16);
let y = 110;
if (currentPose.angles.leftArm !== undefined) {
text(`Left Arm: ${currentPose.angles.leftArm.toFixed(1)}°`, 10, y);
y += 20;
}
if (currentPose.angles.rightArm !== undefined) {
text(`Right Arm: ${currentPose.angles.rightArm.toFixed(1)}°`, 10, y);
y += 20;
}
}
}
}
// Initialize pose detection
async function initializePoseDetection() {
console.log('Initializing Pose Detection...');
setupPoseDetection();
await loadPoseNet();
}
// Export functions
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
initializePoseDetection,
PoseTracker,
calculateAngle,
getBodyAngles,
detectPose
};
}
console.log('ML5.js Pose Detection module loaded');
console.log('Call initializePoseDetection() to start');
// Example p5.js sketch structure:
/*
function setup() {
createCanvas(640, 480);
initializePoseDetection();
}
function draw() {
drawPoseVisualization();
}
*/
💻 Treinamento de Rede Neural javascript
🔴 complex
⭐⭐⭐⭐
Criar e treinar redes neurais personalizadas para várias tarefas
⏱️ 30 min
🏷️ ml5js, neural network, training, deep learning
Prerequisites:
Advanced JavaScript, Neural network basics
// Neural Network Training with ML5.js
// Import ML5.js
// In browser: <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
let nn;
let trainingData = [];
let isTraining = false;
// 1. Create a neural network for regression
function createRegressionNetwork() {
console.log('Creating regression neural network...');
const options = {
inputs: 1,
outputs: 1,
task: 'regression',
debug: true,
learningRate: 0.05
};
nn = ml5.neuralNetwork(options);
// Add training data (simple y = 2x + 1 relationship)
for (let i = 0; i < 100; i++) {
const x = Math.random() * 10;
const y = 2 * x + 1 + (Math.random() - 0.5) * 0.5; // Add some noise
trainingData.push({ input: [x], output: [y] });
}
nn.addData(trainingData);
return nn;
}
// 2. Create a neural network for classification
function createClassificationNetwork() {
console.log('Creating classification neural network...');
const options = {
inputs: 2,
outputs: 3,
task: 'classification',
debug: true,
learningRate: 0.1
};
nn = ml5.neuralNetwork(options);
// Generate classification data (3 clusters)
for (let i = 0; i < 150; i++) {
const cluster = Math.floor(Math.random() * 3);
let x, y, output;
switch(cluster) {
case 0:
x = Math.random() * 3 + 1;
y = Math.random() * 3 + 1;
output = [1, 0, 0]; // Class 0
break;
case 1:
x = Math.random() * 3 + 5;
y = Math.random() * 3 + 5;
output = [0, 1, 0]; // Class 1
break;
case 2:
x = Math.random() * 3 + 3;
y = Math.random() * 3 + 7;
output = [0, 0, 1]; // Class 2
break;
}
trainingData.push({ input: [x, y], output: output });
}
nn.addData(trainingData);
return nn;
}
// 3. Train the neural network
function trainNetwork(callback) {
console.log('Starting training...');
isTraining = true;
const trainingOptions = {
epochs: 50,
batchSize: 16,
validationSplit: 0.1,
shuffle: true
};
nn.train(trainingOptions, (epoch, loss) => {
console.log(`Epoch ${epoch}: Loss = ${loss.toFixed(4)}`);
}, () => {
console.log('Training complete!');
isTraining = false;
if (callback) callback();
});
}
// 4. Make predictions
function predict(input) {
if (isTraining) {
console.log('Network is still training...');
return null;
}
nn.classify(input, (error, results) => {
if (error) {
console.error(error);
return;
}
console.log('Prediction results:');
results.forEach((result, i) => {
console.log(`Class ${i}: ${result.label} (confidence: ${(result.confidence * 100).toFixed(2)}%)`);
});
});
}
// 5. Save and load model
function saveModel() {
nn.save('my-model');
console.log('Model saved!');
}
function loadModel(path, callback) {
const options = {
inputs: 2,
outputs: 3,
task: 'classification'
};
nn = ml5.neuralNetwork(options);
nn.load(path, () => {
console.log('Model loaded successfully!');
if (callback) callback();
});
}
// 6. Custom data generator
function generateCustomData() {
// Generate data for XOR problem
const xorData = [
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [0] }
];
// Add noise and generate more samples
for (let i = 0; i < 100; i++) {
xorData.forEach(sample => {
const noisyInput = sample.input.map(x => x + (Math.random() - 0.5) * 0.1);
const noisyOutput = sample.output.map(y => y + (Math.random() - 0.5) * 0.1);
xorData.push({ input: noisyInput, output: noisyOutput });
});
}
return xorData;
}
// 7. Advanced neural network for image classification
function createImageClassificationNetwork() {
console.log('Creating image classification network...');
const options = {
inputs: 64, // 8x8 grayscale images
outputs: 2, // 2 classes
task: 'classification',
debug: true,
learningRate: 0.01,
hiddenUnits: [32, 16] // Two hidden layers
};
nn = ml5.neuralNetwork(options);
// Generate simple image data
for (let i = 0; i < 200; i++) {
const isClass1 = Math.random() > 0.5;
const imageData = generateImagePattern(isClass1);
const output = isClass1 ? [1, 0] : [0, 1];
nn.addData({ input: imageData, output: output });
}
return nn;
}
// 8. Generate image patterns
function generateImagePattern(isVertical) {
const size = 8;
const imageData = [];
for (let i = 0; i < size * size; i++) {
const x = i % size;
const y = Math.floor(i / size);
let value = 0;
if (isVertical) {
// Vertical line pattern
value = (x > 2 && x < 5) ? 1 : 0;
} else {
// Horizontal line pattern
value = (y > 2 && y < 5) ? 1 : 0;
}
// Add some noise
value += (Math.random() - 0.5) * 0.2;
imageData.push(Math.max(0, Math.min(1, value)));
}
return imageData;
}
// 9. Real-time data collection
class DataCollector {
constructor() {
this.data = [];
this.currentInput = [];
this.isCollecting = false;
this.currentLabel = 0;
}
start(label) {
this.currentLabel = label;
this.isCollecting = true;
this.currentInput = [];
console.log(`Collecting data for label ${label}...`);
}
addDataPoint(point) {
if (this.isCollecting) {
this.currentInput.push(point);
}
}
stop() {
if (this.isCollecting && this.currentInput.length > 0) {
this.data.push({
input: this.currentInput,
output: [this.currentLabel]
});
console.log(`Added ${this.currentInput.length} data points for label ${this.currentLabel}`);
}
this.isCollecting = false;
this.currentInput = [];
}
getData() {
return this.data;
}
clear() {
this.data = [];
console.log('Data cleared');
}
}
// 10. Gesture recognition network
class GestureRecognizer {
constructor() {
this.nn = null;
this.dataCollector = new DataCollector();
this.gestures = ['wave', 'swipe_left', 'swipe_right', 'circle'];
this.currentGesture = 0;
this.isTraining = false;
}
initialize() {
const options = {
inputs: 30, // 10 frames x 3 coordinates (x, y, z)
outputs: this.gestures.length,
task: 'classification',
debug: true
};
this.nn = ml5.neuralNetwork(options);
this.loadTrainingData();
}
startCollecting(gestureIndex) {
this.currentGesture = gestureIndex;
this.dataCollector.start(gestureIndex);
console.log(`Collecting gesture: ${this.gestures[gestureIndex]}`);
}
addHandPosition(x, y, z = 0) {
this.dataCollector.addDataPoint([x, y, z]);
}
stopCollecting() {
this.dataCollector.stop();
const newData = this.dataCollector.getData();
newData.forEach(sample => {
this.nn.addData(sample);
});
}
train() {
if (this.isTraining) return;
this.isTraining = true;
this.nn.normalizeData();
const options = {
epochs: 100,
batchSize: 16
};
this.nn.train(options, (epoch, loss) => {
console.log(`Training - Epoch ${epoch}: Loss = ${loss.toFixed(4)}`);
}, () => {
this.isTraining = false;
console.log('Gesture model trained!');
});
}
recognize(points) {
if (this.isTraining) return null;
this.nn.classify(points, (error, results) => {
if (error) {
console.error(error);
return;
}
const topResult = results[0];
const confidence = (topResult.confidence * 100).toFixed(2);
console.log(`Gesture: ${topResult.label} (${confidence}% confidence)`);
return topResult;
});
}
loadTrainingData() {
// Load pre-existing training data if available
// This would typically load from a file or API
console.log('Loading existing training data...');
}
saveModel() {
this.nn.save('gesture-model');
console.log('Gesture model saved!');
}
}
// Initialize and train example
async function runNeuralNetworkExample() {
console.log('=== Neural Network Example ===');
// Create a classification network
const network = createClassificationNetwork();
// Train the network
trainNetwork(() => {
console.log('Making predictions...');
// Test predictions
predict([2, 2]); // Should be class 0
predict([6, 6]); // Should be class 1
predict([4, 8]); // Should be class 2
});
}
// Initialize gesture recognizer
const gestureRecognizer = new GestureRecognizer();
// Export classes and functions
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
createRegressionNetwork,
createClassificationNetwork,
DataCollector,
GestureRecognizer,
runNeuralNetworkExample
};
}
console.log('ML5.js Neural Network module loaded');
console.log('Available functions:');
console.log('- createRegressionNetwork()');
console.log('- createClassificationNetwork()');
console.log('- runNeuralNetworkExample()');
console.log('- GestureRecognizer class for gesture recognition');
💻 Classificação de Som javascript
🔴 complex
⭐⭐⭐⭐
Classificar sons e áudio usando aprendizado de máquina
⏱️ 25 min
🏷️ ml5js, sound classification, audio, speech
Prerequisites:
Advanced JavaScript, Web Audio API
// Sound Classification with ML5.js
// Import ML5.js
// In browser: <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
// Also requires p5.js and p5.sound library
let soundClassifier;
let audioContext;
let mic;
let modelReady = false;
// 1. Setup audio context and microphone
function setupAudio() {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
// Create audio input
mic = new p5.AudioIn();
mic.start();
console.log('Audio setup complete');
}
// 2. Load pre-trained sound classification model
async function loadSoundClassifier() {
console.log('Loading sound classifier...');
// Options for the classifier
const options = {
probabilityThreshold: 0.75,
overlapFactor: 0.5
};
soundClassifier = ml5.soundClassifier('SpeechCommands18w', options, () => {
console.log('Sound classifier loaded!');
modelReady = true;
// Start classifying
startClassification();
});
}
// 3. Start continuous classification
function startClassification() {
if (!modelReady) {
console.log('Model not ready yet...');
return;
}
// Get audio classification results
soundClassifier.classify(gotResult);
}
// 4. Handle classification results
function gotResult(error, results) {
if (error) {
console.error(error);
return;
}
// Display results
if (results && results.length > 0) {
console.log('Sound Classification Results:');
results.forEach((result, i) => {
console.log(`${i + 1}. ${result.label}: ${(result.confidence * 100).toFixed(2)}%`);
});
// Visual feedback
displaySoundResults(results);
// Trigger actions based on sound
handleSoundCommand(results[0]);
}
}
// 5. Display sound classification results
function displaySoundResults(results) {
const resultsDiv = document.getElementById('soundResults');
if (resultsDiv) {
resultsDiv.innerHTML = '';
results.forEach(result => {
const confidence = (result.confidence * 100).toFixed(1);
const resultElement = document.createElement('div');
resultElement.style.margin = '5px 0';
resultElement.innerHTML = `
<span style="display: inline-block; width: 150px;">${result.label}:</span>
<div style="display: inline-block; width: 200px; height: 20px; background: #ddd; border-radius: 10px; overflow: hidden; position: relative;">
<div style="width: ${confidence}%; height: 100%; background: linear-gradient(90deg, #4ecdc4, #44a3a0);"></div>
</div>
<span style="margin-left: 10px;">${confidence}%</span>
`;
resultsDiv.appendChild(resultElement);
});
}
}
// 6. Handle voice commands
function handleSoundCommand(result) {
const command = result.label.toLowerCase();
const confidence = result.confidence;
if (confidence < 0.7) return; // Only act on high confidence
console.log(`Detected command: ${command} (${(confidence * 100).toFixed(1)}%)`);
switch(command) {
case 'yes':
console.log('✓ Yes detected');
document.body.style.backgroundColor = '#90EE90';
break;
case 'no':
console.log('✗ No detected');
document.body.style.backgroundColor = '#FFB6C1';
break;
case 'up':
console.log('↑ Up command');
window.scrollBy(0, -100);
break;
case 'down':
console.log('↓ Down command');
window.scrollBy(0, 100);
break;
case 'left':
console.log('← Left command');
window.scrollBy(-100, 0);
break;
case 'right':
console.log('→ Right command');
window.scrollBy(100, 0);
break;
case 'stop':
console.log('⏹ Stop command');
// Pause any ongoing action
break;
case 'go':
console.log('▶ Go command');
// Resume or start action
break;
case 'on':
console.log('💡 On command');
document.body.style.filter = 'brightness(1.2)';
break;
case 'off':
console.log('🌙 Off command');
document.body.style.filter = 'brightness(0.8)';
break;
case 'zero':
console.log('0 Reset command');
document.body.style.backgroundColor = '';
document.body.style.filter = '';
break;
}
}
// 7. Custom sound classification with training data
class CustomSoundClassifier {
constructor() {
this.featureExtractor = ml5.featureExtractor('MobileNet');
this.classifier = this.featureExtractor.classification();
this.audioBuffer = [];
this.isRecording = false;
this.isTraining = false;
this.labels = ['silence', 'clap', 'whistle', 'snap'];
}
async initialize() {
console.log('Initializing custom sound classifier...');
// Setup audio capture
this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.audioContext = new AudioContext();
this.source = this.audioContext.createMediaStreamSource(this.stream);
this.analyser = this.audioContext.createAnalyser();
this.source.connect(this.analyser);
this.analyser.fftSize = 2048;
console.log('Custom classifier initialized');
}
startRecording(label) {
this.currentLabel = label;
this.isRecording = true;
this.audioBuffer = [];
console.log(`Recording for label: ${label}`);
this.captureAudioData();
}
captureAudioData() {
if (!this.isRecording) return;
const bufferLength = this.analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
this.analyser.getByteFrequencyData(dataArray);
// Convert to normalized features
const features = Array.from(dataArray).map(x => x / 255);
this.audioBuffer.push(...features);
requestAnimationFrame(() => this.captureAudioData());
}
stopRecording() {
this.isRecording = false;
console.log(`Stopped recording. Captured ${this.audioBuffer.length} features`);
// Add to training data
this.classifier.addExample(this.audioBuffer, this.currentLabel);
}
async train() {
if (this.isTraining) return;
this.isTraining = true;
console.log('Training custom sound classifier...');
const options = {
epochs: 50,
batchSize: 32
};
this.classifier.train(options, (epoch, loss) => {
console.log(`Training - Epoch ${epoch}: Loss = ${loss.toFixed(4)}`);
}, () => {
this.isTraining = false;
console.log('Training complete!');
this.startPrediction();
});
}
startPrediction() {
if (this.isTraining) return;
this.isPredicting = true;
this.predictContinuously();
}
predictContinuously() {
if (!this.isPredicting) return;
const bufferLength = this.analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
this.analyser.getByteFrequencyData(dataArray);
const features = Array.from(dataArray).map(x => x / 255);
this.classifier.classify(features, (error, results) => {
if (!error && results.length > 0) {
const topResult = results[0];
if (topResult.confidence > 0.7) {
console.log(`Detected: ${topResult.label} (${(topResult.confidence * 100).toFixed(1)}%)`);
this.handleCustomSound(topResult);
}
}
});
requestAnimationFrame(() => this.predictContinuously());
}
handleCustomSound(result) {
// Custom actions for different sounds
switch(result.label) {
case 'clap':
console.log('👏 Clap detected!');
document.body.style.animation = 'pulse 0.5s';
setTimeout(() => {
document.body.style.animation = '';
}, 500);
break;
case 'whistle':
console.log('🎵 Whistle detected!');
document.body.style.color = '#FF6B6B';
setTimeout(() => {
document.body.style.color = '';
}, 1000);
break;
case 'snap':
console.log('🤏 Snap detected!');
document.body.style.transform = 'scale(1.05)';
setTimeout(() => {
document.body.style.transform = '';
}, 200);
break;
}
}
saveModel() {
this.classifier.save('custom-sound-model');
console.log('Custom sound model saved!');
}
async loadModel(path) {
await this.classifier.load(path);
console.log('Custom sound model loaded!');
this.startPrediction();
}
}
// 8. Audio visualization
function visualizeAudio() {
if (!mic || !modelReady) return;
push();
translate(width/2, height/2);
// Get audio level
const level = mic.getLevel();
const diameter = map(level, 0, 1, 50, 300);
// Draw visual representation
noFill();
stroke(255, 100);
strokeWeight(2);
for (let i = 0; i < 10; i++) {
const offset = i * 10;
ellipse(0, 0, diameter + offset, diameter + offset);
}
// Center circle reacts to audio
fill(255, 150);
noStroke();
ellipse(0, 0, level * 200, level * 200);
pop();
}
// 9. Volume-based interaction
function volumeBasedControl() {
if (!mic || !modelReady) return;
const level = mic.getLevel();
const threshold = 0.1;
if (level > threshold) {
// Loud sound detected
console.log(`Loud sound detected: ${(level * 100).toFixed(1)}%`);
// Trigger action based on volume level
if (level > 0.3) {
// Very loud - dramatic action
document.body.style.transition = 'transform 0.1s';
document.body.style.transform = 'scale(1.1)';
} else if (level > 0.2) {
// Moderate - subtle action
document.body.style.transition = 'background-color 0.3s';
document.body.style.backgroundColor = '#E8F4FF';
}
} else {
// Reset to normal
document.body.style.transform = '';
document.body.style.backgroundColor = '';
}
}
// 10. Initialize everything
async function initializeSoundClassification() {
console.log('Initializing Sound Classification...');
// Create HTML elements for results
if (!document.getElementById('soundResults')) {
const resultsDiv = document.createElement('div');
resultsDiv.id = 'soundResults';
resultsDiv.style.position = 'fixed';
resultsDiv.style.top = '10px';
resultsDiv.style.right = '10px';
resultsDiv.style.background = 'rgba(0, 0, 0, 0.8)';
resultsDiv.style.color = 'white';
resultsDiv.style.padding = '15px';
resultsDiv.style.borderRadius = '5px';
resultsDiv.style.fontFamily = 'monospace';
resultsDiv.style.minWidth = '300px';
document.body.appendChild(resultsDiv);
// Add title
const title = document.createElement('h3');
title.textContent = 'Sound Classification';
title.style.margin = '0 0 10px 0';
title.style.fontSize = '16px';
resultsDiv.insertBefore(title, resultsDiv.firstChild);
}
// Add pulse animation for claps
const style = document.createElement('style');
style.textContent = `
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
`;
document.head.appendChild(style);
setupAudio();
await loadSoundClassifier();
}
// Create custom classifier instance
const customSoundClassifier = new CustomSoundClassifier();
// Export classes and functions
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
initializeSoundClassification,
CustomSoundClassifier,
customSoundClassifier
};
}
console.log('ML5.js Sound Classification module loaded');
console.log('Available functions:');
console.log('- initializeSoundClassification()');
console.log('- CustomSoundClassifier class for custom training');
// Usage examples:
/*
// Initialize sound classification
initializeSoundClassification();
// Train custom classifier
customSoundClassifier.initialize().then(() => {
customSoundClassifier.startRecording('clap');
// Record clap sound...
customSoundClassifier.stopRecording();
customSoundClassifier.startRecording('whistle');
// Record whistle...
customSoundClassifier.stopRecording();
// Train and start predicting
customSoundClassifier.train();
});
*/