This commit is contained in:
xdl 2025-02-25 18:51:58 +08:00
parent 5dc6bd27a2
commit 4ece90a2a1
32 changed files with 6031 additions and 336 deletions

View File

@ -16,6 +16,34 @@
</mappings> </mappings>
</serverdata> </serverdata>
</paths> </paths>
<paths name="xdl-002-yun">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="xdl-002-yun (2)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="xdl-002-yun (3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="校园网-xdl-002">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData> </serverData>
</component> </component>
</project> </project>

View File

@ -5,9 +5,38 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="91cce309-934c-4921-82fc-69ef0f6bedbc" name="更改" comment="1"> <list default="true" id="91cce309-934c-4921-82fc-69ef0f6bedbc" name="更改" comment="1">
<change afterPath="$PROJECT_DIR$/日志处理文件_真.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/002_B_Car/model-178789.nncase/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/myplot.png" beforeDir="false" afterPath="$PROJECT_DIR$/myplot.png" afterDir="false" /> <change afterPath="$PROJECT_DIR$/002_B_Car/model-178789.nncase/model-178789.kmodel" afterDir="false" />
<change beforePath="$PROJECT_DIR$/日志处理文件.py" beforeDir="false" afterPath="$PROJECT_DIR$/日志处理文件.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/002_B_Car/model-178789.nncase/report.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-178950.nncase/main.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-178950.nncase/model-178950.kmodel" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-178950.nncase/report.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-179117.nncase.zip" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-179147.nncase.zip" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-179299.nncase/main.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-179299.nncase/model-179299.kmodel" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/model-179299.nncase/report.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/002_B_Car/xdl/找圆2.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/txt2xml.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/xml2txt.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/xml删除标签.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/图片分批.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/图片尺寸检查.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/deployment.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/deployment.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/K210采取图片.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/K210采取图片.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/image_with_red_rectangle.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/image_with_red_rectangle.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/xdl/len_B_sai_2.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/xdl/len_B_sai_2.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/xdl/保存图片.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/xdl/找圆.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/xdl/找圆.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/主程序/len_B_240110_waste.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/主程序/len_B_240110_waste.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/红绿灯len.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/红绿灯len.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/红绿灯len2.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/红绿灯len2.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/获取图片.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/获取图片.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/获取颜色阈值LAB.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/获取颜色阈值LAB.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/002_B_Car/颜色识别.py" beforeDir="false" afterPath="$PROJECT_DIR$/002_B_Car/颜色识别.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/img2bin.py" beforeDir="false" afterPath="$PROJECT_DIR$/img2bin.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/抽帧.py" beforeDir="false" afterPath="$PROJECT_DIR$/抽帧.py" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -39,34 +68,43 @@
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent"><![CDATA[{
"keyToString": { "keyToString": {
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true", "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"Python.img2bin.executor": "Run",
"Python.len_B_sai_2.executor": "Run",
"Python.test.executor": "Run", "Python.test.executor": "Run",
"Python.xml2txt.executor": "Run",
"Python.图片分批.executor": "Run",
"Python.图片尺寸检查.executor": "Run",
"Python.图片相似度.executor": "Run", "Python.图片相似度.executor": "Run",
"Python.找圆.executor": "Run",
"Python.抽帧.executor": "Run", "Python.抽帧.executor": "Run",
"Python.日志处理文件.executor": "Run", "Python.日志处理文件.executor": "Run",
"Python.日志处理文件_真.executor": "Run", "Python.日志处理文件_真.executor": "Run",
"Python.获取颜色的阈值.executor": "Run", "Python.获取颜色的阈值.executor": "Run",
"Python.获取颜色阈值LAB.executor": "Run",
"Python.重命名.executor": "Run", "Python.重命名.executor": "Run",
"RunOnceActivity.ShowReadmeOnStart": "true", "RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true", "RunOnceActivity.git.unshallow": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true", "SHARE_PROJECT_CONFIGURATION_FILES": "true",
"git-widget-placeholder": "main", "git-widget-placeholder": "main",
"last_opened_file_path": "D:/projects/Embedded_game", "last_opened_file_path": "D:/projects/Embedded_game/002_B_Car/xdl",
"node.js.detected.package.eslint": "true", "node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true", "node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)", "node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)", "node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm", "nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "vcs.Git", "settings.editor.selected.configurable": "ssh.settings",
"vue.rearranger.settings.migration": "true" "vue.rearranger.settings.migration": "true"
} }
}]]></component> }]]></component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="D:\projects\Embedded_game\002_B_Car\xdl" /> <recent name="D:\projects\Embedded_game\002_B_Car\xdl" />
<recent name="D:\projects\Embedded_game\002_B_Car" />
<recent name="D:\projects\Embedded_game" />
</key> </key>
</component> </component>
<component name="RunManager" selected="Python.日志处理文件"> <component name="RunManager" selected="Python.找圆">
<configuration name="日志处理文件" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> <configuration name="找圆" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" /> <module name="Embedded_game" />
<option name="ENV_FILES" value="" /> <option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -75,12 +113,12 @@
<env name="PYTHONUNBUFFERED" value="1" /> <env name="PYTHONUNBUFFERED" value="1" />
</envs> </envs>
<option name="SDK_HOME" value="" /> <option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/002_B_Car/xdl" />
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/日志处理文件.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/002_B_Car/xdl/找圆.py" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" /> <option name="EMULATE_TERMINAL" value="false" />
@ -89,7 +127,30 @@
<option name="INPUT_FILE" value="" /> <option name="INPUT_FILE" value="" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="日志处理文件_真" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> <configuration name="获取颜色阈值LAB" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/002_B_Car" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/002_B_Car/获取颜色阈值LAB.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="图片尺寸检查" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" /> <module name="Embedded_game" />
<option name="ENV_FILES" value="" /> <option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -103,7 +164,30 @@
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/日志处理文件_真.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/图片尺寸检查.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="图片分批" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/图片分批.py" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" /> <option name="EMULATE_TERMINAL" value="false" />
@ -227,7 +311,30 @@
<option name="INPUT_FILE" value="" /> <option name="INPUT_FILE" value="" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> <configuration name="img2bin" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/img2bin.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="len_B_sai_2" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" /> <module name="Embedded_game" />
<option name="ENV_FILES" value="" /> <option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -241,7 +348,30 @@
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/002_B_Car/xdl/test.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/002_B_Car/xdl/len_B_sai_2.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="xml2txt" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="Embedded_game" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/xml2txt.py" />
<option name="PARAMETERS" value="" /> <option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" /> <option name="EMULATE_TERMINAL" value="false" />
@ -252,9 +382,11 @@
</configuration> </configuration>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Python.日志处理文件" /> <item itemvalue="Python.找圆" />
<item itemvalue="Python.日志处理文件_真" /> <item itemvalue="Python.获取颜色阈值LAB" />
<item itemvalue="Python.test" /> <item itemvalue="Python.img2bin" />
<item itemvalue="Python.xml2txt" />
<item itemvalue="Python.len_B_sai_2" />
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
@ -267,6 +399,9 @@
</attachedChunks> </attachedChunks>
</component> </component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" /> <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="SvnConfiguration">
<configuration>C:\Users\10561\AppData\Roaming\Subversion</configuration>
</component>
<component name="TaskManager"> <component name="TaskManager">
<task active="true" id="Default" summary="默认任务"> <task active="true" id="Default" summary="默认任务">
<changelist id="91cce309-934c-4921-82fc-69ef0f6bedbc" name="更改" comment="" /> <changelist id="91cce309-934c-4921-82fc-69ef0f6bedbc" name="更改" comment="" />
@ -281,7 +416,23 @@
<workItem from="1735874317328" duration="7761000" /> <workItem from="1735874317328" duration="7761000" />
<workItem from="1735975478740" duration="636000" /> <workItem from="1735975478740" duration="636000" />
<workItem from="1736064683409" duration="3459000" /> <workItem from="1736064683409" duration="3459000" />
<workItem from="1736125587467" duration="1293000" /> <workItem from="1736125587467" duration="3642000" />
<workItem from="1736144139377" duration="596000" />
<workItem from="1736315660877" duration="499000" />
<workItem from="1739861435223" duration="7225000" />
<workItem from="1740099101846" duration="1076000" />
<workItem from="1740115682475" duration="3895000" />
<workItem from="1740128927833" duration="660000" />
<workItem from="1740205923474" duration="54000" />
<workItem from="1740220084348" duration="5037000" />
<workItem from="1740271294994" duration="18000" />
<workItem from="1740272768289" duration="18000" />
<workItem from="1740372266844" duration="2224000" />
<workItem from="1740379003167" duration="4805000" />
<workItem from="1740446685371" duration="609000" />
<workItem from="1740450495203" duration="303000" />
<workItem from="1740456642604" duration="7575000" />
<workItem from="1740476732575" duration="3886000" />
</task> </task>
<task id="LOCAL-00001" summary="1"> <task id="LOCAL-00001" summary="1">
<option name="closed" value="true" /> <option name="closed" value="true" />
@ -307,7 +458,23 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1736125962873</updated> <updated>1736125962873</updated>
</task> </task>
<option name="localTasksCounter" value="4" /> <task id="LOCAL-00004" summary="1">
<option name="closed" value="true" />
<created>1736126943869</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1736126943869</updated>
</task>
<task id="LOCAL-00005" summary="1">
<option name="closed" value="true" />
<created>1736126953818</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1736126953818</updated>
</task>
<option name="localTasksCounter" value="6" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@ -329,8 +496,12 @@
<option name="LAST_COMMIT_MESSAGE" value="1" /> <option name="LAST_COMMIT_MESSAGE" value="1" />
</component> </component>
<component name="com.intellij.coverage.CoverageDataManagerImpl"> <component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/Embedded_game$len_B_sai_2.coverage" NAME="len_B_sai_2 覆盖结果" MODIFIED="1739865950794" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/002_B_Car/xdl" />
<SUITE FILE_PATH="coverage/Embedded_game$_.coverage" NAME="日志处理文件_真 覆盖结果" MODIFIED="1736126782615" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> <SUITE FILE_PATH="coverage/Embedded_game$_.coverage" NAME="日志处理文件_真 覆盖结果" MODIFIED="1736126782615" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/Embedded_game$img2bin.coverage" NAME="img2bin 覆盖结果" MODIFIED="1740116992349" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/Embedded_game$LAB.coverage" NAME="获取颜色阈值LAB 覆盖结果" MODIFIED="1740459557626" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/002_B_Car" />
<SUITE FILE_PATH="coverage/Embedded_game$test.coverage" NAME="test 覆盖结果" MODIFIED="1735795840761" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/002_B_Car/xdl" /> <SUITE FILE_PATH="coverage/Embedded_game$test.coverage" NAME="test 覆盖结果" MODIFIED="1735795840761" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/002_B_Car/xdl" />
<SUITE FILE_PATH="coverage/Embedded_game$.coverage" NAME="日志处理文件 覆盖结果" MODIFIED="1736126870474" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> <SUITE FILE_PATH="coverage/Embedded_game$xml2txt.coverage" NAME="xml2txt 覆盖结果" MODIFIED="1740122801815" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/Embedded_game$.coverage" NAME="找圆 覆盖结果" MODIFIED="1740462384229" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/002_B_Car/xdl" />
</component> </component>
</project> </project>

