

我覺得一開始就得放一下這個圖

這個是一些相關的特性,就是沾ESP32芯片的光了。

忘了說這個東西10g可以上飛機,就是這個處理速度實在拉胯
這里放一些更加細致的資料

這個幀率吧太小了,沒有實際的應用價值我覺得

相關相機的管腳定義

這個最小的系統圖,沒有什么作用。就看看管腳算了

這個是帶彩的定義圖

因為我直接加錢把下面的串口芯片也買了,文章里面就不出現用
TTL轉串口下載程序的步驟了

這個是我們的主角

合體的樣子

如果你要是用TTL下載,記得短接IO0+GND
http://arduino.esp8266.com/stable/package_esp8266com_index.jsonhttp://digistump.com/package_digistump_index.jsonhttps://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.jsonhttp://digistump.com/package_digistump_index.jsonhttps://dl.espressif.com/dl/package_esp32_index.json

點擊安裝,先配置一下arduino的環境

選擇這個 安可信的模組

選好的樣子

這里打開今天的demo

注意把別的模組注釋掉,打開安可信

然后波特率,選擇115200
稍微等一下,出現IP

在瀏覽器內打開

串口會輸出傳輸的信息

既然是網頁端,那開發工具不能少
https://github.com/espressif/arduino-esp32

我們去GitHub下載庫

解壓把剩下的輸出,就留庫

我們用code打開

因為圖像的傳輸起來占帶寬很大,所以需要緩沖區這種設計
PSRAM:pseudo SRAM,偽SRAM。它具有類SRAM的接口協議:給出地址、讀、寫命令,就可以實現存取,不像DRAM需要memory controller來控制內存單元定期數據刷新,因此結口簡單;但它的內核是DRAM架構:1T1C一個晶體管一個電容構成存儲cell,而傳統SRAM需要6T即六個晶體管構成一個存儲cell。由此結合,他可以實現類SRAM的接口有可實現較大的存儲容量。(我們都知道大容量SRAM非常貴)
早期的PSRAM制造商包括Samsung、Micron等巨頭,廣泛用于最早期的智能手機。那時候的手機內存有192MB、384MB等現在看起來非常小的容量。但很快,就進入到LPDDR1、LPDDR2、LPDDR3到如今的LPDDR4.
然而,PSRAM如今仍然在大規模的使用,只是一般人不知道、看不見而已:在M、S、R三大2G base band芯片供應商里,都集成有32MB的PSRAM,只不過他們都是以SiP的形式出現,封在芯片里面你看不見。
物聯網時代,賦予了PSRAM新的活力,尤其在語音交互領域,PSRAM以其小封裝、大容量、低成本,開始顯露器獨特優勢。
在一些智能語音交互的場合,有些語音數據來自云端,pSRAM能很好的提供數據緩沖作用,解決網絡數據的不穩定問題,以提供穩定、平滑的語音服務。例如:兒童對著一個玩具娃說,“我要聽葫蘆娃的故事”,玩具娃識別請求后,會在云端找到相關故事,以流媒體傳送的方式,播放該故事。由于有PSRAM做data buffer,即使在不是很穩定的環境里,故事也會非常流暢的播放。
同樣,在一些網絡收音機中,使用PSRAM,能夠是聲音播放非常平滑,提供優越的用戶體驗。
為追求小型化,現在已經有串行化的PSRAM:
1. SPI PSRAM: 8-pin SOP封裝,最高速率可以達到104MHz, 具有片選CS、CLK、SI、SO 4個信號腳。
2. QPI PSRAM: 8-pin SOP封裝,最高速率104MHz, 有額外的3個雙向數據管腳,由此帶寬峰值可以達到416Mbps。
3. OPI PSRAM: 24 腳封裝,有8個串行數據線,最高時鐘頻率達到133MHz,最高帶寬可以達到133x8 x2=2.128Gbps。這里x2是因為它可以實現DDR,以提高數據帶寬。
PSRAM在一些數據緩沖應用中可以取代SRAM或者SDRAM: 高速、大容量PSRAM非常貴;而SDRAM需要很多管腳、需要設計DRAM控制器、實現數據刷新等,再尺寸、設計復雜度等上不經濟。
在傳統的MCU中,都有SPI接口,因此,使用PSRAM沒有問題。對應QPI/OPI,設計上需要一些配合。

我們相機模塊用的就是這個

在渲染圖的這個地方

在下面的位置引入了一個頭文件
以及兩個串,你相機要連接的ap名字和密碼

這個相機服務開啟的代碼在這里,是個大函數

