ESP32-CAM移植和使用經驗分享
@ TOC
前言
之前我將愛智官方的程式碼移植到了 arduino 上,詳細可見 arduino 天下第一(暴論) -- 智慧貓眼與 SDDC 聯結器移植到 arduino 上
在這過程中我踩了一些坑,在這裡和大家分享一下。
arduino 操作介面
arduino 官方提供demo已經封裝很好了,只用呼叫一個函式就能完成拍攝上傳等一系列操作,但是如果這個介面不符合我們的需求,就只能自己同時改改了。
通過下面的連線可以看到 ESP32-CAM 底層的東西一些介面
https://github.com/espressif/arduino-esp32/releases/tag/2.0.2
或者你已經安裝了 ESP32-CAM 相關庫後可以去:
C:\Users\123456\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.5\tools\sdk\include\esp32-camera
可以看到一個 esp_camera.h 檔案,裡面有一些可以用到的介面和結構體。
/** * @brief Data structure of camera frame buffer */ typedef struct { uint8_t * buf; /*!< Pointer to the pixel data */ // 這就是攝像頭拍下來的資料 size_t len; /*!< Length of the buffer in bytes */ size_t width; /*!< Width of the buffer in pixels */ size_t height; /*!< Height of the buffer in pixels */ pixformat_t format; /*!< Format of the pixel data */ struct timeval timestamp; /*!< Timestamp since boot of the first DMA buffer of the frame */ } camera_fb_t; #define ESP_ERR_CAMERA_BASE 0x20000 #define ESP_ERR_CAMERA_NOT_DETECTED (ESP_ERR_CAMERA_BASE + 1) #define ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE (ESP_ERR_CAMERA_BASE + 2) #define ESP_ERR_CAMERA_FAILED_TO_SET_OUT_FORMAT (ESP_ERR_CAMERA_BASE + 3) #define ESP_ERR_CAMERA_NOT_SUPPORTED (ESP_ERR_CAMERA_BASE + 4) /** * @brief Initialize the camera driver * * @note call camera_probe before calling this function * * This function detects and configures camera over I2C interface, * allocates framebuffer and DMA buffers, * initializes parallel I2S input, and sets up DMA descriptors. * * Currently this function can only be called once and there is * no way to de-initialize this module. * * @param config Camera configuration parameters * * @return ESP_OK on success */ esp_err_t esp_camera_init(const camera_config_t* config); /** * @brief Deinitialize the camera driver * * @return * - ESP_OK on success * - ESP_ERR_INVALID_STATE if the driver hasn't been initialized yet */ esp_err_t esp_camera_deinit(); /** * @brief Obtain pointer to a frame buffer. * * @return pointer to the frame buffer */ camera_fb_t* esp_camera_fb_get(); /** * @brief Return the frame buffer to be reused again. * * @param fb Pointer to the frame buffer */ void esp_camera_fb_return(camera_fb_t * fb); /** * @brief Get a pointer to the image sensor control structure * * @return pointer to the sensor */ sensor_t * esp_camera_sensor_get(); /** * @brief Save camera settings to non-volatile-storage (NVS) * * @param key A unique nvs key name for the camera settings */ esp_err_t esp_camera_save_to_nvs(const char *key); /** * @brief Load camera settings from non-volatile-storage (NVS) * * @param key A unique nvs key name for the camera settings */ esp_err_t esp_camera_load_from_nvs(const char *key);
程式碼解析和注意事項
攝像頭拍下來的資料和影象屬性都儲存在 camera_fb_t 結構體中,其中 buf 就是影象資料,其他的都是相關屬性
uint8_t * buf; /*!< Pointer to the pixel data */ // 這就是攝像頭拍下來的資料 size_t len; /*!< Length of the buffer in bytes */ size_t width; /*!< Width of the buffer in pixels */ size_t height; /*!< Height of the buffer in pixels */ pixformat_t format; /*!< Format of the pixel data */ struct timeval timestamp; /*!< Timestamp since boot of the first DMA buffer of the frame */ } camera_fb_t;
然後通過 esp_camera_fb_get 可以拍攝一幀畫面,並且返回 camera_fb_t 結構體指標。
沒錯,這個介面不僅是註釋中描述那樣返回一個指標,他在返回之前會先拍攝一幀畫面,然後才返回指標,所以大家不用去找專門的拍攝函數了,也不用擔心直接呼叫這個函式會返回空指標。
/** * @brief Obtain pointer to a frame buffer. * * @return pointer to the frame buffer */ camera_fb_t* esp_camera_fb_get();
另外每使用完一幀畫面後一定要呼叫 esp_camera_fb_return 釋放掉不用的資料,否則沒辦法拍攝下一幀。
/** * @brief Return the frame buffer to be reused again. * * @param fb Pointer to the frame buffer */ void esp_camera_fb_return(camera_fb_t * fb);
另外這些介面都是比較底層原始的介面,沒有 IDF 平臺封裝的 camera_run() , camera_get_data_size 等函式這麼安全,所以無法使用官方程式碼中那種通過判斷時間間隔控制拍照的方法,只能在應用端控制拍攝頻率
總結
這玩意現在只能說勉強能用,因為這玩意很容易過熱,持續拍攝一段時間後,訊號會逐漸不穩定,直到徹底掉線。
- 設計模式之狀態模式
- 如何實現資料庫讀一致性
- 我是怎麼入行做風控的
- C 11精要:部分語言特性
- 吳恩達來信:人工智慧領域的求職小 tips
- EasyCV帶你復現更好更快的自監督演算法-FastConvMAE
- 某車聯網App 通訊協議加密分析(四) Trace Code
- 帶你瞭解CANN的目標檢測與識別一站式方案
- EasyNLP玩轉文字摘要(新聞標題)生成
- PostgreSQL邏輯複製解密
- 基於 CoreDNS 和 K8s 構建雲原生場景下的企業級 DNS
- 迴圈神經網路(RNN)可是在語音識別、自然語言處理等其他領域中引起了變革!
- 技術分享| 分散式系統中服務註冊發現元件的原理及比較
- 利用谷歌地圖採集外貿客戶的電話和手機號碼
- 跟我學Python影象處理丨關於影象金字塔的影象向下取樣和向上取樣
- 帶你掌握如何使用CANN 運算元ST測試工具msopst
- 一招教你如何高效批量匯入與更新資料
- 一步步搞懂MySQL元資料鎖(MDL)
- 你知道如何用 PHP 實現多程序嗎?
- KubeSphere 閘道器的設計與實現(解讀)