View File

@ -1,24 +1,4 @@
'''
image caupture tool, capture images to SD card with directory switch support
@usage 1. Change camera and lcd configs according to your hardware like `lcd.rotation`
2. Prepare a SD card with SPI mode support, and format to FAT32 with MBR(msdos) partition
3. Copy this boot.py to your SD card root directory
4. Power off board, then insert SD card to board
5. Power on, it will automatically create a directory like `cap_images_1`,
the next time will be `cap_images_2` to avoid rewrite
6. Capture images for one class,
push `boot` button on board and release to capture one image,
this will save images as `cap_images_1/0/0.jpg`,
the name of image will automaitcally increase, like `0.jpg` `1.jpg` ...
7. Long push `boot` botton on board to switch class,
this will create a new directory like `cap_images_1/1/`,
and later captured images will be saved to this directory like `cap_images_1/1/0.jpg`
8. Power off board, pop out SD card, mount on your PC, now you get your images in your file brower
@update https://maixhub.com/app/3
@version v1.0.0
@author neucrack@sipeed
@license MIT
'''
import sensor, lcd import sensor, lcd
from Maix import GPIO from Maix import GPIO

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,112 @@
# generated by maixhub, tested on maixpy3 v0.4.8
# copy files to TF card and plug into board and power on
import sensor, image, lcd, time
import KPU as kpu
from machine import UART
import gc, sys
from fpioa_manager import fm
input_size = (224, 224)
labels = ['light', 'yellow', 'green', 'red']
anchors = [0.63, 0.69, 0.81, 0.91, 0.75, 2.47, 0.94, 3.78, 0.69, 2.78]
def lcd_show_except(e):
import uio
err_str = uio.StringIO()
sys.print_exception(e, err_str)
err_str = err_str.getvalue()
img = image.Image(size=input_size)
img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
lcd.display(img)
class Comm:
def __init__(self, uart):
self.uart = uart
def send_detect_result(self, objects, labels):
msg = ""
for obj in objects:
pos = obj.rect()
p = obj.value()
idx = obj.classid()
label = labels[idx]
msg += "{}:{}:{}:{}:{}:{:.2f}:{}, ".format(pos[0], pos[1], pos[2], pos[3], idx, p, label)
if msg:
msg = msg[:-2] + "\n"
self.uart.write(msg.encode())
def init_uart():
fm.register(10, fm.fpioa.UART1_TX, force=True)
fm.register(11, fm.fpioa.UART1_RX, force=True)
uart = UART(UART.UART1, 115200, 8, 0, 0, timeout=1000, read_buf_len=256)
return uart
def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing(sensor_window)
sensor.set_hmirror(sensor_hmirror)
sensor.set_vflip(sensor_vflip)
sensor.run(1)
lcd.init(type=1)
lcd.rotation(lcd_rotation)
lcd.clear(lcd.WHITE)
if not labels:
with open('labels.txt','r') as f:
exec(f.read())
if not labels:
print("no labels.txt")
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
lcd.display(img)
return 1
try:
img = image.Image("startup.jpg")
lcd.display(img)
except Exception:
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
lcd.display(img)
uart = init_uart()
comm = Comm(uart)
try:
task = None
task = kpu.load(model_addr)
kpu.init_yolo2(task, 0.7, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
while(True):
img = sensor.snapshot()
t = time.ticks_ms()
objects = kpu.run_yolo2(task, img)
t = time.ticks_ms() - t
if objects:
for obj in objects:
pos = obj.rect()
img.draw_rectangle(pos)
img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
comm.send_detect_result(objects, labels)
img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))
img.draw_string(0, 2, "Upgrade to MaixCAM to use YOLOv8", scale=1.2, color=(255, 0, 0))
img.draw_string(0, 30, "wiki.sipeed.com/maixcam", scale=1.2, color=(255, 0, 0))
lcd.display(img)
except Exception as e:
raise e
finally:
if not task is None:
kpu.deinit(task)
if __name__ == "__main__":
try:
# main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
main(anchors = anchors, labels=labels, model_addr="/sd/model-178789.kmodel")
except Exception as e:
sys.print_exception(e)
lcd_show_except(e)
finally:
gc.collect()

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,112 @@
# generated by maixhub, tested on maixpy3 v0.4.8
# copy files to TF card and plug into board and power on
import sensor, image, lcd, time
import KPU as kpu
from machine import UART
import gc, sys
from fpioa_manager import fm
input_size = (224, 224)
labels = ['light']
anchors = [1.06, 1.05, 0.91, 0.97, 0.72, 0.72, 0.84, 0.84, 1.06, 0.88]
def lcd_show_except(e):
import uio
err_str = uio.StringIO()
sys.print_exception(e, err_str)
err_str = err_str.getvalue()
img = image.Image(size=input_size)
img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
lcd.display(img)
class Comm:
def __init__(self, uart):
self.uart = uart
def send_detect_result(self, objects, labels):
msg = ""
for obj in objects:
pos = obj.rect()
p = obj.value()
idx = obj.classid()
label = labels[idx]
msg += "{}:{}:{}:{}:{}:{:.2f}:{}, ".format(pos[0], pos[1], pos[2], pos[3], idx, p, label)
if msg:
msg = msg[:-2] + "\n"
self.uart.write(msg.encode())
def init_uart():
fm.register(10, fm.fpioa.UART1_TX, force=True)
fm.register(11, fm.fpioa.UART1_RX, force=True)
uart = UART(UART.UART1, 115200, 8, 0, 0, timeout=1000, read_buf_len=256)
return uart
def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing(sensor_window)
sensor.set_hmirror(sensor_hmirror)
sensor.set_vflip(sensor_vflip)
sensor.run(1)
lcd.init(type=1)
lcd.rotation(lcd_rotation)
lcd.clear(lcd.WHITE)
if not labels:
with open('labels.txt','r') as f:
exec(f.read())
if not labels:
print("no labels.txt")
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
lcd.display(img)
return 1
try:
img = image.Image("startup.jpg")
lcd.display(img)
except Exception:
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
lcd.display(img)
uart = init_uart()
comm = Comm(uart)
try:
task = None
task = kpu.load(model_addr)
kpu.init_yolo2(task, 0.4, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
while(True):
img = sensor.snapshot()
t = time.ticks_ms()
objects = kpu.run_yolo2(task, img)
t = time.ticks_ms() - t
if objects:
for obj in objects:
pos = obj.rect()
img.draw_rectangle(pos)
img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
comm.send_detect_result(objects, labels)
img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))
img.draw_string(0, 2, "Upgrade to MaixCAM to use YOLOv8", scale=1.2, color=(255, 0, 0))
img.draw_string(0, 30, "wiki.sipeed.com/maixcam", scale=1.2, color=(255, 0, 0))
lcd.display(img)
except Exception as e:
raise e
finally:
if not task is None:
kpu.deinit(task)
if __name__ == "__main__":
try:
# main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
main(anchors = anchors, labels=labels, model_addr="/sd/model-178950.kmodel")
except Exception as e:
sys.print_exception(e)
lcd_show_except(e)
finally:
gc.collect()

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,113 @@
# generated by maixhub, tested on maixpy3 v0.4.8
# copy files to TF card and plug into board and power on
import sensor, image, lcd, time
import KPU as kpu
from machine import UART
import gc, sys
from fpioa_manager import fm
input_size = (224, 224)
labels = ['light']
anchors = [0.84, 0.5, 0.78, 0.81, 0.84, 0.91, 0.78, 0.34, 0.72, 0.72]
def lcd_show_except(e):
import uio
err_str = uio.StringIO()
sys.print_exception(e, err_str)
err_str = err_str.getvalue()
img = image.Image(size=input_size)
img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
lcd.display(img)
class Comm:
def __init__(self, uart):
self.uart = uart
def send_detect_result(self, objects, labels):
msg = ""
for obj in objects:
pos = obj.rect()
p = obj.value()
idx = obj.classid()
label = labels[idx]
msg += "{}:{}:{}:{}:{}:{:.2f}:{}, ".format(pos[0], pos[1], pos[2], pos[3], idx, p, label)
if msg:
msg = msg[:-2] + "\n"
self.uart.write(msg.encode())
def init_uart():
fm.register(10, fm.fpioa.UART1_TX, force=True)
fm.register(11, fm.fpioa.UART1_RX, force=True)
uart = UART(UART.UART1, 115200, 8, 0, 0, timeout=1000, read_buf_len=256)
return uart
def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing(sensor_window)
sensor.set_hmirror(sensor_hmirror)
sensor.set_vflip(sensor_vflip)
sensor.run(1)
lcd.init(type=1)
lcd.rotation(lcd_rotation)
lcd.clear(lcd.WHITE)
if not labels:
with open('labels.txt','r') as f:
exec(f.read())
if not labels:
print("no labels.txt")
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
lcd.display(img)
return 1
try:
img = image.Image("startup.jpg")
lcd.display(img)
except Exception:
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
lcd.display(img)
uart = init_uart()
comm = Comm(uart)
try:
task = None
task = kpu.load(model_addr)
kpu.init_yolo2(task, 0.3, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
while(True):
t = time.ticks_ms()
img = sensor.snapshot()
img = img.rotation_corr(z_rotation=180) # 旋转90度
objects = kpu.run_yolo2(task, img)
t = time.ticks_ms() - t
if objects:
for obj in objects:
pos = obj.rect()
img.draw_rectangle(pos)
img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
comm.send_detect_result(objects, labels)
img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))
# img.draw_string(0, 2, "Upgrade to MaixCAM to use YOLOv8", scale=1.2, color=(255, 0, 0))
# img.draw_string(0, 30, "wiki.sipeed.com/maixcam", scale=1.2, color=(255, 0, 0))
lcd.display(img)
except Exception as e:
raise e
finally:
if not task is None:
kpu.deinit(task)
if __name__ == "__main__":
try:
# main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
main(anchors = anchors, labels=labels, model_addr="/sd/model-179299.kmodel")
except Exception as e:
sys.print_exception(e)
lcd_show_except(e)
finally:
gc.collect()

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -128,7 +128,7 @@ class Mainlen():
self.tracking(img) self.tracking(img)
elif Flag_qr: # 二维码# elif Flag_qr: # 二维码#
print("识别二维码") print("识别二维码")
self.discem_QR(img)#r任务9 self.discem_QR(img)
# Flag_qr = False # Flag_qr = False
elif Flag_light: # 红绿灯 elif Flag_light: # 红绿灯
print("识别红绿灯") print("识别红绿灯")
@ -252,16 +252,14 @@ class Mainlen():
# result = self.remove_chinese_chars(result) # 剔除中文 # result = self.remove_chinese_chars(result) # 剔除中文
print(result) print(result)
if len(result) > 10: # 车牌 if len(result) < 10: # 车牌
result = self.jiajin(result) # result = self.jiajin(result)
result = self.binary_to_hexadecimal(result) # result = self.binary_to_hexadecimal(result)
count = 2
else: # 公式
count = 1 count = 1
if res == len(res_QR) - 1: else: # 公式
if_end = 0x00 continue
print("count: ", count) print("count: ", count)
print("if_end: ", if_end) print("if_end: ", if_end)
@ -275,12 +273,8 @@ class Mainlen():
self.uart.write(bytes([0x06])) self.uart.write(bytes([0x06]))
print(len(result)) print(len(result))
self.uart.write(bytes([count])) self.uart.write(bytes([count]))
self.uart.write(bytes([if_end])) # self.uart.write(bytes([if_end]))
if count==2: if count==1:
self.uart.write(bytes([2]))
self.uart.write(bytes([int(result[1]+result[0], 16)]))
self.uart.write(bytes([int(result[3]+result[2], 16)]))
else:
self.uart.write(bytes([len(result)])) self.uart.write(bytes([len(result)]))
for qr_data in result: for qr_data in result:
self.uart.write(bytes([ord(qr_data)])) self.uart.write(bytes([ord(qr_data)]))

