{"id":17082299,"url":"https://github.com/cnadler86/micropython-camera-API","last_synced_at":"2025-02-22T05:30:47.435Z","repository":{"id":256695969,"uuid":"853594877","full_name":"cnadler86/micropython-camera-API","owner":"cnadler86","description":"Camera API for micropython as user module, with precompiled FW, starting with the esp32 port.","archived":false,"fork":false,"pushed_at":"2025-01-22T05:19:41.000Z","size":208,"stargazers_count":48,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-16T22:32:02.311Z","etag":null,"topics":["camera","esp32-cam","espcam","micropython","ov2640","ov5640"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cnadler86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"cnadler86"}},"created_at":"2024-09-07T01:59:39.000Z","updated_at":"2025-02-14T10:09:10.000Z","dependencies_parsed_at":"2024-09-24T23:20:22.549Z","dependency_job_id":"e6d822d5-6c9d-4e8c-8937-db8cfe4c91f1","html_url":"https://github.com/cnadler86/micropython-camera-API","commit_stats":{"total_commits":58,"total_committers":3,"mean_commits":"19.333333333333332","dds":0.5689655172413793,"last_synced_commit":"b31c83d452a221870e9292312f7518ba2b3eba8c"},"previous_names":["cnadler86/mp_camera","cnadler86/micropython-camera-api"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmicropython-camera-API","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmicropython-camera-API/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmicropython-camera-API/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmicropython-camera-API/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cnadler86","download_url":"https://codeload.github.com/cnadler86/micropython-camera-API/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239599076,"owners_count":19665911,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera","esp32-cam","espcam","micropython","ov2640","ov5640"],"created_at":"2024-10-14T13:00:25.001Z","updated_at":"2025-02-22T05:30:47.427Z","avatar_url":"https://github.com/cnadler86.png","language":"C","readme":"# Camera API for micropython\n\n[![ESP32 Port](https://github.com/cnadler86/micropython-camera-API/actions/workflows/ESP32.yml/badge.svg)](https://github.com/cnadler86/micropython-camera-API/actions/workflows/ESP32.yml)\n\nThis project aims to support various cameras (e.g. OV2640, OV5640) on different MicroPython ports, starting with the ESP32 port. The project implements a general API, has precompiled FW images and supports a lot of cameras out of the box. Defaults are set to work with the OV2640.\nAt the moment, this is a micropython user module, but it might get in the micropython repo in the future.\nThe API is stable, but it might change without previous announce.\n\n## Content\n\n- [Precomiled FW (the easy way)](#precomiled-fw-the-easy-way)\n- [Using the API](#using-the-api)\n  - [Importing the camera module](#importing-the-camera-module)\n  - [Creating a camera object](#creating-a-camera-object)\n  - [Initializing the camera](#initializing-the-camera)\n  - [Capture image](#capture-image)\n  - [Convert image to another format](#convert-image-to-another-format)\n  - [Camera reconfiguration](#camera-reconfiguration)\n  - [Additional methods](#additional-methods)\n  - [Additional information](#additional-information)\n- [Build your custom FW](#build-your-custom-fw)\n  - [Setting up the build environment (DIY method)](#setting-up-the-build-environment-diy-method)\n  - [Add camera configurations to your board (optional, but recommended)](#add-camera-configurations-to-your-board-optional-but-recommended)\n  - [Build the API](#build-the-api)\n- [Notes](#notes)\n- [Benchmark](#benchmark)\n- [Troubleshooting](#troubleshooting)\n- [Donate](#donate)\n\n## Precomiled FW (the easy way)\n\nIf you are not familiar with building custom firmware, visit the [releases](https://github.com/cnadler86/micropython-camera-API/releases) page to download firmware that suits your board. **There are over 20 precompiled board images with the latest micropython!**\n\n## Using the API\n\n### Importing the camera module\n\n```python\nfrom camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling\n```\n\n### Creating a camera object\n\nCamera construction using defaults. This is the case if you are using a **non-generic** precompiled firmware or if you specified the camera model or pins in mpconfigboard.h during your build. Then you can just call the construction without any keyword arguments.\n\n```python\ncam = Camera()\n```\n\nor with relevant keyword arguments:\n\n```python\ncam = Camera(pixel_format=PixelFormat.JPEG,\n    frame_size=FrameSize.QVGA,\n    jpeg_quality=90,\n    fb_count=2,\n    grab_mode=GrabMode.WHEN_EMPTY)\n```\n\nWhen using a **generic** precompiled firmware, the camera constructor requires specific keyword arguments (namely the camera pins to be used).\nThese pins are just examples and if used as-is, a error will occur. Adapt them to your board!\n\n```python\ncam = Camera(\n    data_pins=[1,2,3,4,5,6,7,8],\n    vsync_pin=9,\n    href_pin=10,\n    sda_pin=11,\n    scl_pin=12,\n    pclk_pin=13,\n    xclk_pin=14,\n    xclk_freq=20000000,\n    powerdown_pin=-1,\n    reset_pin=-1,\n)\n```\n\n**Keyword arguments for construction:**\n\n- data_pins: List of data pins\n- pclk_pin: Pixel clock pin\n- vsync_pin: VSYNC pin\n- href_pin: HREF pin\n- sda_pin: SDA pin\n- scl_pin: SCL pin\n- xclk_pin: XCLK pin\n- xclk_freq: XCLK frequency in Hz\n- powerdown_pin: Powerdown pin\n- reset_pin: Reset pin\n- pixel_format: Pixel format as PixelFormat\n- frame_size: Frame size as FrameSize\n- jpeg_quality: JPEG quality\n- fb_count: Frame buffer count\n- grab_mode: Grab mode as GrabMode\n- init: Initialize camera at construction time (default: True)\n- bmp_out: Image captured output converted to bitmap (default: False)\n\n**Default values:**\n\nThe following keyword arguments have default values:\n\n- xclk_freq: 20MHz    // Frequencies are normally either 10 MHz or 20 MHz\n- frame_size: QQVGA\n- pixel_format: RGB565\n- jpeg_quality: 85    // Quality of JPEG output in percent. Higher means higher quality.\n- powerdown_pin and reset_pin: -1 ( = not used/available/needed)\n- fb_count:\n  - 2 for ESP32S3 boards\n  - 1 for all other\n- grab_mode:\n  - LATEST for ESP32S3 boards\n  - WHEN_EMPTY for all other\n\n### Initializing the camera\n\n```python\ncam.init()\n```\n\n### Capture image\n\n```python\nimg = cam.capture()\n```\n\nArguments for capture\n\n- out_format: Output format as PixelFormat (optional)\n\n### Convert image to another format\n\nYou can either convert the image with the `capture` method directly passing the desired output format:\n```python\nimg_rgb888 = cam.capture(PixelFormat.RGB888) #capture image as configured (e.g. JPEG), convert it to RGB888 and return the converted image\n```\nOr you can first capture the image and then convert it to the desired PixelFormat with the `convert` method.\nDoing so you can have both, the captured and the converted image. Note that more memory will be used.\n```python\nimg = cam.capture()\nimg_rgb888 = cam.convert(PixelFormat.RGB888) #converts the last captured image to RGB888 and returns the converted image\n```\n\nConvertion supported \n- from JPEG to RGB565\n- to RGB888 in general\n- to JPEG in gerenal (use the `set_quality` method to set the desired JPEG quality)\n\n### Camera reconfiguration\n\n```python\ncam.reconfigure(pixel_format=PixelFormat.JPEG,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST, fb_count=2)\n```\n\nKeyword arguments for reconfigure\n\n- frame_size: Frame size as FrameSize (optional)\n- pixel_format: Pixel format as PixelFormat(optional)\n- grab_mode: Grab mode as GrabMode (optional)\n- fb_count: Frame buffer count (optional)\n\n### Additional methods\n\nHere are just a few examples:\n\n```python\ncam.set_quality(90)  # The quality goes from 0% to 100%, meaning 100% is the highest but has probably no compression\ncam.set_bmp_out(True) # Enables convertion to bmp when capturing image\ncamera.get_brightness()\ncamera.set_vflip(True) #Enable vertical flip\n```\n\nSee autocompletions in Thonny in order to see the list of methods.\nIf you want more insides in the methods and what they actually do, you can find a very good documentation [here](https://docs.circuitpython.org/en/latest/shared-bindings/espcamera/index.html).\nNote that each method requires a \"get_\" or \"set_\" prefix, depending on the desired action.\n\nTo get the version of the camera driver used:\n\n```python\nimport camera\nvers = camera.Version()\n```\n\n### Additional information\n\nThe FW images support the following cameras out of the box, but is therefore big: OV7670, OV7725, OV2640, OV3660, OV5640, NT99141, GC2145, GC032A, GC0308, BF3005, BF20A6, SC030IOT\n\n## Build your custom FW\n\n### Setting up the build environment (DIY method)\n\nTo build the project, follow these instructions:\n\n- [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v5.2.3/esp32/get-started/index.html): I used version 5.2.3, but it might work with other versions (see notes).\n- Clone the micropython repo and this repo in a folder, e.g. \"MyESPCam\". MicroPython version 1.24 or higher is required (at least commit 92484d8).\n- You will have to add the ESP32-Camera driver (I used v2.0.15). To do this, add the following to the respective idf_component.yml file (e.g. in micropython/ports/esp32/main_esp32s3/idf_component.yml):\n\n```yml\n  espressif/esp32-camera:\n    git: https://github.com/espressif/esp32-camera.git\n```\n\nAlternatively, you can clone the \u003chttps://github.com/espressif/esp32-camera\u003e repository inside the esp-idf/components folder instead of altering the idf_component.yml file.\n\n### Add camera configurations to your board (optional, but recommended)\n\n#### Supported camera models\n\nThis project supports various boards with camera interface out of the box. You typically only need to add a single line to your board config file (\"mpconfigboard.h).\nExample (don't forget to add the empty line at the bottom):\n\n```c\n#define MICROPY_CAMERA_MODEL_WROVER_KIT       1\n\n```\n\nBelow is a list of supported `MICROPY_CAMERA_MODEL_xxx` definitions:\n\n- MICROPY_CAMERA_MODEL_WROVER_KIT - [ESP32-WROVER-KIT](https://www.espressif.com/en/products/devkits/esp32-wrover-kit/overview)\n- MICROPY_CAMERA_MODEL_ESP_EYE - [ESP-EYE](https://www.espressif.com/en/products/devkits/esp-eye/overview)\n- MICROPY_CAMERA_MODEL_M5STACK_PSRAM - [M5Stack PSRAM](https://shop.m5stack.com/collections/m5-cameras)\n- MICROPY_CAMERA_MODEL_M5STACK_UNITCAM - [M5Stack UnitCam](https://shop.m5stack.com/collections/m5-cameras)\n- MICROPY_CAMERA_MODEL_M5STACK_V2_PSRAM - [M5Stack V2 PSRAM](https://shop.m5stack.com/collections/m5-cameras)\n- MICROPY_CAMERA_MODEL_M5STACK_WIDE - [M5Stack Wide](https://shop.m5stack.com/collections/m5-cameras)\n- MICROPY_CAMERA_MODEL_M5STACK_ESP32CAM - [M5Stack ESP32CAM](https://shop.m5stack.com/collections/m5-cameras)\n- MICROPY_CAMERA_MODEL_M5STACK_CAMS3_UNIT - [M5Stack CAMS3 Unit](https://shop.m5stack.com/collections/m5-cameras)\n- MICROPY_CAMERA_MODEL_AI_THINKER - [AI-Thinker ESP32-CAM]\n- MICROPY_CAMERA_MODEL_XIAO_ESP32S3 - [XIAO ESP32S3](https://www.seeedstudio.com/xiao-series-page)\n- MICROPY_CAMERA_MODEL_ESP32_MP_CAMERA_BOARD - [ESP32 MP Camera Board]\n- MICROPY_CAMERA_MODEL_ESP32S3_CAM_LCD - [ESP32-S3 CAM LCD]\n- MICROPY_CAMERA_MODEL_ESP32S3_EYE - [ESP32-S3 EYE](https://www.espressif.com/en/products/devkits/esp32-s3-eye/overview)\n- MICROPY_CAMERA_MODEL_FREENOVE_ESP32S3_CAM - [Freenove ESP32-S3 CAM](https://store.freenove.com/products/fnk0085)\n- MICROPY_CAMERA_MODEL_DFRobot_ESP32S3 - [DFRobot ESP32-S3](https://www.dfrobot.com/)\n- MICROPY_CAMERA_MODEL_TTGO_T_JOURNAL - [TTGO T-Journal](https://www.lilygo.cc/products/)\n- MICROPY_CAMERA_MODEL_TTGO_T_CAMERA_PLUS - [TTGO T-Camera Plus](https://www.lilygo.cc/products/)\n- MICROPY_CAMERA_MODEL_NEW_ESPS3_RE1_0 - [New ESP32-S3 RE:1.0]\n- MICROPY_CAMERA_MODEL_XENOIONEX - [Xenoionex]\n\n#### For unsupported camera models\n\nIf your board is not yet supported, add the following lines to your board config-file \"mpconfigboard.h\" with the respective pins and camera parameters. Otherwise, you will need to pass all parameters during construction.\nExample for Xiao sense:\n\n```c\n#define MICROPY_CAMERA_PIN_D0       (15)\n#define MICROPY_CAMERA_PIN_D1       (17)\n#define MICROPY_CAMERA_PIN_D2       (18)\n#define MICROPY_CAMERA_PIN_D3       (16)\n#define MICROPY_CAMERA_PIN_D4       (14)\n#define MICROPY_CAMERA_PIN_D5       (12)\n#define MICROPY_CAMERA_PIN_D6       (11)\n#define MICROPY_CAMERA_PIN_D7       (48)\n#define MICROPY_CAMERA_PIN_PCLK     (13)\n#define MICROPY_CAMERA_PIN_VSYNC    (38)\n#define MICROPY_CAMERA_PIN_HREF     (47)\n#define MICROPY_CAMERA_PIN_XCLK     (10)\n#define MICROPY_CAMERA_PIN_PWDN     (-1)\n#define MICROPY_CAMERA_PIN_RESET    (-1)\n#define MICROPY_CAMERA_PIN_SIOD     (40)        // SDA\n#define MICROPY_CAMERA_PIN_SIOC     (39)        // SCL\n#define MICROPY_CAMERA_XCLK_FREQ    (20000000)  // Frequencies are normally either 10 MHz or 20 MHz\n#define MICROPY_CAMERA_FB_COUNT     (2)         // The value is between 1 (slow) and 2 (fast, but more load on CPU and more ram usage)\n#define MICROPY_CAMERA_JPEG_QUALITY (85)        // Quality of JPEG output in percent. Higher means higher quality.\n#define MICROPY_CAMERA_GRAB_MODE    (1)         // 0=WHEN_EMPTY (might have old data, but less resources), 1=LATEST (best, but more resources)\n\n```\n#### Customize additional camera settings\n\nIf you want to customize additional camera setting or reduce the FW size by removing support for unused camera sensors, then take a look at the kconfig file of the esp32-camera driver and specify these on the sdkconfig file of your board.\n\n### Build the API\n\nTo build the project, you could do it the following way:\n\n```bash\n. \u003cpath2esp-idf\u003e/esp-idf/export.sh\ncd MyESPCam/micropython/ports/esp32\nmake USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=\u003cYour-Board\u003e clean\nmake USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=\u003cYour-Board\u003e submodules\nmake USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=\u003cYour-Board\u003e all\n```\n\nIf you experience problems, visit [MicroPython external C modules](https://docs.micropython.org/en/latest/develop/cmodules.html).\n\n## Notes\n\n- For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has significantly improved, but JPEG mode always gives better frame rates.\n- The OV5640 pinout is compatible with boards designed for the OV2640 but the voltage supply is too high for the internal 1.5V regulator, so the camera overheats unless a heat sink is applied. For recording purposes the OV5640 should only be used with an ESP32S3 board. Frame sizes above FHD framesize should only be used for still images due to memory limitations.\n- If your target board is a ESP32, I recommend using IDF \u003e= 5.2, since older versions may lead to IRAM overflow during build. Alternatively you can modify your sdkconfig-file (see [issue #1](https://github.com/cnadler86/micropython-camera-API/issues/1)).\n- The driver requires PSRAM to be installed and activated.\n- Most of the precompiled firmware images are untested, but the only difference between them are the target architecture and pin definitions, so they should work out of the box. If not, please raise an issue.\n- Every sensor has its own ranges and settings, please consult the respective specifications.\n\n## Benchmark\n\nI didn't use a calibrated osziloscope, but here is a FPS benchmark with my ESP32S3 (xclck_freq = 20MHz, GrabMode=LATEST, fb_count = 1, jpeg_quality=85%) and OV2640.\nUsing fb_count=2 theoretically can double the FPS (see JPEG with fb_count=2). This might also aplly for other PixelFormats.\n\n| Frame Size | GRAYSCALE | RGB565 | YUV422 | JPEG   | JPEG -\u003e RGB565 | JPEG -\u003e RGB888 | JPEG (fb=2) |\n|------------|-----------|--------|--------|--------|----------------|----------------|-------------|\n| R96X96     | 12.5      | 12.5   | 12.5   | No img | No img         | No img         | No img      |\n| QQVGA      | 12.5      | 12.5   | 12.5   | 25     | 25             | 25             | 50          |\n| QCIF       | 11        | 11     | 11.5   | 25     | 25             | 25             | 50          |\n| HQVGA      | 12.5      | 12.5   | 12.5   | 25     | 16.7           | 16.7           | 50          |\n| R240X240   | 12.5      | 12.5   | 11.5   | 25     | 16.7           | 12.5           | 50          |\n| QVGA       | 12        | 11     | 12     | 25     | 25             | 25             | 50          |\n| CIF        | 12.5      | No img | No img | 6.3    | 8.3            | 8.3            | 12.5        |\n| HVGA       | 3         | 3      | 2.5    | 12.5   | 6.3            | 6.3            | 25          |\n| VGA        | 3         | 3      | 3      | 12.5   | 3.6            | 3.6            | 25          |\n| SVGA       | 3         | 3      | 3      | 12.5   | 2.8            | 2.5            | 25          |\n| XGA        | No img    | No img | No img | 6.3    | 1.6            | 1.6            | 12.5        |\n| HD         | No img    | No img | No img | 6.3    | 1.4            | 1.3            | 12.5        |\n| SXGA       | 2         | 2      | 2      | 6.3    | 1              | 1              | 12.5        |\n| UXGA       | No img    | No img | No img | 6.3    | 0.7            | 0.7            | 12.5        |\n\n\nLooking at the results: image conversion make only sense for frame sized below QVGA or if capturing the image in the intended pixelformat and frame size combination fails.\n\n## Troubleshooting\n\nYou can find information on the following sites:\n- [ESP-FAQ](https://docs.espressif.com/projects/esp-faq/en/latest/application-solution/camera-application.html)\n- [ChatGPT](https://chatgpt.com/)\n- [Issues in here](https://github.com/cnadler86/micropython-camera-API/issues?q=is%3Aissue)\n\n## Donate\n\nIf you enjoy this work and would like to share your enjoyment, please feel free to [donate](https://github.com/sponsors/cnadler86?frequency=one-time) and contribute to the project. Thanks! :blush:\n","funding_links":["https://github.com/sponsors/cnadler86","https://github.com/sponsors/cnadler86?frequency=one-time"],"categories":["Libraries","Recently Updated"],"sub_categories":["Sensors","[Oct 12, 2024](/content/2024/10/12/README.md)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnadler86%2Fmicropython-camera-API","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcnadler86%2Fmicropython-camera-API","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnadler86%2Fmicropython-camera-API/lists"}