開發平台

win10系統

ESP-IDF(5.2.6)版本

ESP32S3

部署過程

一在樂鑫科技的官網下載ESP-IDF。

我下載的版本是離線安裝5.2.6的版本,然後直接安裝到D盤的根目錄下,安裝過程一切順利,沒有遇到問題。

下載好之後桌面上就會出現ESP-IDF5.2的命令窗口

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_3d

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_工程文件_02

二在GitHub上下載NCNN        git clone https://github.com/Tencent/ncnn.git

並且將NCNN的文件夾拷貝到ESP-IDF-V5.2.6的文件夾下,這樣方便它們交叉編譯。如果git clone命令用不了,直接去github官網下載NCNN解壓縮也是可以的。

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_3d_03

三交叉編譯

在ncnn文件下創建一個文件夾,名字為build-s3,用於存放交叉編譯後的NCNN庫

在ncnn文件夾下的toolchains文件夾裏創建一個cmake源文件,名字為:esp32s3.toolchain。源文件內容如下:

set(CMAKE_SYSTEM_NAME freertos)
set(CMAKE_SYSTEM_PROCESSOR xtensa-esp32s3)

include($ENV{IDF_PATH}/tools/cmake/toolchain-esp32s3.cmake)

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")

option(NCNN_INSTALL_SDK "" ON)
option(NCNN_PIXEL_ROTATE "" OFF)
option(NCNN_PIXEL_AFFINE "" OFF)
option(NCNN_PIXEL_DRAWING "" OFF)
option(NCNN_BUILD_BENCHMARK "" OFF)
option(NCNN_BUILD_TESTS "" OFF)
option(NCNN_BUILD_TOOLS "" OFF)
option(NCNN_BUILD_EXAMPLES "" OFF)
option(NCNN_DISABLE_RTTI "" ON)
option(NCNN_DISABLE_EXCEPTION "" ON)
option(NCNN_DISABLE_PIC "" ON)
option(NCNN_BF16 "" OFF)
option(NCNN_INT8 "" OFF)
option(NCNN_THREADS "" OFF)
option(NCNN_OPENMP "" OFF)
option(NCNN_STDIO "" OFF)
option(NCNN_STRING "" OFF)
option(NCNN_PLATFORM_API "" OFF)
option(NCNN_RUNTIME_CPU "" OFF)

option(WITH_LAYER_absval "" OFF)
option(WITH_LAYER_argmax "" OFF)
option(WITH_LAYER_batchnorm "" OFF)
option(WITH_LAYER_bias "" OFF)
option(WITH_LAYER_bnll "" OFF)
option(WITH_LAYER_concat "" OFF)
option(WITH_LAYER_convolution "" ON)
option(WITH_LAYER_crop "" OFF)
option(WITH_LAYER_deconvolution "" OFF)
option(WITH_LAYER_dropout "" OFF)
option(WITH_LAYER_eltwise "" OFF)
option(WITH_LAYER_elu "" OFF)
option(WITH_LAYER_embed "" OFF)
option(WITH_LAYER_exp "" OFF)
option(WITH_LAYER_flatten "" ON)
option(WITH_LAYER_innerproduct "" ON)
option(WITH_LAYER_input "" ON)
option(WITH_LAYER_log "" OFF)
option(WITH_LAYER_lrn "" OFF)
option(WITH_LAYER_memorydata "" ON)
option(WITH_LAYER_mvn "" OFF)
option(WITH_LAYER_pooling "" ON)
option(WITH_LAYER_power "" OFF)
option(WITH_LAYER_prelu "" OFF)
option(WITH_LAYER_proposal "" OFF)
option(WITH_LAYER_reduction "" OFF)
option(WITH_LAYER_relu "" ON)
option(WITH_LAYER_reshape "" ON)
option(WITH_LAYER_roipooling "" OFF)
option(WITH_LAYER_scale "" OFF)
option(WITH_LAYER_sigmoid "" OFF)
option(WITH_LAYER_slice "" OFF)
option(WITH_LAYER_softmax "" OFF)
option(WITH_LAYER_split "" ON)
option(WITH_LAYER_spp "" OFF)
option(WITH_LAYER_tanh "" OFF)
option(WITH_LAYER_threshold "" OFF)
option(WITH_LAYER_tile "" OFF)
option(WITH_LAYER_rnn "" OFF)
option(WITH_LAYER_lstm "" OFF)
option(WITH_LAYER_binaryop "" ON)
option(WITH_LAYER_unaryop "" OFF)
option(WITH_LAYER_convolutiondepthwise "" OFF)
option(WITH_LAYER_padding "" ON)
option(WITH_LAYER_squeeze "" OFF)
option(WITH_LAYER_expanddims "" OFF)
option(WITH_LAYER_normalize "" OFF)
option(WITH_LAYER_permute "" OFF)
option(WITH_LAYER_priorbox "" OFF)
option(WITH_LAYER_detectionoutput "" OFF)
option(WITH_LAYER_interp "" OFF)
option(WITH_LAYER_deconvolutiondepthwise "" OFF)
option(WITH_LAYER_shufflechannel "" OFF)
option(WITH_LAYER_instancenorm "" OFF)
option(WITH_LAYER_clip "" OFF)
option(WITH_LAYER_reorg "" OFF)
option(WITH_LAYER_yolodetectionoutput "" OFF)
option(WITH_LAYER_quantize "" OFF)
option(WITH_LAYER_dequantize "" OFF)
option(WITH_LAYER_yolov3detectionoutput "" OFF)
option(WITH_LAYER_psroipooling "" OFF)
option(WITH_LAYER_roialign "" OFF)
option(WITH_LAYER_packing "" ON)
option(WITH_LAYER_requantize "" OFF)
option(WITH_LAYER_cast "" ON)
option(WITH_LAYER_hardsigmoid "" OFF)
option(WITH_LAYER_selu "" OFF)
option(WITH_LAYER_hardswish "" OFF)
option(WITH_LAYER_noop "" OFF)
option(WITH_LAYER_pixelshuffle "" OFF)
option(WITH_LAYER_deepcopy "" OFF)
option(WITH_LAYER_mish "" OFF)
option(WITH_LAYER_statisticspooling "" OFF)
option(WITH_LAYER_swish "" OFF)
option(WITH_LAYER_gemm "" ON)
option(WITH_LAYER_groupnorm "" OFF)
option(WITH_LAYER_layernorm "" OFF)
option(WITH_LAYER_softplus "" OFF)
option(WITH_LAYER_gru "" OFF)
option(WITH_LAYER_multiheadattention "" OFF)
option(WITH_LAYER_gelu "" OFF)
option(WITH_LAYER_convolution1d "" OFF)
option(WITH_LAYER_pooling1d "" OFF)
option(WITH_LAYER_convolutiondepthwise1d "" OFF)
option(WITH_LAYER_convolution3d "" OFF)
option(WITH_LAYER_convolutiondepthwise3d "" OFF)
option(WITH_LAYER_pooling3d "" OFF)
option(WITH_LAYER_matmul "" OFF)
option(WITH_LAYER_deconvolution1d "" OFF)
option(WITH_LAYER_deconvolutiondepthwise1d "" OFF)
option(WITH_LAYER_deconvolution3d "" OFF)
option(WITH_LAYER_deconvolutiondepthwise3d "" OFF)

# cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/esp32s3.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..

打開ESP-IDF的CMD,用cd命令移動到剛剛創建的build-s3文件夾下,執行交叉編譯的命令

cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/esp32s3.toolchain.cmake -DCMAKE_BUILD_TYPE=Release  -G"Unix Makefiles" ..
make -j4
make install

從這一步我就遇到問題了

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_3d_04

問題提示是CMake錯誤,不能生成Unix Makefiles,然後我的解決方法是將cmake工具換成ninja,成功解決這個問題,並且交叉編譯出來的NCNN庫也可以用

cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/esp32s3.toolchain.cmake -DCMAKE_BUILD_TYPE=Release  -G"Ninja" ..
ninja -j4
ninja install

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_#新人首發_05

出現上面這個就算是成功了,build-s3文件夾裏會出現install的文件夾,將這個文件夾改名為ncnn,這就是我們後面要用的ncnn庫

將這個工程文件解壓後拷貝到esp-idf-v5.2.6文件夾下,然後將剛剛編譯的ncnn庫替換工程文件裏的ncnn庫

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_#新人首發_06

這個工程文件是不能直接用的,要修改一下,修改裏面的CMakeLists.txt文件,注意要把第五行的ncnn路徑改成自己的路徑

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_#新人首發_07

然後在ESP-IDF的CMD裏面用cd命令移動到ncnn_on_esp32-master目錄下執行以下命令

將目標板卡設置為esp32s3

idf.py set-target esp32s3

編譯工程文件

idf.py build

將編譯的工程文件燒錄到esp32s3單片機,如果燒錄不進去建議多試幾次,或者將單片機與電腦斷開在連接多試試。

idf.py flash

監視串口輸出

idf.py monitor

我用nihui大佬的main.cpp文件監視串口輸出就出問題了,如下圖所示,命令行一直彈出這個錯誤,具體什麼原因我也不太清楚,如果有大佬知道這是什麼原因,歡迎指導,然後我就抱着試一試的心態,將東哥aigc的工程文件裏的main.cpp文件替換nihui大佬裏的main.cpp,然後就成功。

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_交叉編譯_08

這個是成功的輸出:

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_#新人首發_09

如果想試一下別的數字能不能識別,可以去網上找不同數字的mnist數據集圖片,然後運行image文件夾下的img2c.py將要識別的數字圖片生成二進制權重文件fs.h,然後替換main文件夾下的fs.h文件,然後我運行img2c.py又遇到了問題,

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_工程文件_10

由問題可以看出sys.argv[1]這個數組超過了指標,意思就是説sys.argv[]裏只有一個元素,然後我用print函數打印

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_交叉編譯_11

發現sys.argv[0]是img2c.py這個文件,然後我又查了一下cv2.imread函數如何使用,然後我就直接把圖片的文件名放入函數,然後就成功了,然後就可以改變fs.h文件識別不同的數字了。

深度學習——CNN實現MNIST手寫數字的識別_mnist手寫數字識別_#新人首發_12