View File

@ -1,28 +0,0 @@
import sensor, image, lcd, time
from Maix import UART
from fpioa_manager import fm
# 初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
# 初始化 LCD
lcd.init()
lcd.rotation(2)
# 初始化 UART
fm.register(7, fm.fpioa.UART1_TX) # TX 引脚映射
fm.register(6, fm.fpioa.UART1_RX) # RX 引脚映射
uart = UART(UART.UART1, 115200, read_buf_len=4096)
print("按下按钮捕获图片并发送")
while True:
img = sensor.snapshot()
lcd.display(img)
if uart.read(1): # 等待串口信号(例如从电脑发送字符)
print("开始发送图片...")
uart.write(img.compress(quality=90).to_bytes()) # 压缩并发送图片
print("图片发送完成")

View File

@ -18,12 +18,8 @@ sensor.skip_frames(time=200) # 等待设置生效
def draw_circles(): def draw_circles():
""" """
检测并绘制图像中的圆形仅在图像的右半部分进行检测 检测并绘制图像中的圆形仅在图像的右半部分进行检测
累计识别条件为超过4秒或识别到3个圆
""" """
result_cache = [] # 缓存每次有结果的识别
max_results = 3 # 累计识别到的圆形数量
start_time = time.ticks_ms() # 记录开始时间(毫秒) start_time = time.ticks_ms() # 记录开始时间(毫秒)
def circles_overlap(c1, c2): def circles_overlap(c1, c2):
"""判断两个圆是否重叠""" """判断两个圆是否重叠"""
dx = c1.x() - c2.x() dx = c1.x() - c2.x()
@ -35,109 +31,111 @@ def draw_circles():
"""尝试合并新检测到的圆与缓存中的圆""" """尝试合并新检测到的圆与缓存中的圆"""
for existing in cache: for existing in cache:
if circles_overlap(new_circle, existing): if circles_overlap(new_circle, existing):
return # 如果重叠,不加入新的圆 return False # 如果重叠,不加入新的圆
cache.append(new_circle) # 如果没有重叠,添加到缓存中 cache.append(new_circle) # 如果没有重叠,添加到缓存中
return True
def calculate_lab(area, img): def calculate_lab(area, img):
"""计算给定区域的中间 1/3 的平均 LAB 值""" """计算给定区域的平均 LAB 值"""
mean_l, mean_a, mean_b = 0, 0, 0 stats = img.get_statistics(roi=area)
pixel_count = 0 return stats.l_mean(), stats.a_mean(), stats.b_mean()
start_y = area[1] + area[3] // 3
end_y = start_y + area[3] // 3
for y in range(start_y, end_y):
for x in range(area[0], area[0] + area[2]):
l, a, b = img.get_statistics(roi=(x, y, 1, 1)).l_mean(), \
img.get_statistics(roi=(x, y, 1, 1)).a_mean(), \
img.get_statistics(roi=(x, y, 1, 1)).b_mean()
mean_l += l
mean_a += a
mean_b += b
pixel_count += 1
mean_l //= pixel_count
mean_a //= pixel_count
mean_b //= pixel_count
return mean_l, mean_a, mean_b
def determine_farthest_circle(circles, img):
"""找到与其他圆 LAB 差异最大的圆"""
start_time = time.ticks_ms() # 开始时间
max_distance = -1
farthest_circle = None
farthest_lab = None
for i, c1 in enumerate(circles):
area1 = (c1.x() - c1.r(), c1.y() - c1.r(), 2 * c1.r(), 2 * c1.r())
lab1 = calculate_lab(area1, img)
total_distance = 0
for j, c2 in enumerate(circles):
if i != j:
area2 = (c2.x() - c2.r(), c2.y() - c2.r(), 2 * c2.r(), 2 * c2.r())
lab2 = calculate_lab(area2, img)
total_distance += ((lab1[0] - lab2[0]) ** 2 + (lab1[1] - lab2[1]) ** 2 + (lab1[2] - lab2[2]) ** 2) ** 0.5
if total_distance > max_distance:
max_distance = total_distance
farthest_circle = c1
farthest_lab = lab1
elapsed_time = time.ticks_diff(time.ticks_ms(), start_time) # 计算耗时
print("determine_farthest_circle 耗时:" ,elapsed_time," ms")
return farthest_circle, farthest_lab
def determine_color_from_lab(lab): def determine_color_from_lab(lab):
"""根据 LAB 值判断颜色倾向""" """
返回最接近的颜色以及对应的距离
:param lab: (l, a, b) 三元组
:return: (closest_color, min_distance)
"""
# 你可以根据实际情况添加或修改更多预设颜色及其 LAB
predefined_colors = { predefined_colors = {
"红色": (53, 80, 67), "红色": (50, 38, 1),
"黄色": (97, -21, 94), "黄色": (86, 2, 27),
"绿色": (87, -86, 83) "绿色": (75, -29, 15)
} }
min_distance = float('inf') min_distance = float('inf')
closest_color = "灰色" closest_color = "灰色" # 默认或者未匹配时
for color_name, (l, a, b) in predefined_colors.items():
distance = ((lab[0] - l) ** 2 + (lab[1] - a) ** 2 + (lab[2] - b) ** 2) ** 0.5 # 打印一下实际检测到的LAB便于调试
# print("检测到的LAB:", lab)
for color_name, (l_ref, a_ref, b_ref) in predefined_colors.items():
distance = ((lab[0] - l_ref) ** 2 +
(lab[1] - a_ref) ** 2 +
(lab[2] - b_ref) ** 2) ** 0.5
if distance < min_distance: if distance < min_distance:
min_distance = distance min_distance = distance
closest_color = color_name closest_color = color_name
return closest_color if min_distance < 10:
print("最接近的颜色={}, 距离={:.2f}".format(closest_color, min_distance))
# print("最接近的颜色={}, 距离={:.2f}".format(closest_color, min_distance))
return closest_color, min_distance
count=0
min_color='red'
min_distance=50
while True: while True:
img = sensor.snapshot() img = sensor.snapshot()
roi = (img.width() // 2, 0, img.width() // 2, img.height()) # 只处理右半部分 # 只处理右半部分
# 查找圆形 roi = (img.width() // 2, 0, img.width() // 2, img.height())
circles = img.find_circles(roi=roi, threshold=2500, x_margin=10, y_margin=10, r_margin=10,
r_min=2, r_max=100, r_step=2) # 在此根据整体亮度简单调参,阈值可自行调整
threshold = max(1000, min(5000, int(img.get_statistics().l_mean() * 50)))
# find_circles 参数可根据实际效果调整
circles = img.find_circles(roi=roi,
threshold=2500,
x_margin=20,
y_margin=20,
r_margin=20,
r_min=15,
r_max=30,
r_step=2)
if circles: if circles:
# 如果有结果,尝试合并到结果缓存 closest_circle = None
closest_distance = float('inf')
closest_color = "未知"
for c in circles: for c in circles:
merge_circles(c, result_cache) area = (c.x() - c.r(), c.y() - c.r(), 2*c.r(), 2*c.r())
lab_val = calculate_lab(area, img)
color_name, distance = determine_color_from_lab(lab_val)
# 找出最小距离(与预设颜色最相似)的那个圆
if distance < closest_distance:
closest_distance = distance
closest_color = color_name
closest_circle = c
if closest_circle is None:
print('没有识别到')
continue
elif closest_distance<20:
area = (closest_circle.x() - closest_circle.r(),
closest_circle.y() - closest_circle.r(),
2*closest_circle.r(), 2*closest_circle.r())
# 画框和画圆
img.draw_rectangle(area, color=(255, 0, 0))
img.draw_circle(closest_circle.x(), closest_circle.y(), closest_circle.r(), color=(255, 0, 0))
print("最终识别到的颜色={}, 距离={:.2f}".format(closest_color, closest_distance))
min_distance=50
print("{}轮检测耗时: {} ms".format(count,time.ticks_diff(time.ticks_ms(), start_time)))
start_time = time.ticks_ms()
count+=1
# 检查是否达到累计条件或超时 else:
current_time = time.ticks_ms() if closest_distance<min_distance:
elapsed_time = time.ticks_diff(current_time, start_time) # 计算耗时 min_color=closest_color
if len(result_cache) >= max_results or elapsed_time > 4000: min_distance=closest_distance
# 找到 LAB 最不一样的圆 if time.ticks_diff(time.ticks_ms(), start_time) > 5000:
farthest_circle, farthest_lab = determine_farthest_circle(result_cache, img) print("最终识别到的颜色={}, 距离={:.2f}".format(min_color, min_distance))
print("{}轮检测耗时: {} ms".format(count,time.ticks_diff(time.ticks_ms(), start_time)))
start_time = time.ticks_ms()
# 绘制并输出结果 min_distance=50
if farthest_circle: count+=1
area = (farthest_circle.x() - farthest_circle.r(), farthest_circle.y() - farthest_circle.r(),
2 * farthest_circle.r(), 2 * farthest_circle.r())
color = determine_color_from_lab(farthest_lab)
if color in ["红色", "黄色", "绿色"]:
img.draw_rectangle(area, color=(255, 255, 255)) # 画圆外接矩形
img.draw_circle(farthest_circle.x(), farthest_circle.y(), farthest_circle.r(), color=(255, 0, 0))
print("颜色倾向: ", color)
current_time = time.ticks_ms()
elapsed_time = time.ticks_diff(current_time, start_time) # 计算耗时
print("保留的圆形数量:", len(result_cache))
print("耗时:", elapsed_time, "ms")
result_cache = [] # 清空缓存
start_time = time.ticks_ms() # 重置开始时间
time.sleep(0.1)
# 主函数调用 # 主函数调用
if __name__ == "__main__": if __name__ == "__main__":

142
002_B_Car/xdl/找圆2.py Normal file
View File

@ -0,0 +1,142 @@
# -*- coding:utf-8 -*-
# @Author len
# @Create 2023/11/30 11:08
import sensor, lcd, time
from machine import Timer, PWM
lcd.init(freq=15000000) # 初始化LCD
sensor.reset() # 复位和初始化摄像头
sensor.set_vflip(1) # 将摄像头设置成后置方式(所见即所得)
sensor.set_pixformat(sensor.RGB565)# 设置像素格式为彩色 RGB565
sensor.set_framesize(sensor.QVGA) # 设置帧大小为 QVGA (320x240)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
sensor.set_auto_gain(0, 0)
sensor.skip_frames(time=200) # 等待设置生效
def draw_circles():
"""
检测并绘制图像中的圆形仅在图像的右半部分进行检测
"""
start_time = time.ticks_ms() # 记录开始时间(毫秒)
def circles_overlap(c1, c2):
"""判断两个圆是否重叠"""
dx = c1.x() - c2.x()
dy = c1.y() - c2.y()
distance = (dx**2 + dy**2)**0.5
return distance < (c1.r() + c2.r())
def merge_circles(new_circle, cache):
"""尝试合并新检测到的圆与缓存中的圆"""
for existing in cache:
if circles_overlap(new_circle, existing):
return False # 如果重叠,不加入新的圆
cache.append(new_circle) # 如果没有重叠,添加到缓存中
return True
def calculate_lab(area, img):
"""计算给定区域的平均 LAB 值"""
stats = img.get_statistics(roi=area)
return stats.l_mean(), stats.a_mean(), stats.b_mean()
def determine_color_from_lab(lab):
"""
返回最接近的颜色以及对应的距离
:param lab: (l, a, b) 三元组
:return: (closest_color, min_distance)
"""
# 你可以根据实际情况添加或修改更多预设颜色及其 LAB
predefined_colors = {
"红色": (50, 38, 1),
"黄色": (86, 2, 27),
"绿色": (75, -29, 15)
}
min_distance = float('inf')
closest_color = "灰色" # 默认或者未匹配时
# 打印一下实际检测到的LAB便于调试
# print("检测到的LAB:", lab)
for color_name, (l_ref, a_ref, b_ref) in predefined_colors.items():
distance = ((lab[0] - l_ref) ** 2 +
(lab[1] - a_ref) ** 2 +
(lab[2] - b_ref) ** 2) ** 0.5
if distance < min_distance:
min_distance = distance
closest_color = color_name
if min_distance < 10:
print("最接近的颜色={}, 距离={:.2f}".format(closest_color, min_distance))
# print("最接近的颜色={}, 距离={:.2f}".format(closest_color, min_distance))
return closest_color, min_distance
count=0
min_color='red'
min_distance=50
while True:
img = sensor.snapshot()
# 只处理右半部分
roi = (img.width() // 2, 0, img.width() // 2, img.height())
# 在此根据整体亮度简单调参,阈值可自行调整
threshold = max(1000, min(5000, int(img.get_statistics().l_mean() * 50)))
# find_circles 参数可根据实际效果调整
circles = img.find_circles(roi=roi,
threshold=2500,
x_margin=20,
y_margin=20,
r_margin=20,
r_min=15,
r_max=30,
r_step=2)
if circles:
closest_circle = None
closest_distance = float('inf')
closest_color = "未知"
for c in circles:
area = (c.x() - c.r(), c.y() - c.r(), 2*c.r(), 2*c.r())
lab_val = calculate_lab(area, img)
color_name, distance = determine_color_from_lab(lab_val)
# 找出最小距离(与预设颜色最相似)的那个圆
if distance < closest_distance:
closest_distance = distance
closest_color = color_name
closest_circle = c
if closest_circle is None:
print('没有识别到')
continue
elif closest_distance<20:
area = (closest_circle.x() - closest_circle.r(),
closest_circle.y() - closest_circle.r(),
2*closest_circle.r(), 2*closest_circle.r())
# 画框和画圆
img.draw_rectangle(area, color=(255, 0, 0))
img.draw_circle(closest_circle.x(), closest_circle.y(), closest_circle.r(), color=(255, 0, 0))
print("最终识别到的颜色={}, 距离={:.2f}".format(closest_color, closest_distance))
min_distance=50
print("{}轮检测耗时: {} ms".format(count,time.ticks_diff(time.ticks_ms(), start_time)))
start_time = time.ticks_ms()
count+=1
else:
if closest_distance<min_distance:
min_color=closest_color
min_distance=closest_distance
if time.ticks_diff(time.ticks_ms(), start_time) > 5000:
print("最终识别到的颜色={}, 距离={:.2f}".format(min_color, min_distance))
print("{}轮检测耗时: {} ms".format(count,time.ticks_diff(time.ticks_ms(), start_time)))
start_time = time.ticks_ms()
min_distance=50
count+=1
# 主函数调用
if __name__ == "__main__":
draw_circles()

View File

@ -141,6 +141,8 @@ class Mainlen():
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565 sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
# sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色 # sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色
sensor.set_framesize(sensor.QVGA) # 设置帧大小为QVGA320×240 sensor.set_framesize(sensor.QVGA) # 设置帧大小为QVGA320×240
# sensor.set_framesize(sensor.FRAME_240X240 ) # 设置帧大小为QVGA320×240
sensor.set_vflip(1) # 后置模式 sensor.set_vflip(1) # 后置模式
sensor.skip_frames(30) # # 跳过前30帧 sensor.skip_frames(30) # # 跳过前30帧
@ -151,6 +153,8 @@ class Mainlen():
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565 sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
# sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色 # sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色
sensor.set_framesize(sensor.QVGA) # 设置帧大小为 QVGA (320x240) sensor.set_framesize(sensor.QVGA) # 设置帧大小为 QVGA (320x240)
# sensor.set_framesize(sensor.FRAME_240X240) # 设置帧大小为 QVGA (320x240)
# sensor.set_windowing((224, 224)) # 设置摄像头的窗口大小 # sensor.set_windowing((224, 224)) # 设置摄像头的窗口大小
sensor.set_auto_gain(False) sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False) sensor.set_auto_whitebal(False)

View File

@ -11,9 +11,10 @@ sensor.set_auto_gain(0,0)
sensor.skip_frames(time = 200) # 等待设置生效 sensor.skip_frames(time = 200) # 等待设置生效
# 阈值设置 # 阈值设置
thresholds = [(35, 100, 6, 127, 0, 127), # 红色阈值 thresholds = [(123, 143, 161, 181, 136, 156), # 红色阈值
(25, 100, -6, 127, 5, 43), # 黄色阈值 (207, 227, 126, 146, 155, 175), # 黄色阈值
(87, 100, -59, 127, -10, 127)] # 绿色阈值 (196, 216, 103, 123, 135, 155)] # 绿色阈值
# while True: # while True:
img = sensor.snapshot() img = sensor.snapshot()

View File

@ -34,9 +34,9 @@ Servo(15)
# (25, 100, -6, 127, 5, 43, "黄色"), # 黄色阈值 # (25, 100, -6, 127, 5, 43, "黄色"), # 黄色阈值
# (52, 100, -128, -5, 5, 127, "绿色")] # 绿色阈值 # (52, 100, -128, -5, 5, 127, "绿色")] # 绿色阈值
thresholds = [(51, 62, 33, 101, 14, 127, "红色"), # 红色阈值 thresholds = [(43, 68, 7, 74, 1, 46, "红色"), # 红色阈值
(39, 98, -17, 21, 17, 57, "黄色"), # 黄色阈值 (48, 100, -23, 19, 4, 55, "黄色"), # 黄色阈值
(44, 90, -61, -13, -3, 30, "绿色")] # 绿色阈值 (40, 93, -57, -7, -8, 29, "绿色")] # 绿色阈值
while True: while True:
img = sensor.snapshot() img = sensor.snapshot()
@ -45,9 +45,9 @@ while True:
max_blob_color = "" max_blob_color = ""
max_blob_color_index = 0 max_blob_color_index = 0
# 找圆 # # 找圆
circles = img.find_circles(threshold=3500, x_margin=10, y_margin=10, r_margin=10, # circles = img.find_circles(threshold=3500, x_margin=10, y_margin=10, r_margin=10,
r_min=2, r_max=100, r_step=2) # r_min=2, r_max=100, r_step=2)
for index, threshold in enumerate(thresholds): for index, threshold in enumerate(thresholds):
# 查找每种颜色的色块 # 查找每种颜色的色块
@ -60,15 +60,17 @@ while True:
max_blob_size = blob.pixels() max_blob_size = blob.pixels()
max_blob_color = threshold[-1] # 颜色标签 max_blob_color = threshold[-1] # 颜色标签
max_blob_color_index = index max_blob_color_index = index
print(circles) # print(circles)
# 画圆 # 画圆
for c in circles: # for c in circles:
area = (c.x() - c.r(), c.y() - c.r(), 2 * c.r(), 2 * c.r()) # area = (c.x() - c.r(), c.y() - c.r(), 2 * c.r(), 2 * c.r())
img.draw_rectangle(area, color=(255, 255, 255)) # img.draw_rectangle(area, color=(255, 255, 255))
# 绘制最大色块的矩形和中心十字,并输出颜色 # 绘制最大色块的矩形和中心十字,并输出颜色
if max_blob: if max_blob:
img.draw_rectangle(max_blob[0:4]) img.draw_rectangle(max_blob[0:4])
img.draw_cross(max_blob[5], max_blob[6]) img.draw_cross(max_blob[5], max_blob[6])
print("最大色块的颜色是:", max_blob_color, max_blob_color_index) print("最大色块的颜色是:", max_blob_color, max_blob_color_index)
else:
print("没有找到色块")
lcd.display(img) lcd.display(img)

View File

@ -22,22 +22,22 @@ def Servo(angle):
S1 = PWM(tim_pwm, freq=50, duty=0, pin=17) S1 = PWM(tim_pwm, freq=50, duty=0, pin=17)
S1.duty((angle+90)/180*10+2.5) S1.duty((angle+90)/180*10+2.5)
Servo(15) # Servo(15)
# 摄像头初始化 # 摄像头初始化
sensor.reset() sensor.reset()
sensor.set_pixformat(sensor.RGB565) sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(40)
sensor.set_vflip(1) # 摄像头后置方式 sensor.set_vflip(1) # 摄像头后置方式
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565 sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
#sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色 #sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色
sensor.set_framesize(sensor.QVGA) # 设置帧大小为 QVGA (320x240)
sensor.set_auto_gain(False) sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False) sensor.set_auto_whitebal(False)
sensor.set_auto_gain(0,0) sensor.set_auto_gain(0,0)
lcd.init() # LCD初始化 # lcd.init() # LCD初始化
# 初始化 BOOT 键 # 初始化 BOOT 键
boot_pin = 16 # 根据您的板子修改对应的引脚号 boot_pin = 16 # 根据您的板子修改对应的引脚号
@ -51,35 +51,7 @@ taking_pictures = False
count = 0 count = 0
while(True): while(True):
img = sensor.snapshot() sensor.snapshot().save("/sd/imgs/{}.jpg".format(count))
# 检查 BOOT 键是否被按下
if key.value() == 0:
# 等待按键释放
while key.value() == 0:
time.sleep_ms(20)
# 改变拍照状态
taking_pictures = not taking_pictures
if taking_pictures:
print("Start taking pictures")
else:
print("Stop taking pictures")
# 根据拍照状态决定是否保存图片
if taking_pictures:
img = img.resize(224, 224)
image_save = "/sd/img/example{}.jpg".format(count)
img.save(image_save)
print("Image saved:", image_save)
count+=1 count+=1
a = lcd.display(img) print(count)
time.sleep_ms(100)
else:
a = lcd.display(img)
# 打印FPS
print(clock.fps())
# 稍作延迟,避免过快的循环
time.sleep_ms(20)

