Skip to content

Commit 253af59

Browse files
committed
object detection
1 parent 99d544d commit 253af59

File tree

7 files changed

+90
-11
lines changed

7 files changed

+90
-11
lines changed

Diff for: camera.py

+21
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,24 @@ def cnn_classify(self, model_name=None, top_results=3):
373373
def find_class(self):
374374
return self.cnn_classify(top_results=1)[0][0]
375375

376+
def cnn_detect_objects(self, model_name=None, top_results=3):
377+
classifier = None
378+
if model_name:
379+
classifier = self._cnn_classifiers.get(model_name)
380+
if classifier is None:
381+
classifier = CNNManager.get_instance().load_model(model_name)
382+
self._cnn_classifiers[model_name] = classifier
383+
else:
384+
classifier = self._cnn_classifier_default
385+
386+
t0 = time.time()
387+
classes = None
388+
try:
389+
img = self.get_image()
390+
classes = classifier.detect_objects(img.mat(), top_results=top_results)
391+
except Exception:
392+
logging.warning("classifier not available")
393+
classes = [("None", 100)]
394+
raise
395+
logging.info("fps: %f", 1.0/(time.time()-t0))
396+
return classes

Diff for: cnn_classifier.py

+42-10
Original file line numberDiff line numberDiff line change
@@ -129,23 +129,55 @@ def classify_image(self,
129129
#else:
130130
input_image = self.read_tensor_from_image_mat(image_file_or_mat)
131131

132-
logger.info("classify.0")
133132
self._interpreter.set_tensor(self._input_details[0]['index'], input_image)
134133
self._interpreter.invoke()
135-
logger.info("classify.1")
136134
scores = self._interpreter.get_tensor(self._output_details[0]['index'])[0] # Bounding box coordinates of detected objects
137-
#logger.info("classify.2")
138-
#classes = self._interpreter.get_tensor(self._output_details[1]['index'])[0] # Class index of detected objects
139-
#logger.info("classify.3")
140-
#scores = self._interpreter.get_tensor(self._output_details[2]['index'])[0] # Confidence of detected objects
141-
#logger.info("classify.4")
142135

143-
#pairs = [(classes[i], scores[i], boxes[i]) for i in range(0, len(classes))]
144136
pairs = []
145137
for i in range(0, len(scores)):
146-
if scores[i] > 0.5:
138+
if scores[i] > 128:
147139
object_name = self._labels[i]
148-
pairs.append((object_name, scores[i]))
140+
pairs.append((object_name, int(100*scores[i]/256)))
149141

142+
pairs = sorted(pairs, key=lambda x: x[1], reverse=True)[:top_results]
143+
logger.info(str(pairs))
144+
return pairs
145+
146+
def detect_objects(self,
147+
image_file_or_mat,
148+
top_results=3):
149+
input_image = None
150+
#if isinstance(image_file_or_mat, str):
151+
# t = self.read_tensor_from_image_file(file_name=image_file_or_mat)
152+
#else:
153+
input_image = self.read_tensor_from_image_mat(image_file_or_mat)
154+
155+
self._interpreter.set_tensor(self._input_details[0]['index'], input_image)
156+
self._interpreter.invoke()
157+
158+
# Retrieve detection results
159+
boxes = self._interpreter.get_tensor(self._output_details[0]['index'])[0] # Bounding box coordinates of detected objects
160+
classes = self._interpreter.get_tensor(self._output_details[1]['index'])[0] # Class index of detected objects
161+
scores = self._interpreter.get_tensor(self._output_details[2]['index'])[0] # Confidence of detected objects
162+
163+
# Loop over all detections and draw detection box if confidence is above minimum threshold
164+
min_conf_threshold=0.1
165+
imH=100
166+
imW=100
167+
pairs = []
168+
for i in range(len(scores)):
169+
if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):
170+
171+
# Get bounding box coordinates and draw box
172+
# Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
173+
ymin = int(max(1,(boxes[i][0] * imH)))
174+
xmin = int(max(1,(boxes[i][1] * imW)))
175+
ymax = int(min(imH,(boxes[i][2] * imH)))
176+
xmax = int(min(imW,(boxes[i][3] * imW)))
177+
178+
object_name = self._labels[int(classes[i])]
179+
pairs.append((object_name, int(100*scores[i]), (xmin, ymin, xmax, ymax)))
180+
181+
pairs = sorted(pairs, key=lambda x: x[1], reverse=True)[:top_results]
150182
logger.info(str(pairs))
151183
return pairs