通過傳遞類型httpd_uri_t結構的對象來注冊URI處理程序,該對象具有包括uri名稱,method類型

下面的這一部分是人臉識別的部分
MTMN是一種輕量級的人臉檢測模型,它圍繞一個新的移動架構(稱為移動網絡2和多任務級聯卷積網絡)構建,專為嵌入式設備而設計。
MTMN 由三個主要部分組成:
建議網(P-Net):建議候選邊界框,并將其發送到R-Net;
優化網絡(R-Net):從P-Net篩選邊界框;
輸出網絡 (O-Net):輸出最終結果,即精確邊界框、置信系數和 5 點地標。
API 簡介
box_array_t *face_detect(dl_matrix3du_t *image_matrix, mtmn_config_t *config);
這將處理整個人臉檢測任務。face_detect()
輸入包括:
image_matrix:類型中的圖像dl_matrix3du_t
配置:MTMN 的配置。有關更多詳細信息,請參閱"提前配置"部分。
輸出為:
類型值包含人臉框,以及每個框的分數和地標。box_array_t
此結構定義如下:
typedef struct tag_box_list
{
fptp_t *score;
box_t *box;
landmark_t *landmark;
int len;
} box_array_t;
該結構包含數組頭,每個數組具有相同的長度,即圖像中的面數。
face_detect()為用戶自定義定義提供參數。config
box_array_t *face_detect(dl_matrix3du_t *image_matrix, mtmn_config_t *config);
的定義:mtmn_config_t
typedef struct
{
float min_face; /// The minimum size of a detectable face
float pyramid; /// The scale of the gradient scaling for the input images
int pyramid_times; /// The pyramid resizing times
threshold_config_t p_threshold; /// The thresholds for P-Net. For details, see the definition of threshold_config_t
threshold_config_t r_threshold; /// The thresholds for R-Net. For details, see the definition of threshold_config_t
threshold_config_t o_threshold; /// The thresholds for O-Net. For details, see the definition of threshold_config_t
mtmn_resize_type type; /// The image resize type. 'pyramid' will lose efficacy, when 'type'==FAST.
} mtmn_config_t;
typedef struct
{
float score; /// The threshold of confidence coefficient. The candidate bounding boxes with a confidence coefficient lower than the threshold will be filtered out.
float nms; /// The threshold of NMS. During the Non-Maximum Suppression, the candidate bounding boxes with a overlapping ratio higher than the threshold will be filtered out.
int candidate_number; /// The maximum number of allowed candidate bounding boxes. Only the first 'candidate_number' of all the candidate bounding boxes will be kept.
} threshold_config_t;
min_face:
不同大小的生成圖像的數量越大;
可檢測面的最小尺寸越小;
處理時間越長
范圍:+12,原始輸入圖像最短邊緣的長度)。
對于固定大小的原始輸入圖像,尺寸越小,min_face
反之亦然。
金字塔
不同大小的生成圖像的數量越大;
檢測比越高;
處理時間越長
指定控制生成的金字塔的刻度。
范圍:(0,1)
對于固定大小的原始輸入圖像,大小越大,pyramid
反之亦然。
pyramid_times
指定控制生成的金字塔的數字。
范圍:{1,\inf)
與金字塔和min_face一起,可以在范圍 [min_face、min_face/金字塔=pyramid_times] 和 min_face/金字塔=pyramid_times < 原始輸入圖像最短邊緣的長度確定主要可檢測到的面大小。
類型
FAST:金字塔等于默認值。在同一金字塔值中,類型比類型快。0.707106781FASTNORMAL
NORMAL:如果要自定義金字塔值,請將類型設置為請。NORMAL
選項:或FASTNORMAL
分數閾值
篩選出候選邊界框的數量越大
檢測比率越低
范圍:(0,1)
對于固定大小的原始輸入圖像,大小越大,score
反之亦然。
nms 閾值
檢測到重疊面的可能性越高;
檢測到同一面的候選邊界框的數量越大
范圍:(0,1)
對于固定大小的原始輸入圖像,大小越大,nms
反之亦然。
候選人編號
越大,處理時間越長;candidate_number
O-Net 越大,檢測到的面數越大candidate_number
P-Net:[1, 200]
R-Net:[1, 100]
O-Net:[1, 10]
指定每個網絡的輸出候選框數。
范圍
對于固定大小的原始輸入圖像,
反之亦然。
用戶可以根據實際要求配置這些參數。另請參閱以下通用方案(一個人臉檢測)的建議配置:
mtmn_config.type = FAST;
mtmn_config.min_face = 80;
mtmn_config.pyramid = 0.707;
mtmn_config.pyramid_times = 4;
mtmn_config.p_threshold.score = 0.6;
mtmn_config.p_threshold.nms = 0.7;
mtmn_config.p_threshold.candidate_number = 20;
mtmn_config.r_threshold.score = 0.7;
mtmn_config.r_threshold.nms = 0.7;
mtmn_config.r_threshold.candidate_number = 10;
mtmn_config.o_threshold.score = 0.7;
mtmn_config.o_threshold.nms = 0.7;
mtmn_config.o_threshold.candidate_number = 1;
MTMN 現在有兩個版本可用:
MTMN lite 在量化(默認值)
浮動中的 Mtmn 精簡版
MTMN 在量化方面很重
我們使用相同的配置和我們自己的測試集來評估所有型號。結果如下所示。
mtmn_config.type = FAST;
mtmn_config.pyramid = 0.707;
mtmn_config.min_face = 80;
mtmn_config.pyramid_times = 4;
mtmn_config.p_threshold.score = 0.6;
mtmn_config.p_threshold.nms = 0.7;
mtmn_config.p_threshold.candidate_number = 100;
mtmn_config.r_threshold.score = 0.7;
mtmn_config.r_threshold.nms = 0.7;
mtmn_config.r_threshold.candidate_number = 100;
mtmn_config.o_threshold.score = 0.7;
mtmn_config.o_threshold.nms = 0.7;
mtmn_config.o_threshold.candidate_number = 1;

