64
loading...
This website collects cookies to deliver better user experience
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/[email protected]/dist/ml5.min.js"></script>
<title>Twilio Video Mask ||
No-Mask Training</title>
</head>
<body>
<h2>
Train model to detect mask-wearing: Are you wearing a mask?: <span id="result">N/A</span> (<span id="confidence">N/A</span>)
</h2>
<div id="room-controls">
<video id="video" autoplay muted="true" width="320"
height="240"></video>
</div>
<p>
<em>Add pics to train the model!</em>
</p>
<p>
<button id="noMaskButton">Add >= 20 no-mask images</button> - No-mask: <span id="numNoMaskImages">0</span> images
</p>
<p>
<button id="maskButton">Add >= 20 mask images</button> - Mask: <span id="numMaskImages">0</span> images
</p>
<p>
<button id="train">Train</button> <span id="loss"></span>
</p>
<p>
<button id="predict">See the model in action once training is done</button>
</p>
<p>
<button id = "save">Save model to Assets folder</button>
</p>
<p>
<a href="video.html"><button id="goToVideo">Go to video call to use the mask detection in</button></a>
</p>
<script src="//media.twiliocdn.com/sdk/js/video/releases/2.3.0/twilio-video.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
<script src="train.js"></script>
</body>
</html>
<body>
, it adds an h2
heading with the text "Are you wearing a mask?", a result
span displaying "yes" or "no" to answer that question, and a confidence
span showing the model's confidence level of "yes, there is a mask" or "no, there is not a mask."noMaskButton
and maskButton
will add new image data to the model while the train
button trains the model and the predict
button begins running the model on the video feed to predict if a mask is detected.const video = document.getElementById("video");
const resSpan = document.getElementById('result');
const conf = document.getElementById('confidence');
const saveModelButton = document.getElementById('save');
const noMaskButton = document.getElementById('noMaskButton');
const maskButton = document.getElementById('maskButton');
const amountOfLabel1Images = document.getElementById('numNoMaskImages');
const amountOfLabel2Images = document.getElementById('numMaskImages');
const predictButton = document.getElementById('predict');
const featureExtractor = ml5.featureExtractor('MobileNet');
const classifier = featureExtractor.classification(video);
let localStream, totalLoss;
navigator.mediaDevices.getUserMedia({video: true, audio: true})
.then(vid => {
video.srcObject = vid;
localStream = vid;
});
//buttons for when you need to build the model
//no mask
noMaskButton.onclick = () => {
classifier.addImage('no');
amountOfLabel1Images.innerText = Number(amountOfLabel1Images.innerText) + 1;
};
maskButton.onclick = () => { //mask
classifier.addImage('yes');
amountOfLabel2Images.innerText = Number(amountOfLabel2Images.innerText) + 1;
};
train.onclick = () => {
classifier.train((lossValue) => {
if (lossValue) {
totalLoss = lossValue;
loss.innerHTML = `Loss: ${totalLoss}`;
} else {
loss.innerHTML = `Done Training! Final Loss: ${totalLoss}`;
}
});
};
const resultsFunc = (err, res) => {
if (err) {
console.error(err);
} else if (res && res[0]) {
resSpan.innerText = res[0].label;
conf.innerText = res[0].confidence;
classifier.classify(resultsFunc); // recall the classify function again
//console.dir(classifier);
}
}
predictButton.onclick = () => {
classifier.classify(resultsFunc);
};
saveModelButton.onclick = () => {
featureExtractor.save();
};
featureExtractor
object from the MobileNet model. The code calls the classification()
method on the featureExtractor
object, setting the input source of the classifier
object as the video element. This means that whatever appears on the camera acts as the input to classifier.lossValue
in the loss
span. The lower that value is, the greater the accuracy. Eventually, it decreases closer and closer to zero and the training process is finished when lossValue
becomes null.yes
or no
label in addition to the confidence level of the classification to reflect how confident the model is in that label. The closer to the number is to 1, the more sure it is.classification()
method is called over and over in the background, so that model is constantly predicting if someone is wearing a mask or not.featureExtractor.save()
to save the model.h2
and some span
s to reflect the "no" and "yes" mask labels and confidence levels, and a button to detect mask-wearing.<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/[email protected]/dist/ml5.min.js"></script>
<title>Twilio Video Mask ||
No-Mask Demo</title>
</head>
<body>
<h2>
Are you wearing a mask?: <span id="result">N/A</span> (<span id="confidence">N/A</span>)
</h2>
<div id="room-controls">
<video id="video" autoplay muted="true" width="320"
height="240"></video>
<button id="button-join">Join Room</button>
<button id="button-leave" disabled>Leave Room</button>
</div>
<p>
<em>This model has already been fed and trained with images categorized into mask or no mask.</em>
</p>
<p>
<button id="predict">Detect!</button>
</p>
<script src="//media.twiliocdn.com/sdk/js/video/releases/2.3.0/twilio-video.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
<script src="index.js"></script>
</body>
</html>
const ROOM_NAME = 'mask';
. Then beneath the video
variable, add the following variables which you should recognize from train.js:const resSpan = document.getElementById('result');
const conf = document.getElementById('confidence');
const predictButton = document.getElementById('predict');
let classifier = null;
let featureExtractor = ml5.featureExtractor('MobileNet');
joinRoomButton.onclick = () => {
featureExtractor.load('model.json');
joinRoomButton
click handler that say:joinRoomButton.disabled = true;
leaveRoomButton.disabled = false;
classifier = featureExtractor.classification(video);
const resultsFunc = (err, res) => {
if (err) {
console.error(err);
}
else if (res && res[0]) {
resSpan.innerText = res[0].label;
conf.innerText = res[0].confidence;
classifier.classify(resultsFunc); // recall the classify function again
}
}
predictButton.onclick = () => {
classifier.classify(resultsFunc);
};