Diff for: cnn_models/models.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"test_model_1": {"status": 0, "image_height": "128", "image_width": "128", "output_layer": "final_result"}, "mobilenet_v1_1_0_quant": {"status": 100, "image_height": 120, "output_layer": "final_result", "image_width": 160}}
1+
{"test_model_1": {"status": 0, "image_height": "128", "image_width": "128", "output_layer": "final_result"}, "mobilenet_v1_1_0_quant": {"status": 100, "image_height": 120, "output_layer": "final_result", "image_width": 160}, "v3-large_224_1.0_uint8": {"status": 1.0, "image_height": 224, "output_layer": "final_result", "image_width": 224}, "object_detection": {"status": 1.0, "image_height": 224, "output_layer": "final_result", "image_width": 224}}

Diff for: static/js/blockly/blocks.js

+23
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,29 @@ Blockly.Python['coderbot_adv_cnn_classify'] = function(block) {
759759
return [class_scores, Blockly.Python.ORDER_ATOMIC];
760760
};
761761

762+
Blockly.Blocks['coderbot_adv_cnn_detect_objects'] = {
763+
/**
764+
* Block for find_class function.
765+
* @this Blockly.Block
766+
*/
767+
init: function() {
768+
this.setHelpUrl(Blockly.Msg.LOGIC_BOOLEAN_HELPURL);
769+
this.setColour(250);
770+
this.appendDummyInput()
771+
.appendField(Blockly.Msg.CODERBOT_SENSOR_FINDOBJECT)
772+
.appendField(new Blockly.FieldDropdown(CODERBOT_CNN_MODEL_LIST), 'MODEL');
773+
this.setInputsInline(true);
774+
this.setOutput(true, ['Array']);
775+
this.setTooltip(Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP);
776+
}
777+
};
778+
779+
Blockly.Python['coderbot_adv_cnn_detect_objects'] = function(block) {
780+
var model = block.getFieldValue('MODEL');
781+
var class_scores = 'get_cam().cnn_detect_objects("'+ model +'")';
782+
return [class_scores, Blockly.Python.ORDER_ATOMIC];
783+
};
784+
762785
Blockly.Blocks['coderbot_event_generator'] = {
763786
init: function() {
764787
this.appendDummyInput()

Diff for: static/js/blockly/bot_en.js

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Blockly.Msg.CODERBOT_SENSOR_FINDFACE_SIZE = "size";
5252
Blockly.Msg.CODERBOT_SENSOR_FINDFACE_ALL = "x, y, size (as list)";
5353
Blockly.Msg.CODERBOT_SENSOR_FINDLOGO = "find logo";
5454
Blockly.Msg.CODERBOT_SENSOR_FINDCLASS = "find class";
55+
Blockly.Msg.CODERBOT_SENSOR_FINDOBJECT = "detect objects";
5556
Blockly.Msg.CODERBOT_SENSOR_AVERAGE = "get image average";
5657
Blockly.Msg.CODERBOT_SENSOR_AVERAGE_HUE = "Hue";
5758
Blockly.Msg.CODERBOT_SENSOR_AVERAGE_SATURATION = "Saturation";

Diff for: static/js/blockly/bot_it.js

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Blockly.Msg.CODERBOT_SENSOR_FINDFACE_SIZE = "dimensione";
5252
Blockly.Msg.CODERBOT_SENSOR_FINDFACE_ALL = "x, y, dimensione (come lista)";
5353
Blockly.Msg.CODERBOT_SENSOR_FINDLOGO = "trova logo";
5454
Blockly.Msg.CODERBOT_SENSOR_FINDCLASS = "trova classe";
55+
Blockly.Msg.CODERBOT_SENSOR_FINDOBJECT = "trova oggetti";
5556
Blockly.Msg.CODERBOT_SENSOR_AVERAGE = "valore medio immagine";
5657
Blockly.Msg.CODERBOT_SENSOR_AVERAGE_HUE = "Tinta";
5758
Blockly.Msg.CODERBOT_SENSOR_AVERAGE_SATURATION = "Saturazione";

Diff for: templates/blocks_adv.xml

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@
303303
<block type="coderbot_adv_findARCode"></block>
304304
<block type="coderbot_adv_find_class"></block>
305305
<block type="coderbot_adv_cnn_classify"></block>
306+
<block type="coderbot_adv_cnn_detect_objects"></block>
306307
<block type="coderbot_sonar_get_distance"></block>
307308
</category>{%endif%}
308309
<category name="{% trans %}Sound{% endtrans %}" colour="220">

0 commit comments

Comments
 (0)