当前位置:   article > 正文

ESP32-CAM移植和使用经验分享_esp32—idf:移植esp32-camera

esp32—idf:移植esp32-camera


前言

之前我将爱智官方的代码移植到了 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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

代码解析和注意事项

摄像头拍下来的数据和图像属性都保存在 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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后通过 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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

另外每使用完一帧画面后一定要调用 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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

另外这些接口都是比较底层原始的接口,没有 IDF 平台封装的 camera_run()camera_get_data_size 等函数这么安全,所以无法使用官方代码中那种通过判断时间间隔控制拍照的方法,只能在应用端控制拍摄频率


总结

这玩意现在只能说勉强能用,因为这玩意很容易过热,持续拍摄一段时间后,信号会逐渐不稳定,直到彻底掉线。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/896407
推荐阅读
相关标签
  

闽ICP备14008679号