Skip to content

Commit 10adab4

Browse files
committed
feat: enhance object detection with state management and new reporting functions
1 parent ef60fbf commit 10adab4

File tree

1 file changed

+103
-15
lines changed
  • scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_object_detection

1 file changed

+103
-15
lines changed

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

Lines changed: 103 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ const iconURI = "";
2222
// eslint-disable-next-line max-len
2323
const menuIconURI = "";
2424

25-
const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`;
25+
// const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`;
26+
27+
const wsServerURL = `ws://192.168.1.39:7000`;
2628

2729
/**
2830
* RGB color constants for confidence visualization
@@ -42,7 +44,8 @@ class ArduinoObjectDetection {
4244

4345
this._penSkinId = null;
4446

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

4750
/** @type {number|null} */
4851
this._loopIntervalId = null;
@@ -93,11 +96,7 @@ class ArduinoObjectDetection {
9396
);
9497
});
9598

96-
// Update person detection for backward compatibility
97-
const personDetected = this.detectedObjects.some(detectionObject =>
98-
detectionObject.label === MODEL_LABELS.PERSON
99-
);
100-
this._isfaceDetected = personDetected;
99+
this._updateDetectionStates();
101100

102101
if (this._enableBoundingBoxes) {
103102
this._drawBoundingBoxes();
@@ -143,11 +142,17 @@ ArduinoObjectDetection.prototype.getInfo = function() {
143142
arguments: {},
144143
},
145144
{
146-
opcode: "isPersonDetected",
145+
opcode: "isObjectDetected",
147146
blockType: BlockType.BOOLEAN,
148-
text: "is person detected",
149-
func: "isPersonDetected",
150-
arguments: {},
147+
text: "is [OBJECT] detected",
148+
func: "isObjectDetected",
149+
arguments: {
150+
OBJECT: {
151+
type: ArgumentType.STRING,
152+
menu: "modelsLabels",
153+
defaultValue: MODEL_LABELS.PERSON,
154+
},
155+
},
151156
},
152157
{
153158
opcode: "showBoundingBoxes",
@@ -163,6 +168,20 @@ ArduinoObjectDetection.prototype.getInfo = function() {
163168
func: "hideBoundingBoxes",
164169
arguments: {},
165170
},
171+
{
172+
opcode: "getDetectedObjectsCount",
173+
blockType: BlockType.REPORTER,
174+
text: "number of detected objects",
175+
func: "getDetectedObjectsCount",
176+
arguments: {},
177+
},
178+
{
179+
opcode: "getDetectedLabelsAsString",
180+
blockType: BlockType.REPORTER,
181+
text: "detected object types",
182+
func: "getDetectedLabelsAsString",
183+
arguments: {},
184+
},
166185
],
167186
menus: {
168187
modelsLabels: Object.values(MODEL_LABELS).sort(),
@@ -208,19 +227,22 @@ ArduinoObjectDetection.prototype._loop = function() {
208227
}
209228
this._detectObjects();
210229

211-
// Note: The face detection state (_isfaceDetected) will be updated
230+
// Note: The detection states for all objects will be updated
212231
// automatically when the detection_result event is received
213232
};
214233

215234
ArduinoObjectDetection.prototype.whenObjectDetected = function(args) {
216235
const objectLabel = args.OBJECT;
217-
return this.detectedObjects.some(detectionObject =>
236+
return this.detectedObjects.some(detectionObject =>
218237
detectionObject.label === objectLabel
219238
);
220239
};
221240

222-
ArduinoObjectDetection.prototype.isPersonDetected = function(args) {
223-
return this._isfaceDetected;
241+
ArduinoObjectDetection.prototype.isObjectDetected = function(args) {
242+
const objectLabel = args.OBJECT;
243+
return this.detectedObjects.some(detectionObject =>
244+
detectionObject.label === objectLabel
245+
);
224246
};
225247

226248
ArduinoObjectDetection.prototype.hideBoundingBoxes = function(args) {
@@ -335,4 +357,70 @@ ArduinoObjectDetection.prototype._createRectangleFromBoundingBox = function(x1,
335357
return rectangle;
336358
};
337359

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

0 commit comments

Comments
 (0)