這個是性能部分
https://github.com/espressif/esp-face/blob/master/face_detection/README.md
參考資料

這個是服務穩定后的后的一些打印的東西

接著又是一個服務器相關的打印語句

因為在主文件里面已經選擇了對應的平臺,所以在camera_pin的里面全點亮

先看一下概覽的樣子,只引入了相機,wifi,引腳的頭文件
這些引入的頭文件里面還有什么的頭文件再說

一開始開啟了串口的一些相關的配置,初始化了波特率,打開了debug。
下面是引腳的配置部分,在使用這些庫去移植的時候需要改動的地方

這個代碼就說的很明白了,就是這個地方沒有寫很底層的代碼就是去申請內存什么的。只是開啟了更高的分辨率,相當于開啟功能

相機初始化
Step:
尋找攝像頭
提供攝像頭時鐘、初始化 SCCB 總線、硬件復位攝像頭
輪詢地址尋找攝像頭,通過 SCCB 總線讀取攝像頭 ID 等信息
更改攝像頭的 ID 判斷型號,并綁定對應的相關函數(攝像頭傳感器配置相關函數)
初始化攝像頭
根據選擇的圖像格式、和是否是高速模式,選擇對應的 DMA BUF 處理函數和 DMA FIFO 模式
初始化 I2S 總線,使能 I2S_IN_DONE_INT 中斷:當前 DMA 接收鏈表描述符被處理時即觸發此中斷 3. 初始化 DMA 相關變量(鏈表描述符、DMA 使用的數據緩沖區鏈表等),DMA 單次最多 4KB 、每行 DMA 采集幾次
初始化存儲圖像的數據緩沖區(添加到一個鏈表中)并清空
初始化相關信號量:DMA 數據采集完成、一幀圖像采集完成信號量、圖像數據緩沖區進出信號量
創建 dma_filter_task 將 DMA 數據轉換成像素數據并存儲到圖像緩沖區,這里也會檢查是否有臟數據產生,判斷是否接收完一幀完整的圖像
初始化 vsync io 中斷:每一幀圖像開始結尾都會發生電平翻轉
攝像頭傳感器相關配置(圖像大小、格式等)
剩下有一點代碼,我因為自己這個圖像識別方面學的少就不作更多的分析了

代碼放這里

最后一部分是WiFi配置部分,一開始的配置通過指針傳到這里
配置部分到這里就好了。

因為是demo嘛,一些邏輯代碼就沒有寫
然后整體來說,框架搭好啦。

然后這兩個地方是超級大的數組

這個是最后一部分的代碼庫的頭文件了
你看引入了,http的服務器,定時器相關,相機,圖像轉換庫,相機index?
arduino的頭,以及三個關于人臉識別的庫

一開始是宏定義,名字一目了然

下面是兩個結構體


這兩個是結構體傳遞的地方,我也看不懂了。我寫完文章就學CPP去了。。。

第一個函數應該是一個操作內存的一個函數,申請一定量的空間用
具體的大小是看結構體去申請的

剩下的函數就是這些了,我能力以及相關領域的知識儲備不夠就不能繼續和各位看官一起分享了,我去惡補知識了~