View File

@ -6,28 +6,57 @@ import cv2
import numpy as np import numpy as np
# 读取图像 # 读取图像
image_path = 'xdl/1.png' # 请替换为您图像的实际路径 image_path =r"E:\imgs\4.jpg"
image_bgr = cv2.imread(image_path) image_bgr = cv2.imread(image_path)
# 全局变量
roi = []
drawing = False
def draw_rectangle(event, x, y, flags, param):
global roi, drawing, image_bgr_copy
if event == cv2.EVENT_LBUTTONDOWN:
roi = [(x, y)]
drawing = True
elif event == cv2.EVENT_MOUSEMOVE:
if drawing:
image_bgr_copy = image_bgr.copy()
cv2.rectangle(image_bgr_copy, roi[0], (x, y), (0, 0, 255), 2)
cv2.imshow('Select ROI', image_bgr_copy)
elif event == cv2.EVENT_LBUTTONUP:
roi.append((x, y))
drawing = False
cv2.rectangle(image_bgr, roi[0], roi[1], (0, 0, 255), 2)
cv2.imshow('Select ROI', image_bgr)
# 检查图像是否成功加载 # 检查图像是否成功加载
if image_bgr is not None: if image_bgr is not None:
# 将图像从 BGR 颜色空间转换到 LAB 颜色空间 image_bgr_copy = image_bgr.copy()
cv2.imshow('Select ROI', image_bgr_copy)
cv2.setMouseCallback('Select ROI', draw_rectangle)
while True:
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
cv2.destroyAllWindows()
if len(roi) == 2:
x1, y1 = roi[0]
x2, y2 = roi[1]
x, y, w, h = min(x1, x2), min(y1, y2), abs(x2 - x1), abs(y2 - y1)
# 转换到 LAB 颜色空间
image_lab = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2LAB) image_lab = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2LAB)
# 定义红框区域的坐标 (x, y, width, height)
# 请用实际的红框坐标替换
x, y, w, h = 280, 340, 60, 60 # 替换为红框的实际坐标
# 裁剪 LAB 图像以获取红框内的区域
cropped_lab = image_lab[y:y+h, x:x+w] cropped_lab = image_lab[y:y+h, x:x+w]
# 计算裁剪区域的平均 LAB 值 # 计算裁剪区域的 LAB 颜色阈值下界和上界
avg_lab = np.mean(cropped_lab.reshape(-1, 3), axis=0) lower_red_threshold = np.min(cropped_lab.reshape(-1, 3), axis=0)
upper_red_threshold = np.max(cropped_lab.reshape(-1, 3), axis=0)
# 定义阈值范围
threshold_range = 10
lower_red_threshold = np.clip(avg_lab - threshold_range, 0, 255)
upper_red_threshold = np.clip(avg_lab + threshold_range, 0, 255)
# 输出红色 LAB 颜色阈值 # 输出红色 LAB 颜色阈值
lower = lower_red_threshold.astype(int) lower = lower_red_threshold.astype(int)
@ -36,15 +65,9 @@ if image_bgr is not None:
print('红色的 LAB 颜色阈值上界:', upper) print('红色的 LAB 颜色阈值上界:', upper)
print("{}, {}, {}, {}, {}, {}".format(lower[0], upper[0], lower[1], upper[1], lower[2], upper[2])) print("{}, {}, {}, {}, {}, {}".format(lower[0], upper[0], lower[1], upper[1], lower[2], upper[2]))
# 在原图像上绘制红框
cv2.rectangle(image_bgr, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 显示图像
cv2.imshow('Image with Red Rectangle', image_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存处理后的图像 # 保存处理后的图像
cv2.imwrite("image_with_red_rectangle.jpg", image_bgr) cv2.imwrite("image_with_red_rectangle.jpg", image_bgr)
else:
print("未正确标注区域。")
else: else:
print("图像无法加载。") print("图像无法加载。")

View File

@ -28,9 +28,9 @@ clock=time.clock()
# thresholds = [(59, 100, 40, 127, 5, 127), # 红色阈值 # thresholds = [(59, 100, 40, 127, 5, 127), # 红色阈值
# (87, 100, -59, 127, -10, 127), # 绿色阈值 # (87, 100, -59, 127, -10, 127), # 绿色阈值
# (0, 30, 0, 64, -128, -20)] # 蓝色阈值 # (0, 30, 0, 64, -128, -20)] # 蓝色阈值
thresholds = [(35, 100, 6, 127, 0, 127), # 红色阈值 thresholds = [(123, 143, 161, 181, 136, 156), # 红色阈值
(25, 100, -6, 127, 5, 43), # 黄色阈值 (207, 227, 126, 146, 155, 175), # 黄色阈值
(87, 100, -59, 127, -10, 127)] # 绿色阈值 (196, 216, 103, 123, 135, 155)] # 绿色阈值
while True: while True:

View File

@ -1,102 +1,91 @@
# -*- coding:utf-8 -*-
# @Author len
# @Create 2023/10/26 9:18
from PIL import Image from PIL import Image
import numpy as np import numpy as np
import os import os
def convert_jpg_to_bin(input_file, output_file, max_width, max_height): def convert_jpg_to_bin(input_file, output_file):
# 打开JPEG图像
image = Image.open(input_file)
print(f"Processing: {input_file}") print(f"Processing: {input_file}")
# 打开已经调整尺寸并转换为 JPEG 的图像
image = Image.open(input_file).convert("RGB")
# 限制图像尺寸 # 转换为 NumPy 数组
image.thumbnail((max_width, max_height)) img_array = np.array(image, dtype=np.uint16)
r = img_array[:, :, 0]
g = img_array[:, :, 1]
b = img_array[:, :, 2]
# 将图像转换为RGB模式 # 计算 RGB565 格式的值
image = image.convert("RGB") rgb565 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
# 创建一个空白的16位彩色图像 # 展平数组并保存为 BIN 文件
result_image = np.zeros((image.size[1], image.size[0]), dtype=np.uint16) rgb565.flatten().tofile(output_file)
# 遍历图像的每个像素 def prepare_image(input_path, temp_dir, target_width, target_height):
for y in range(image.size[1]): """
for x in range(image.size[0]): 先调整图片尺寸保持原始比例然后将缩放后的图片粘贴到固定尺寸的画布上
# 获取RGB值 最终保存为 JPEG 格式确保输出尺寸为 target_width x target_height
r, g, b = image.getpixel((x, y)) """
# 将RGB值转换为RGB565格式
pixel_value = ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3)
# 将RGB565值存储到16位彩色图像中
result_image[y, x] = pixel_value
# 将三维数组展平为一维数组
flattened_array = result_image.flatten()
# 保存为BIN文件
with open(output_file, "wb") as file:
file.write(flattened_array.tobytes())
def ensure_jpg_format(input_path, temp_dir):
# 确保文件是JPEG格式如果不是则转换为JPEG
with Image.open(input_path) as img: with Image.open(input_path) as img:
if img.format != "JPEG": img = img.convert("RGB")
# 按比例缩放,使图片适应目标尺寸,但不会超出目标尺寸
img.thumbnail((target_width, target_height))
# 创建一个新的目标尺寸图像,背景填充黑色(可以根据需要修改背景色)
new_img = Image.new("RGB", (target_width, target_height), (0, 0, 0))
# 计算居中粘贴的位置
left = (target_width - img.width) // 2
top = (target_height - img.height) // 2
new_img.paste(img, (left, top))
base_name = os.path.splitext(os.path.basename(input_path))[0] base_name = os.path.splitext(os.path.basename(input_path))[0]
jpg_path = os.path.join(temp_dir, f"{base_name}.jpg") jpg_path = os.path.join(temp_dir, f"{base_name}.jpg")
img = img.convert("RGB") # 转换为RGB模式 new_img.save(jpg_path, "JPEG")
img.save(jpg_path, "JPEG") print(f"Converted, resized and padded to JPEG: {jpg_path}")
print(f"Converted to JPEG: {jpg_path}")
return jpg_path return jpg_path
return input_path
def get_sort_key(filename): def get_sort_key(filename):
# 提取文件名前两位数字用于排序
base_name = os.path.splitext(filename)[0] base_name = os.path.splitext(filename)[0]
try: try:
# 尝试将前两位数字转换为整数
return int(base_name[:2]) return int(base_name[:2])
except ValueError: except ValueError:
# 如果无法转换为数字,则返回一个较大的默认值
return float('inf') return float('inf')
# 使用示例 def main():
input_file = r"C:\Users\10561\Desktop\002\任务2" # 图片地址 input_dir = r"C:\Users\10561\Desktop\20250221\tft图片" # 图片目录
temp_dir = os.path.join(input_file, "temp") # 临时目录 temp_dir = os.path.join(input_dir, "temp") # 临时目录
output_dir = os.path.join(input_file, "bin") # 输出目录 output_dir = os.path.join(input_dir, "bin") # 输出目录
os.makedirs(temp_dir, exist_ok=True) # 创建临时目录 os.makedirs(temp_dir, exist_ok=True)
os.makedirs(output_dir, exist_ok=True) # 创建输出目录 os.makedirs(output_dir, exist_ok=True)
max_width = 800 target_width, target_height = 800, 480
max_height = 480
# 获取文件列表并忽略目录,同时按照前两位数字排序 # 获取所有文件,并按照文件名前两位数字排序
files = sorted( files = sorted(
[file for file in os.listdir(input_file) if os.path.isfile(os.path.join(input_file, file))], [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))],
key=get_sort_key key=get_sort_key
) )
for file in files: for file in files:
print(file)
if file in ["System Volume Information"] or ".bin" in file: if file in ["System Volume Information"] or ".bin" in file:
continue continue
portion = os.path.splitext(file) file_base = os.path.splitext(file)[0]
input001 = os.path.join(input_file, file) input_path = os.path.join(input_dir, file)
# 确保输入文件是JPEG格式 # 调整尺寸、填充背景并转换为 JPEG
jpg_file = ensure_jpg_format(input001, temp_dir) jpg_file = prepare_image(input_path, temp_dir, target_width, target_height)
# 生成输出文件路径 # 生成输出 BIN 文件路径
out001 = os.path.join(output_dir, f"{portion[0]}.bin") output_file = os.path.join(output_dir, f"{file_base}.bin")
print(f"Output BIN: {out001}") print(f"Output BIN: {output_file}")
# 转换为 BIN 文件 # 转换为 BIN 文件
convert_jpg_to_bin(jpg_file, out001, max_width, max_height) convert_jpg_to_bin(jpg_file, output_file)
# 清理临时目录 # 如有需要,可清理临时目录
for temp_file in os.listdir(temp_dir): # for temp_file in os.listdir(temp_dir):
os.remove(os.path.join(temp_dir, temp_file)) # os.remove(os.path.join(temp_dir, temp_file))
os.rmdir(temp_dir) # os.rmdir(temp_dir)
if __name__ == '__main__':
main()

