Skip to content

Commit 78b6ff9

Browse files
authored
feat: update object detection to support multiple labels (#34)
* feat: update object detection to support multiple labels and maintain backward compatibility * feat: enhance object detection with state management and new reporting functions * fix: update block text for detected object labels in Arduino object detection extension * feat: update socket URL handling and enhance detected object reporting * refactor: simplify socket URL determination by removing unnecessary function * refactor: remove unnecessary comments and secure option from socket.io configuration * refactor: remove getDetectedLabels and getAllDetectionStates methods to streamline object detection logic * refactor: clean up code formatting and improve readability in object detection methods * refactor: improve code readability and add _getDetectedLabels method for clarity * refactor: clean up code formatting and improve readability in object detection methods
1 parent 7c5284a commit 78b6ff9

File tree

1 file changed

+102
-18
lines changed
  • scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_object_detection

1 file changed

+102
-18
lines changed

scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_object_detection/index.js

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class ArduinoObjectDetection {
4242

4343
this._penSkinId = null;
4444

45-
this._isfaceDetected = false;
45+
/** @type {Object<string, boolean>} */
46+
this._detectionStates = this._initializeDetectionStates();
4647

4748
/** @type {number|null} */
4849
this._loopIntervalId = null;
@@ -93,10 +94,7 @@ class ArduinoObjectDetection {
9394
);
9495
});
9596

96-
const personDetected = this.detectedObjects.some(detectionObject =>
97-
detectionObject.label === MODEL_LABELS.PERSON
98-
);
99-
this._isfaceDetected = personDetected;
97+
this._updateDetectionStates();
10098

10199
if (this._enableBoundingBoxes) {
102100
this._drawBoundingBoxes();
@@ -115,11 +113,17 @@ ArduinoObjectDetection.prototype.getInfo = function() {
115113
blockIconURI: iconURI,
116114
blocks: [
117115
{
118-
opcode: "whenPersonDetected",
116+
opcode: "whenObjectDetected",
119117
blockType: BlockType.HAT,
120-
text: "when person detected",
121-
func: "whenPersonDetected",
122-
arguments: {},
118+
text: "when [OBJECT] detected",
119+
func: "whenObjectDetected",
120+
arguments: {
121+
OBJECT: {
122+
type: ArgumentType.STRING,
123+
menu: "modelsLabels",
124+
defaultValue: MODEL_LABELS.PERSON,
125+
},
126+
},
123127
},
124128
{
125129
opcode: "startDetectionLoop",
@@ -136,11 +140,17 @@ ArduinoObjectDetection.prototype.getInfo = function() {
136140
arguments: {},
137141
},
138142
{
139-
opcode: "isPersonDetected",
143+
opcode: "isObjectDetected",
140144
blockType: BlockType.BOOLEAN,
141-
text: "is person detected",
142-
func: "isPersonDetected",
143-
arguments: {},
145+
text: "is [OBJECT] detected",
146+
func: "isObjectDetected",
147+
arguments: {
148+
OBJECT: {
149+
type: ArgumentType.STRING,
150+
menu: "modelsLabels",
151+
defaultValue: MODEL_LABELS.PERSON,
152+
},
153+
},
144154
},
145155
{
146156
opcode: "showBoundingBoxes",
@@ -156,6 +166,20 @@ ArduinoObjectDetection.prototype.getInfo = function() {
156166
func: "hideBoundingBoxes",
157167
arguments: {},
158168
},
169+
{
170+
opcode: "getDetectedObjectsCount",
171+
blockType: BlockType.REPORTER,
172+
text: "number",
173+
func: "getDetectedObjectsCount",
174+
arguments: {},
175+
},
176+
{
177+
opcode: "getDetectedLabelsAsString",
178+
blockType: BlockType.REPORTER,
179+
text: "labels",
180+
func: "getDetectedLabelsAsString",
181+
arguments: {},
182+
},
159183
],
160184
menus: {
161185
modelsLabels: Object.values(MODEL_LABELS).sort(),
@@ -201,16 +225,18 @@ ArduinoObjectDetection.prototype._loop = function() {
201225
}
202226
this._detectObjects();
203227

204-
// Note: The face detection state (_isfaceDetected) will be updated
228+
// Note: The detection states for all objects will be updated
205229
// automatically when the detection_result event is received
206230
};
207231

208-
ArduinoObjectDetection.prototype.whenPersonDetected = function(args) {
209-
return this.isPersonDetected();
232+
ArduinoObjectDetection.prototype.whenObjectDetected = function(args) {
233+
const objectLabel = args.OBJECT;
234+
return this.detectedObjects.some(detectionObject => detectionObject.label === objectLabel);
210235
};
211236

212-
ArduinoObjectDetection.prototype.isPersonDetected = function(args) {
213-
return this._isfaceDetected;
237+
ArduinoObjectDetection.prototype.isObjectDetected = function(args) {
238+
const objectLabel = args.OBJECT;
239+
return this.detectedObjects.some(detectionObject => detectionObject.label === objectLabel);
214240
};
215241

216242
ArduinoObjectDetection.prototype.hideBoundingBoxes = function(args) {
@@ -325,4 +351,62 @@ ArduinoObjectDetection.prototype._createRectangleFromBoundingBox = function(x1,
325351
return rectangle;
326352
};
327353

354+
/**
355+
* Block function: Get the total number of detected objects
356+
* @returns {number} Number of currently detected objects
357+
*/
358+
ArduinoObjectDetection.prototype.getDetectedObjectsCount = function() {
359+
return this.detectedObjects.length;
360+
};
361+
362+
/**
363+
* Block function: Get detected object types as a comma-separated string
364+
* @returns {string} Comma-separated list of detected object types
365+
*/
366+
ArduinoObjectDetection.prototype.getDetectedLabelsAsString = function() {
367+
const detectedLabels = this._getDetectedLabels();
368+
return detectedLabels.length > 0 ? detectedLabels.join(", ") : "none";
369+
};
370+
371+
/**
372+
* Initialize detection states for all model labels
373+
* @returns {Object<string, boolean>} Object with all labels set to false
374+
*/
375+
ArduinoObjectDetection.prototype._initializeDetectionStates = function() {
376+
const states = {};
377+
Object.values(MODEL_LABELS).forEach(label => {
378+
states[label] = false;
379+
});
380+
return states;
381+
};
382+
383+
/**
384+
* Update detection states based on currently detected objects
385+
*/
386+
ArduinoObjectDetection.prototype._updateDetectionStates = function() {
387+
// Reset all states to false
388+
Object.keys(this._detectionStates).forEach(label => {
389+
this._detectionStates[label] = false;
390+
});
391+
392+
// Set to true for currently detected objects
393+
this.detectedObjects.forEach(detectionObject => {
394+
this._detectionStates[detectionObject.label] = true;
395+
});
396+
397+
// Log detection updates for debugging
398+
const detectedLabels = Object.keys(this._detectionStates).filter(label => this._detectionStates[label]);
399+
if (detectedLabels.length > 0) {
400+
console.log(`Currently detected: ${detectedLabels.join(", ")}`);
401+
}
402+
};
403+
404+
/**
405+
* Get all currently detected object labels
406+
* @returns {Array<string>} Array of currently detected object labels
407+
*/
408+
ArduinoObjectDetection.prototype._getDetectedLabels = function() {
409+
return Object.keys(this._detectionStates).filter(label => this._detectionStates[label]);
410+
};
411+
328412
module.exports = ArduinoObjectDetection;

0 commit comments

Comments
 (0)