From 9e27c59346d4f99a25c2d93be65e00066307f4c8 Mon Sep 17 00:00:00 2001
From: Irene-Maxine <114802521+Irene-Maxine@users.noreply.github.com>
Date: Sat, 1 Nov 2025 09:32:17 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9D=BF=E8=BD=BD=E6=99=BA=E8=83=BD=E4=BF=AE?=
=?UTF-8?q?=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../micropython/blocks/ai_local.js | 146 ++++++++++++++----
.../micropython/generators/ai_local.js | 67 +++++++-
.../micropython_esp32s3/template.xml | 129 ++++++++++++++--
common/msg/blockly/zh-hans.js | 3 +
4 files changed, 297 insertions(+), 48 deletions(-)
diff --git a/boards/default_src/micropython/blocks/ai_local.js b/boards/default_src/micropython/blocks/ai_local.js
index fa166923..b4a61804 100644
--- a/boards/default_src/micropython/blocks/ai_local.js
+++ b/boards/default_src/micropython/blocks/ai_local.js
@@ -390,7 +390,9 @@ export const CONVERT_IMAGE_TO_JPG = {
.appendField(new Blockly.FieldDropdown([
["JPG" + Blockly.Msg.MIXLY_SD_DATA,"0"],
[Blockly.Msg.MIXLY_JPG_base64_CODE + Blockly.Msg.MIXLY_SD_DATA ,"1"]
- ]),"kind")
+ ]),"kind");
+ this.appendValueInput('quality')
+ .appendField(Blockly.Msg.MIXLY_IMAGE_QUALITY);
this.setOutput(true);
this.setInputsInline(true);
}
@@ -426,6 +428,23 @@ export const SCREEN_SHOW_CAM_GRAPH_SHOOT = {
}
};
+export const SCREEN_SHOW_CAM_GRAPH_SHOOT_LOCATION = {
+ init: function () {
+ this.setColour(DISPLAY_ONBOARD_HUE);
+ this.appendValueInput("SUB")
+ .appendField(Blockly.Msg.OLEDDISPLAY + Blockly.Msg.MIXLY_MICROBIT_IMAGE)
+ this.appendValueInput("x")
+ .appendField(Blockly.Msg.TURTLE_POS + "x");
+ this.appendValueInput("y")
+ .appendField("y")
+ this.appendValueInput('boolean')
+ .appendField( Blockly.Msg.MIXLY_synchronize);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
export const SCREEN_DISPLAY_IMAGE = {
init: function () {
this.setColour(DISPLAY_ONBOARD_HUE);
@@ -448,6 +467,52 @@ export const SCREEN_DISPLAY_IMAGE = {
}
};
+export const SCREEN_DISPLAY_IMAGE_LOCATION = {
+ init: function () {
+ this.setColour(DISPLAY_ONBOARD_HUE);
+ this.appendValueInput('direct')
+ .appendField(Blockly.Msg.OLED_BITMAP)
+ .appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_THE_PATH);
+ this.appendValueInput("x")
+ .appendField(Blockly.Msg.TURTLE_POS + "x");
+ this.appendValueInput("y")
+ .appendField("y")
+ this.appendDummyInput('')
+ .appendField(Blockly.Msg.MIXLY_ROTATION_ANGLE)
+ .appendField(new Blockly.FieldDropdown([
+ ['0','0'],
+ ['90','90'],
+ ['180','180'],
+ ['270','270']
+ ]),'angle');
+ this.appendValueInput('boolean')
+ .appendField( Blockly.Msg.MIXLY_synchronize);
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
+};
+
+export const GET_SCREEN_IMAGE_SIZE = {
+ init: function () {
+ this.setColour(DISPLAY_ONBOARD_HUE);
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.MIXLY_SCREENSHOT + Blockly.Msg.MIXLY_MICROBIT_monitor)
+ this.appendValueInput("x")
+ .appendField("x")
+ this.appendValueInput("y")
+ .appendField("y")
+ this.appendValueInput("w")
+ .appendField("w")
+ this.appendValueInput("h")
+ .appendField("h")
+ this.appendDummyInput("")
+ .appendField(Blockly.Msg.blockpy_set_of + Blockly.Msg.MIXLY_MICROBIT_IMAGE)
+ this.setOutput(true);
+ this.setInputsInline(true);
+ }
+};
+
export const GET_SCREEN_IMAGE = {
init: function () {
this.setColour(DISPLAY_ONBOARD_HUE);
@@ -471,10 +536,23 @@ export const AI_CAMERA_INIT = {
[Blockly.Msg.MIXLY_COLOR_RECOGNTITION, "ColorDetector"],
[Blockly.Msg.MIXLY_CAT + Blockly.Msg.MIXLY_RECOGNITION, "CatDetector"],
[Blockly.Msg.MIXLY_HUMAN + Blockly.Msg.MIXLY_RECOGNITION, "HumanDetector"],
- [Blockly.Msg.MIXLY_FACE_CLASSIFIER, "FaceDetector"]
+ [Blockly.Msg.MIXLY_FACE_CLASSIFIER, "FaceDetector"],
+ [Blockly.Msg.MIXLY_PICTURE_CLASSIFY,"ImageNet"]
]), "kind");
+ this.appendValueInput("WIDTH")
+ .appendField(Blockly.Msg.MIXLY_WIDTH);
+ this.appendValueInput("HEIGHT")
+ .appendField(Blockly.Msg.MIXLY_HEIGHT);
+ this.setInputsInline(true);
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ }
+};
+
+export const MODEL_INIT_WIDTH = {
+ init: function(){
+ this.setColour(AI_LOCAL_GRAPH_HUE);
this.appendDummyInput("")
- .appendField(Blockly.Msg.MIXLY_WIDTH)
.appendField(new Blockly.FieldDropdown([
["240px","240"],
["320px","320"],
@@ -484,8 +562,15 @@ export const AI_CAMERA_INIT = {
["480px","480"],
["160px","160"]
]),"width");
+ this.setOutput(true);
+ this.setInputsInline(true);
+ }
+};
+
+export const MODEL_INIT_HEIGHT = {
+ init: function(){
+ this.setColour(AI_LOCAL_GRAPH_HUE);
this.appendDummyInput("")
- .appendField(Blockly.Msg.MIXLY_HEIGHT)
.appendField(new Blockly.FieldDropdown([
["240px","240"],
["320px","320"],
@@ -497,8 +582,7 @@ export const AI_CAMERA_INIT = {
["120px","120"]
]),"height");
this.setInputsInline(true);
- this.setPreviousStatement(true, null);
- this.setNextStatement(true, null);
+ this.setOutput(true);
}
};
@@ -511,29 +595,10 @@ export const AI_CAMERA_INIT_FACERECOGNIZE = {
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_SETUP + Blockly.Msg.LISTS_SET_INDEX_INPUT_TO)
.appendField(Blockly.Msg.MIXLY_AipFace);
- this.appendDummyInput("")
- .appendField(Blockly.Msg.MIXLY_WIDTH)
- .appendField(new Blockly.FieldDropdown([
- ["240px","240"],
- ["320px","320"],
- ["128px","128"],
- ["96px","96"],
- ["640px","640"],
- ["480px","480"],
- ["160px","160"]
- ]),"width");
- this.appendDummyInput("")
- .appendField(Blockly.Msg.MIXLY_HEIGHT)
- .appendField(new Blockly.FieldDropdown([
- ["240px","240"],
- ["320px","320"],
- ["128px","128"],
- ["96px","96"],
- ["480px","480"],
- ["320px","320"],
- ["240px","240"],
- ["120px","120"]
- ]),"height");
+ this.appendValueInput("WIDTH")
+ .appendField(Blockly.Msg.MIXLY_WIDTH);
+ this.appendValueInput("HEIGHT")
+ .appendField(Blockly.Msg.MIXLY_HEIGHT);
this.appendValueInput("PATH")
.appendField(Blockly.Msg.PATH_OF_FACE_DATABASE);
this.setInputsInline(true);
@@ -616,7 +681,8 @@ export const GET_NO_RECOGNITION = {
[Blockly.Msg.HTML_COLOUR, "ColorDetector"],
[Blockly.Msg.MIXLY_CAT, "CatDetector"],
[Blockly.Msg.MIXLY_HUMAN, "HumanDetector"],
- [Blockly.Msg.MIXLY_FACE, "FaceDetector"]
+ [Blockly.Msg.MIXLY_FACE, "FaceDetector"],
+ [Blockly.Msg.MIXLY_PICTURE_CLASSIFY,"ImageNet"]
]), "kind");
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_DE + Blockly.Msg.OLED_STRING);
@@ -639,7 +705,8 @@ export const GET_NO_CAT_OR_FACE_RECOGNITION = {
[Blockly.Msg.HTML_COLOUR, "ColorDetector"],
[Blockly.Msg.MIXLY_CAT, "CatDetector"],
[Blockly.Msg.MIXLY_HUMAN, "HumanDetector"],
- [Blockly.Msg.MIXLY_FACE, "FaceDetector"]
+ [Blockly.Msg.MIXLY_FACE, "FaceDetector"],
+ [Blockly.Msg.MIXLY_PICTURE_CLASSIFY,"ImageNet"]
]), "kind");
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_DE + Blockly.Msg.MIXLY_CONFIDENCE_DEGREE);
@@ -851,6 +918,20 @@ export const GET_QR_CODE_RECOGNITION_DATA = {
}
};
+export const GET_PICTURE_RECOGNITION_DATA = {
+ init: function () {
+ this.setColour(AI_LOCAL_GRAPH_HUE);
+ this.appendValueInput('SUB')
+ .setCheck("var");
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GET_PICTURE_CLASSIFY_RESULT);
+ this.appendValueInput('boolean')
+ .appendField( Blockly.Msg.MIXLY_synchronize);
+ this.setOutput(true);
+ this.setInputsInline(true);
+ }
+};
+
export const GET_COLOR_DETECTION_NUM = {
init: function () {
this.setColour(AI_LOCAL_GRAPH_HUE);
@@ -1174,7 +1255,8 @@ export const AI_CAMERA_INIT_SIMPLE = {
[Blockly.Msg.MIXLY_CAT + Blockly.Msg.MIXLY_RECOGNITION, "CatDetector"],
[Blockly.Msg.MIXLY_HUMAN + Blockly.Msg.MIXLY_RECOGNITION, "HumanDetector"],
[Blockly.Msg.MIXLY_FACE_CLASSIFIER, "FaceDetector"],
- [Blockly.Msg.MIXLY_AipFace,"FaceRecognizer"]
+ [Blockly.Msg.MIXLY_AipFace,"FaceRecognizer"],
+ [Blockly.Msg.MIXLY_PICTURE_CLASSIFY,"ImageNet"]
]), "kind");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
diff --git a/boards/default_src/micropython/generators/ai_local.js b/boards/default_src/micropython/generators/ai_local.js
index 892f9600..8d3b1b20 100644
--- a/boards/default_src/micropython/generators/ai_local.js
+++ b/boards/default_src/micropython/generators/ai_local.js
@@ -177,7 +177,8 @@ export const CONVERT_IMAGE_TO_JPG = function (_, generator) {
generator.definitions_['camera_import_Image'] = 'from camera import Image';
var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
var kind = this.getFieldValue('kind');
- var code = 'Image.convert(' + sub + ', formats=' + kind + ')';
+ var q = generator.valueToCode(this, 'quality', generator.ORDER_ATOMIC);
+ var code = 'Image.convert(' + sub + ', formats=' + kind + ', quality='+ q +')';
return [code, generator.ORDER_ATOMIC];
}
@@ -198,6 +199,17 @@ export const SCREEN_SHOW_CAM_GRAPH_SHOOT = function (_, generator) {
return code;
}
+export const SCREEN_SHOW_CAM_GRAPH_SHOOT_LOCATION = function (_, generator) {
+ var version = Boards.getSelectedBoardKey().split(':')[2];
+ generator.definitions_['import_' + version + '_onboard_tft'] = "from " + version + " import onboard_tft";
+ var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
+ var x = generator.valueToCode(this, 'x', generator.ORDER_ATOMIC);
+ var y = generator.valueToCode(this, 'y', generator.ORDER_ATOMIC);
+ var bool = generator.valueToCode(this, 'boolean', generator.ORDER_ATOMIC);
+ var code = 'onboard_tft.display(' + sub +',x='+x+',x='+y+', sync='+ bool +')\n';
+ return code;
+}
+
export const SCREEN_DISPLAY_IMAGE = function (_, generator) {
var version = Boards.getSelectedBoardKey().split(':')[2];
generator.definitions_['import_' + version + '_onboard_tft'] = "from " + version + " import onboard_tft";
@@ -208,6 +220,18 @@ export const SCREEN_DISPLAY_IMAGE = function (_, generator) {
return code;
}
+export const SCREEN_DISPLAY_IMAGE_LOCATION = function (_, generator) {
+ var version = Boards.getSelectedBoardKey().split(':')[2];
+ generator.definitions_['import_' + version + '_onboard_tft'] = "from " + version + " import onboard_tft";
+ var direct = generator.valueToCode(this, 'direct', generator.ORDER_ATOMIC);
+ var x = generator.valueToCode(this, 'x', generator.ORDER_ATOMIC);
+ var y = generator.valueToCode(this, 'y', generator.ORDER_ATOMIC);
+ var a = this.getFieldValue('angle');
+ var bool = generator.valueToCode(this, 'boolean', generator.ORDER_ATOMIC);
+ var code = 'onboard_tft.display(' + direct +',x='+x+',x='+y + ',rotation=' + a + ',sync='+ bool + ')\n';
+ return code;
+}
+
export const GET_SCREEN_IMAGE = function (_, generator) {
var version = Boards.getSelectedBoardKey().split(':')[2];
generator.definitions_['import_' + version + '_onboard_tft'] = "from " + version + " import onboard_tft";
@@ -215,22 +239,45 @@ export const GET_SCREEN_IMAGE = function (_, generator) {
return [code, generator.ORDER_ATOMIC];
}
+export const GET_SCREEN_IMAGE_SIZE = function (_, generator) {
+ var version = Boards.getSelectedBoardKey().split(':')[2];
+ generator.definitions_['import_' + version + '_onboard_tft'] = "from " + version + " import onboard_tft";
+ var x = generator.valueToCode(this, 'x', generator.ORDER_ATOMIC);
+ var y = generator.valueToCode(this, 'y', generator.ORDER_ATOMIC);
+ var w = generator.valueToCode(this, 'w', generator.ORDER_ATOMIC);
+ var h = generator.valueToCode(this, 'h', generator.ORDER_ATOMIC);
+ var code = 'screenshot(x='+x+',y='+y+',w='+w+',h='+h+')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
export const AI_CAMERA_INIT = function (_, generator) {
generator.definitions_['import_esp_dl'] = 'import esp_dl';
var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
var cmd = this.getFieldValue('kind');
- var width = this.getFieldValue('width');
- var height = this.getFieldValue('height');
+ var width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC);
+ var height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC);
var code = sub +' = esp_dl.'+cmd + '(width='+width+', height='+height+')\n';
return code;
}
+export const MODEL_INIT_WIDTH = function (_, generator) {
+ var width = this.getFieldValue('width');
+ var code = width;
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const MODEL_INIT_HEIGHT = function (_, generator) {
+ var height = this.getFieldValue('height');
+ var code = height;
+ return [code, generator.ORDER_ATOMIC];
+}
+
export const AI_CAMERA_INIT_FACERECOGNIZE = function (_, generator) {
generator.definitions_['import_esp_dl'] = 'import esp_dl';
var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
var path = generator.valueToCode(this, 'PATH', generator.ORDER_ATOMIC);
- var width = this.getFieldValue('width');
- var height = this.getFieldValue('height');
+ var width = generator.valueToCode(this, 'WIDTH', generator.ORDER_ATOMIC);
+ var height = generator.valueToCode(this, 'HEIGHT', generator.ORDER_ATOMIC);
var code = sub +' = esp_dl.FaceRecognizer(width='+width+', height='+height+', db_path='+ path +')\n';
return code;
}
@@ -374,6 +421,14 @@ export const GET_QR_CODE_RECOGNITION_DATA = function (_, generator) {
return [code, generator.ORDER_ATOMIC];
}
+export const GET_PICTURE_RECOGNITION_DATA = function (_, generator) {
+ generator.definitions_['import_esp_dl'] = 'import esp_dl'
+ var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
+ var bool = generator.valueToCode(this, 'boolean', generator.ORDER_ATOMIC);
+ var code = 'esp_dl.simple_run('+ sub + ', camera, "data", color=0xF800, sync='+bool+')';
+ return [code, generator.ORDER_ATOMIC];
+}
+
export const GET_COLOR_DETECTION_NUM = function (_, generator) {
generator.definitions_['import_esp_dl'] = 'import esp_dl'
var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
@@ -425,7 +480,7 @@ export const GET_FACE_DETECTION_NAME = function (_, generator) {
generator.definitions_['import_esp_dl'] = 'import esp_dl'
var sub = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
var bool = generator.valueToCode(this, 'boolean', generator.ORDER_ATOMIC);
- var code = 'esp_dl.simple_run('+ sub + ', "person", color=0xF800, sync='+bool+')["name"]\n';
+ var code = 'esp_dl.simple_run('+ sub + ', camera, "person", "name", color=0xF800, sync='+bool+')';
return [code, generator.ORDER_ATOMIC];
}
diff --git a/boards/default_src/micropython_esp32s3/template.xml b/boards/default_src/micropython_esp32s3/template.xml
index 50b612c5..af30619b 100644
--- a/boards/default_src/micropython_esp32s3/template.xml
+++ b/boards/default_src/micropython_esp32s3/template.xml
@@ -2456,11 +2456,19 @@
-
-
- Model
-
-
+
+
+ Model
+
+
+
+
+
+
+
+
+
+
@@ -2499,6 +2507,17 @@
+
+
+
+ Model
+
+
+
+
+
+
+
@@ -2685,6 +2704,11 @@
image
+
+
+ 90
+
+
@@ -2734,12 +2758,60 @@
+
+
+
+ mixly.jpg
+
+
+
+
+ 0
+
+
+
+
+ 0
+
+
+
+
+
+
+
image
+
+ image
+
+
+
+
+ 0
+
+
+
+
+ 0
+
+
+
+
+ 240
+
+
+
+
+ 240
+
+
+
+
+
@@ -2751,12 +2823,41 @@
+
+
+
+ image
+
+
+
+
+ 0
+
+
+
+
+ 0
+
+
+
+
+
+
+
-
-
- Model
-
-
+
+
+ Model
+
+
+
+
+
+
+
+
+
+
@@ -2764,6 +2865,14 @@
Model
+
+
+
+
+
+
+
+
face.db
diff --git a/common/msg/blockly/zh-hans.js b/common/msg/blockly/zh-hans.js
index 4ed2b6f2..db5db9c8 100644
--- a/common/msg/blockly/zh-hans.js
+++ b/common/msg/blockly/zh-hans.js
@@ -4242,4 +4242,7 @@ ZhHans.print_the_contents_of_the_face_database = '打印人脸数据库的内容
ZhHans.MIXLY_FACE_ID = '面容ID';
ZhHans.MILXY_FACE_SIMILARITY = '面容相似度';
ZhHans.MIXLY_FACE_NAME = '面容姓名';
+ZhHans.MIXLY_PICTURE_CLASSIFY = '图像分类';
+ZhHans.MIXLY_GET_PICTURE_CLASSIFY_RESULT = '获取图像分类结果';
+ZhHans.MIXLY_SCREENSHOT = '截取';
})();
\ No newline at end of file