154
txt2xml.py Normal file
View File

@ -0,0 +1,154 @@
import os
import xml.etree.ElementTree as ET
from xml.dom import minidom
from PIL import Image
def convert_txt_to_xml(txt_path, image_path, xml_path):
# 打开图像,获取尺寸及通道数
with Image.open(image_path) as img:
img_width, img_height = img.size
mode = img.mode
if mode == "RGB":
depth = 3
elif mode == "L":
depth = 1
else:
depth = 3 # 默认3
# 读取TXT文件中的标注信息
with open(txt_path, "r") as f:
lines = f.readlines()
# 类别编号到标签名称的映射
id_to_label = {
0: "light",
1: "red",
2: "yellow",
3: "green"
}
# 构建XML结构
annotation = ET.Element("annotation", verified="yes")
folder_elem = ET.SubElement(annotation, "folder")
folder_elem.text = os.path.basename(os.path.dirname(image_path))
filename_elem = ET.SubElement(annotation, "filename")
image_filename = os.path.basename(image_path)
filename_elem.text = image_filename
path_elem = ET.SubElement(annotation, "path")
path_elem.text = os.path.abspath(image_path)
source_elem = ET.SubElement(annotation, "source")
database_elem = ET.SubElement(source_elem, "database")
database_elem.text = "Unknown"
size_elem = ET.SubElement(annotation, "size")
width_elem = ET.SubElement(size_elem, "width")
width_elem.text = str(img_width)
height_elem = ET.SubElement(size_elem, "height")
height_elem.text = str(img_height)
depth_elem = ET.SubElement(size_elem, "depth")
depth_elem.text = str(depth)
segmented_elem = ET.SubElement(annotation, "segmented")
segmented_elem.text = "0"
# 逐行处理TXT标注
for line in lines:
parts = line.strip().split()
if len(parts) != 5:
print(f"跳过格式不正确的行: {line.strip()}")
continue
class_id_str, x_center_norm_str, y_center_norm_str, width_norm_str, height_norm_str = parts
try:
class_id = int(class_id_str)
x_center_norm = float(x_center_norm_str)
y_center_norm = float(y_center_norm_str)
width_norm = float(width_norm_str)
height_norm = float(height_norm_str)
except Exception as e:
print(f"转换数据出错 {line.strip()}: {e}")
continue
if class_id not in id_to_label:
print(f"未知标签编号 {class_id},跳过该行")
continue
label = id_to_label[class_id]
# 计算绝对坐标
x_center = x_center_norm * img_width
y_center = y_center_norm * img_height
bbox_width = width_norm * img_width
bbox_height = height_norm * img_height
xmin = int(x_center - bbox_width / 2)
ymin = int(y_center - bbox_height / 2)
xmax = int(x_center + bbox_width / 2)
ymax = int(y_center + bbox_height / 2)
# 构建object节点
object_elem = ET.SubElement(annotation, "object")
name_elem = ET.SubElement(object_elem, "name")
name_elem.text = label
pose_elem = ET.SubElement(object_elem, "pose")
pose_elem.text = "Unspecified"
truncated_elem = ET.SubElement(object_elem, "truncated")
truncated_elem.text = "0"
difficult_elem = ET.SubElement(object_elem, "difficult")
difficult_elem.text = "0"
bndbox_elem = ET.SubElement(object_elem, "bndbox")
xmin_elem = ET.SubElement(bndbox_elem, "xmin")
xmin_elem.text = str(xmin)
ymin_elem = ET.SubElement(bndbox_elem, "ymin")
ymin_elem.text = str(ymin)
xmax_elem = ET.SubElement(bndbox_elem, "xmax")
xmax_elem.text = str(xmax)
ymax_elem = ET.SubElement(bndbox_elem, "ymax")
ymax_elem.text = str(ymax)
# 美化输出的XML字符串
xml_str = ET.tostring(annotation, encoding="utf-8")
parsed_str = minidom.parseString(xml_str)
pretty_xml_str = parsed_str.toprettyxml(indent=" ")
with open(xml_path, "w", encoding="utf-8") as f:
f.write(pretty_xml_str)
def batch_convert_txt_to_xml(txt_dir, image_dir, output_dir, image_ext=".jpg"):
"""
批量将TXT转换为XML
txt_dir: TXT文件所在目录
image_dir: 对应图像所在目录图片文件名与TXT同名后缀可指定
output_dir: XML文件保存目录
image_ext: 图像文件扩展名默认 .jpg
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for file in os.listdir(txt_dir):
if file.lower().endswith(".txt"):
txt_path = os.path.join(txt_dir, file)
base_name = os.path.splitext(file)[0]
image_filename = base_name + image_ext
image_path = os.path.join(image_dir, image_filename)
if not os.path.exists(image_path):
print(f"图像文件不存在: {image_path},跳过 {txt_path}")
continue
xml_filename = base_name + ".xml"
xml_path = os.path.join(output_dir, xml_filename)
try:
convert_txt_to_xml(txt_path, image_path, xml_path)
print(f"成功转换: {txt_path} --> {xml_path}")
except Exception as e:
print(f"处理 {txt_path} 时出错: {e}")
if __name__ == "__main__":
# 请修改以下目录为实际路径
txt_directory = "path_to_txt_directory" # TXT文件所在目录
image_directory = "path_to_image_directory" # 图像文件所在目录
output_directory = "path_to_output_xml_directory" # 输出XML文件保存目录
batch_convert_txt_to_xml(txt_directory, image_directory, output_directory, image_ext=".jpg")

82
xml2txt.py Normal file
View File

@ -0,0 +1,82 @@
import os
import xml.etree.ElementTree as ET
def convert_xml_to_txt(xml_path, txt_path):
# 解析XML文件
tree = ET.parse(xml_path)
root = tree.getroot()
# 获取图像尺寸信息
size = root.find("size")
img_width = int(size.find("width").text)
img_height = int(size.find("height").text)
# 标签映射字典
label_mapping = {
"light": 0,
"red": 1,
"yellow": 2,
"green": 3
}
lines = []
# 遍历每个object节点
for obj in root.findall("object"):
# 获取并转换标签名称,统一转为小写
class_name = obj.find("name").text.strip().lower()
if class_name in label_mapping:
class_id = label_mapping[class_name]
else:
print(f"未知标签 {class_name},文件 {xml_path} 中跳过该对象")
continue
# 获取边界框坐标
bndbox = obj.find("bndbox")
xmin = float(bndbox.find("xmin").text)
ymin = float(bndbox.find("ymin").text)
xmax = float(bndbox.find("xmax").text)
ymax = float(bndbox.find("ymax").text)
# 计算边界框中心点和宽高
x_center = (xmin + xmax) / 2.0
y_center = (ymin + ymax) / 2.0
bbox_width = xmax - xmin
bbox_height = ymax - ymin
# 归一化
x_center_norm = x_center / img_width
y_center_norm = y_center / img_height
width_norm = bbox_width / img_width
height_norm = bbox_height / img_height
# 每行格式:类别编号 x_center y_center width height
line = f"{class_id} {x_center_norm:.6f} {y_center_norm:.6f} {width_norm:.6f} {height_norm:.6f}"
lines.append(line)
# 将转换结果写入TXT文件
with open(txt_path, "w") as f:
for line in lines:
f.write(line + "\n")
def batch_convert_xml_to_txt(input_dir, output_dir):
# 如果输出目录不存在则创建
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 遍历输入目录下所有XML文件
for file in os.listdir(input_dir):
if file.lower().endswith(".xml"):
xml_path = os.path.join(input_dir, file)
txt_file = os.path.splitext(file)[0] + ".txt"
txt_path = os.path.join(output_dir, txt_file)
try:
convert_xml_to_txt(xml_path, txt_path)
print(f"成功转换: {xml_path} --> {txt_path}")
except Exception as e:
print(f"处理 {xml_path} 时出错: {e}")
if __name__ == "__main__":
# 请替换下面的目录为实际路径
input_directory = r"C:\Users\10561\Downloads\Compressed\xml" # XML文件所在的目录
output_directory = r"C:\Users\10561\Downloads\Compressed\txt" # 转换后txt文件保存的目录
batch_convert_xml_to_txt(input_directory, output_directory)

51
xml删除标签.py Normal file
View File

@ -0,0 +1,51 @@
import os
import xml.etree.ElementTree as ET
def remove_tag_from_element(element, tag):
"""
递归遍历element的所有子节点删除所有匹配指定标签的子节点
"""
for child in list(element): # 用 list() 避免在遍历时修改子节点列表导致问题
if child.tag == tag:
element.remove(child)
else:
remove_tag_from_element(child, tag)
def remove_tag_from_xml(xml_file, tag_to_remove, output_file):
"""
解析单个 XML 文件删除其中所有指定的标签然后保存为新的 XML 文件
"""
try:
tree = ET.parse(xml_file)
root = tree.getroot()
# 如果根节点本身就是要删除的标签,则提示并跳过处理
if root.tag == tag_to_remove:
print(f"警告:{xml_file} 的根标签就是要删除的标签({tag_to_remove}),跳过该文件。")
return
remove_tag_from_element(root, tag_to_remove)
tree.write(output_file, encoding="utf-8", xml_declaration=True)
print(f"处理完成: {xml_file} -> {output_file}")
except Exception as e:
print(f"处理 {xml_file} 时出错: {e}")
def batch_remove_tag(input_dir, output_dir, tag_to_remove):
"""
批量处理遍历 input_dir 下所有 XML 文件删除指定标签后将新文件保存到 output_dir
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for file in os.listdir(input_dir):
if file.lower().endswith(".xml"):
input_path = os.path.join(input_dir, file)
output_path = os.path.join(output_dir, file)
remove_tag_from_xml(input_path, tag_to_remove, output_path)
if __name__ == "__main__":
# 请修改以下路径和要删除的标签名称
input_directory = r"C:\Users\10561\Downloads\Compressed\xml" # 输入 XML 文件所在目录
output_directory = "path_to_output_xml_directory" # 处理后 XML 文件保存目录
tag_to_delete = "segmented" # 例如:删除 <segmented> 标签,可改为你需要删除的标签名
batch_remove_tag(input_directory, output_directory, tag_to_delete)

20
图片分批.py Normal file
View File

@ -0,0 +1,20 @@
import os
if __name__ == '__main__':
dir_path=r"C:\Users\10561\Desktop\frames-3000"
output_dir=r"C:\Users\10561\Desktop\frames-3000-批次"
if not os.path.exists(output_dir):
os.mkdir(output_dir)
images=os.listdir(dir_path)
images=[os.path.join(dir_path,i) for i in images]
for i in range(len(images)//100):
out=os.path.join(output_dir,f"{i}")
os.mkdir(out)
if i == len(images)//100:
#复制
for j in range(i*100,len(images)):
os.system(f"copy {images[j]} {out}")
else:
for j in range(i*100,(i+1)*100):
os.system(f"copy {images[j]} {out}")

21
图片尺寸检查.py Normal file
View File

@ -0,0 +1,21 @@
import os
from PIL import Image
# 指定要检查的目录路径
directory = r"C:\Users\10561\Downloads\Compressed\images" # 替换为你的目录路径
# 目标尺寸
target_size = (224, 224)
# 遍历目录中的所有文件
for filename in os.listdir(directory):
# 只处理图片文件(根据文件后缀判断)
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
file_path = os.path.join(directory, filename)
try:
with Image.open(file_path) as img:
# 检查图片尺寸是否与目标尺寸不一致
if img.size != target_size:
print(f"{filename}: {img.size}")
except Exception as e:
print(f"处理 {filename} 时出错: {e}")

View File

@ -38,8 +38,8 @@ def extract_frames(video_path, output_dir, interval=0.5,output_name='frame'):
cap.release() cap.release()
print(f"共保存了 {saved_count} 帧.") print(f"共保存了 {saved_count} 帧.")
video_dir=r'C:\Users\10561\Desktop\bcar红绿灯\1' video_dir=r'C:\Users\10561\Desktop\bcar红绿灯\3'
output_directory = r"C:\Users\10561\Desktop\frames" # 替换为你希望保存的目录路径 output_directory = r"C:\Users\10561\Desktop\frames123" # 替换为你希望保存的目录路径
for file in os.listdir(video_dir): for file in os.listdir(video_dir):
if file.endswith('.mp4'): if file.endswith('.mp4'):