Initial commit
This commit is contained in:
commit
9f12627649
17 changed files with 4047 additions and 0 deletions
164
ESP_sources/CameraWebServer.ino
Normal file
164
ESP_sources/CameraWebServer.ino
Normal file
|
@ -0,0 +1,164 @@
|
|||
#include "esp_camera.h"
|
||||
#include <WiFi.h>
|
||||
|
||||
//
|
||||
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
|
||||
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
|
||||
// Partial images will be transmitted if image exceeds buffer size
|
||||
//
|
||||
// You must select partition scheme from the board menu that has at least 3MB APP space.
|
||||
// Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15
|
||||
// seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well
|
||||
|
||||
// ===================
|
||||
// Select camera model
|
||||
// ===================
|
||||
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
||||
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
|
||||
//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
|
||||
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
|
||||
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
|
||||
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
|
||||
// ** Espressif Internal Boards **
|
||||
//#define CAMERA_MODEL_ESP32_CAM_BOARD
|
||||
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
|
||||
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
|
||||
#include "camera_pins.h"
|
||||
|
||||
// ===========================
|
||||
// Enter your WiFi credentials
|
||||
// ===========================
|
||||
const char* ssid = "RPI Henri";
|
||||
|
||||
IPAddress staticIP(192, 168, 0, 152);
|
||||
IPAddress gateway(192, 168, 0, 0);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
IPAddress dns(192, 168, 0, 0);
|
||||
|
||||
void startCameraServer();
|
||||
void setupLedFlash(int pin);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Serial.println();
|
||||
|
||||
camera_config_t config;
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;how can i open multiple files at the same time in python
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sccb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sccb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000;
|
||||
config.frame_size = FRAMESIZE_UXGA;
|
||||
config.pixel_format = PIXFORMAT_JPEG; // for streaming
|
||||
//config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
|
||||
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
|
||||
config.fb_location = CAMERA_FB_IN_PSRAM;
|
||||
config.jpeg_quality = 12;
|
||||
config.fb_count = 1;
|
||||
|
||||
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
|
||||
// for larger pre-allocated frame buffer.
|
||||
if(config.pixel_format == PIXFORMAT_JPEG){
|
||||
if(psramFound()){
|
||||
config.jpeg_quality = 10;
|
||||
config.fb_count = 2;
|
||||
config.grab_mode = CAMERA_GRAB_LATEST;
|
||||
} else {
|
||||
// Limit the frame size when PSRAM is not available
|
||||
config.frame_size = FRAMESIZE_SVGA;
|
||||
config.fb_location = CAMERA_FB_IN_DRAM;
|
||||
}
|
||||
} else {
|
||||
// Best option for face detection/recognition
|
||||
config.frame_size = FRAMESIZE_240X240;
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
config.fb_count = 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CAMERA_MODEL_ESP_EYE)
|
||||
pinMode(13, INPUT_PULLUP);
|
||||
pinMode(14, INPUT_PULLUP);
|
||||
#endif
|
||||
|
||||
// camera init
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
// initial sensors are flipped vertically and colors are a bit saturated
|
||||
if (s->id.PID == OV3660_PID) {
|
||||
s->set_vflip(s, 1); // flip it back
|
||||
s->set_brightness(s, 1); // up the brightness just a bit
|
||||
s->set_saturation(s, -2); // lower the saturation
|
||||
}
|
||||
// drop down frame size for higher initial frame rate
|
||||
// if(config.pixel_format == PIXFORMAT_JPEG){
|
||||
// s->set_framesize(s, FRAMESIZE_QVGA);
|
||||
// }
|
||||
|
||||
#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||
s->set_vflip(s, 1);
|
||||
s->set_hmirror(s, 1);
|
||||
#endif
|
||||
|
||||
#if defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||
s->set_vflip(s, 1);
|
||||
#endif
|
||||
|
||||
// Setup LED FLash if LED pin is defined in camera_pins.h
|
||||
#if defined(LED_GPIO_NUM)
|
||||
setupLedFlash(LED_GPIO_NUM);
|
||||
#endif
|
||||
|
||||
if (WiFi.config(staticIP, gateway, subnet, dns, dns) == false) {
|
||||
Serial.println("Configuration failed.");
|
||||
}
|
||||
|
||||
// WiFi.begin(ssid, password);
|
||||
WiFi.begin(ssid);
|
||||
WiFi.setSleep(false);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
|
||||
startCameraServer();
|
||||
|
||||
Serial.print("Camera Ready! Use 'http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
Serial.println("' to connect");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Do nothing. Everything is done in another task by the web server
|
||||
delay(10000);
|
||||
}
|
1394
ESP_sources/app_httpd.cpp
Normal file
1394
ESP_sources/app_httpd.cpp
Normal file
File diff suppressed because it is too large
Load diff
1571
ESP_sources/camera_index.h
Normal file
1571
ESP_sources/camera_index.h
Normal file
File diff suppressed because it is too large
Load diff
317
ESP_sources/camera_pins.h
Normal file
317
ESP_sources/camera_pins.h
Normal file
|
@ -0,0 +1,317 @@
|
|||
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 37
|
||||
#define Y7_GPIO_NUM 38
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 35
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 13
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#define LED_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#define LED_GPIO_NUM 2
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
// 4 for flash led or 33 for normal led
|
||||
#define LED_GPIO_NUM 4
|
||||
|
||||
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
|
||||
#define PWDN_GPIO_NUM 0
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_XIAO_ESP32S3)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 10
|
||||
#define SIOD_GPIO_NUM 40
|
||||
#define SIOC_GPIO_NUM 39
|
||||
|
||||
#define Y9_GPIO_NUM 48
|
||||
#define Y8_GPIO_NUM 11
|
||||
#define Y7_GPIO_NUM 12
|
||||
#define Y6_GPIO_NUM 14
|
||||
#define Y5_GPIO_NUM 16
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 17
|
||||
#define Y2_GPIO_NUM 15
|
||||
#define VSYNC_GPIO_NUM 38
|
||||
#define HREF_GPIO_NUM 47
|
||||
#define PCLK_GPIO_NUM 13
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD)
|
||||
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||
#define USE_BOARD_HEADER 0
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM 33
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 19
|
||||
#define Y7_GPIO_NUM 21
|
||||
#define Y6_GPIO_NUM 39
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y5_GPIO_NUM 13
|
||||
#else
|
||||
#define Y5_GPIO_NUM 35
|
||||
#endif
|
||||
#define Y4_GPIO_NUM 14
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y3_GPIO_NUM 35
|
||||
#else
|
||||
#define Y3_GPIO_NUM 13
|
||||
#endif
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 40
|
||||
#define SIOD_GPIO_NUM 17
|
||||
#define SIOC_GPIO_NUM 18
|
||||
|
||||
#define Y9_GPIO_NUM 39
|
||||
#define Y8_GPIO_NUM 41
|
||||
#define Y7_GPIO_NUM 42
|
||||
#define Y6_GPIO_NUM 12
|
||||
#define Y5_GPIO_NUM 3
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 47
|
||||
#define Y2_GPIO_NUM 13
|
||||
#define VSYNC_GPIO_NUM 21
|
||||
#define HREF_GPIO_NUM 38
|
||||
#define PCLK_GPIO_NUM 11
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD)
|
||||
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||
#define USE_BOARD_HEADER 0
|
||||
#define PWDN_GPIO_NUM 1
|
||||
#define RESET_GPIO_NUM 2
|
||||
#define XCLK_GPIO_NUM 42
|
||||
#define SIOD_GPIO_NUM 41
|
||||
#define SIOC_GPIO_NUM 18
|
||||
|
||||
#define Y9_GPIO_NUM 16
|
||||
#define Y8_GPIO_NUM 39
|
||||
#define Y7_GPIO_NUM 40
|
||||
#define Y6_GPIO_NUM 15
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y5_GPIO_NUM 12
|
||||
#else
|
||||
#define Y5_GPIO_NUM 13
|
||||
#endif
|
||||
#define Y4_GPIO_NUM 5
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y3_GPIO_NUM 13
|
||||
#else
|
||||
#define Y3_GPIO_NUM 12
|
||||
#endif
|
||||
#define Y2_GPIO_NUM 14
|
||||
#define VSYNC_GPIO_NUM 38
|
||||
#define HREF_GPIO_NUM 4
|
||||
#define PCLK_GPIO_NUM 3
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 15
|
||||
#define SIOD_GPIO_NUM 4
|
||||
#define SIOC_GPIO_NUM 5
|
||||
|
||||
#define Y2_GPIO_NUM 11
|
||||
#define Y3_GPIO_NUM 9
|
||||
#define Y4_GPIO_NUM 8
|
||||
#define Y5_GPIO_NUM 10
|
||||
#define Y6_GPIO_NUM 12
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y8_GPIO_NUM 17
|
||||
#define Y9_GPIO_NUM 16
|
||||
|
||||
#define VSYNC_GPIO_NUM 6
|
||||
#define HREF_GPIO_NUM 7
|
||||
#define PCLK_GPIO_NUM 13
|
||||
|
||||
#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 45
|
||||
#define SIOD_GPIO_NUM 1
|
||||
#define SIOC_GPIO_NUM 2
|
||||
|
||||
#define Y9_GPIO_NUM 48
|
||||
#define Y8_GPIO_NUM 46
|
||||
#define Y7_GPIO_NUM 8
|
||||
#define Y6_GPIO_NUM 7
|
||||
#define Y5_GPIO_NUM 4
|
||||
#define Y4_GPIO_NUM 41
|
||||
#define Y3_GPIO_NUM 40
|
||||
#define Y2_GPIO_NUM 39
|
||||
#define VSYNC_GPIO_NUM 6
|
||||
#define HREF_GPIO_NUM 42
|
||||
#define PCLK_GPIO_NUM 5
|
||||
|
||||
#else
|
||||
#error "Camera model not selected"
|
||||
#endif
|
5
ESP_sources/partitions.csv
Normal file
5
ESP_sources/partitions.csv
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x3d0000,
|
||||
fr, data, , 0x3e0000, 0x20000,
|
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Stage: Stéréovision sur ESP32
|
||||
|
||||
Ce dépot contient les sources python pour le tracking ainsi que celles pour les ESP32 et le modèle 3D de l'étui qui permet de les maintenir en place.
|
BIN
models/Holder V4.stl
Normal file
BIN
models/Holder V4.stl
Normal file
Binary file not shown.
42
tracking_sources/REAMDE.md
Normal file
42
tracking_sources/REAMDE.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Python sources for object tracking
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### With Nix
|
||||
|
||||
```bash
|
||||
nix-shell
|
||||
```
|
||||
|
||||
### Without Nix
|
||||
|
||||
requirements : Conda
|
||||
|
||||
```bash
|
||||
conda create --yes -q -n stage python=3.10 -c conda-forge
|
||||
conda activate stage
|
||||
conda install --yes -f conda-requirements.txt -c conda-forge
|
||||
```
|
||||
## Usage
|
||||
|
||||
|
||||
Tracking:
|
||||
```bash
|
||||
python tracking.py
|
||||
```
|
||||
|
||||
verify on a benchmarck of pictures
|
||||
```bash
|
||||
python verify.py
|
||||
```
|
||||
|
||||
Graph results:
|
||||
```bash
|
||||
python graphing.py results.csv
|
||||
```
|
||||
|
||||
Graph frametime:
|
||||
```bash
|
||||
python frametime.py
|
||||
```
|
7
tracking_sources/conda-requirements.txt
Normal file
7
tracking_sources/conda-requirements.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
opencv
|
||||
ultralytics
|
||||
numpy
|
||||
pytorch
|
||||
torchvision
|
||||
ffmpeg
|
||||
lap
|
5
tracking_sources/core_functions.py
Normal file
5
tracking_sources/core_functions.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
import pandas as pd
|
||||
|
||||
def read_table(path):
|
||||
df=pd.read_csv(path)
|
||||
return df.shape[0], df["percent"], df["angle"]
|
31
tracking_sources/frametime.py
Normal file
31
tracking_sources/frametime.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
import matplotlib.pyplot as plt
|
||||
|
||||
def plot_graph(file_path):
|
||||
# Read the file and extract the floats
|
||||
with open(file_path, 'r') as file:
|
||||
values1 = []
|
||||
values2 = []
|
||||
values3 = []
|
||||
for line in file:
|
||||
float1, float2, float3 = map(float, line.strip().split())
|
||||
values1.append(float1)
|
||||
values2.append(float2)
|
||||
values3.append(float3)
|
||||
|
||||
# Generate x-axis values (assuming each float pair is a data point)
|
||||
x_values = list(range(1, len(values1) + 1))
|
||||
|
||||
# Plot the graph
|
||||
plt.plot(x_values, values1, label='requete')
|
||||
plt.plot(x_values, values2, label='traitement') # Plot the graph
|
||||
plt.plot(x_values, values3, label='total')
|
||||
plt.title('Temps pour traiter une image')
|
||||
plt.xlabel("numero de l'image")
|
||||
plt.ylabel('temps (s)')
|
||||
plt.grid(True)
|
||||
plt.legend()
|
||||
plt.xlim(left=0)
|
||||
plt.ylim(bottom=0)
|
||||
plt.show()
|
||||
|
||||
plot_graph("frametime.txt")
|
45
tracking_sources/graphing.py
Normal file
45
tracking_sources/graphing.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Graphing script
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import sys
|
||||
|
||||
|
||||
# Read csv path
|
||||
args = sys.argv
|
||||
path = args[1]
|
||||
|
||||
# open csv
|
||||
df = pd.read_csv(path)
|
||||
print(df)
|
||||
|
||||
|
||||
# compute the error
|
||||
df["dr1m1"] = abs(df["r1m1"] - df["reel"])
|
||||
df["dr2m1"] = abs(df["r2m1"] - df["reel"])
|
||||
df["dr3m1"] = abs(df["r3m1"] - df["reel"])
|
||||
df["dr4m1"] = abs(df["r4m1"] - df["reel"])
|
||||
|
||||
|
||||
# Plotting the distance seen vs real
|
||||
plt.plot(df["reel"], df["reel"], label="Real")
|
||||
plt.plot(df["reel"], df["r1m1"], label="r1m1")
|
||||
plt.plot(df["reel"], df["r2m1"], label="r2m1")
|
||||
plt.plot(df["reel"], df["r3m1"], label="r3m1")
|
||||
plt.plot(df["reel"], df["r4m1"], label="r4m1")
|
||||
plt.xlabel("Distance (m)")
|
||||
plt.ylabel("Distance (m)")
|
||||
plt.title("Real vs Seen Distance")
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
# Plotting the error over distance
|
||||
# plt.plot(df["reel"], df["dr1m1"], label="r1m1")
|
||||
# plt.plot(df["reel"], df["dr2m1"], label="r2m1")
|
||||
# plt.plot(df["reel"], df["dr3m1"], label="r3m1")
|
||||
plt.plot(df["reel"], df["dr4m1"], label="r4m1")
|
||||
plt.xlabel("Distance (m)")
|
||||
plt.ylabel("Error (m)")
|
||||
plt.title("Tracking Error over Distance")
|
||||
plt.legend()
|
||||
plt.show()
|
10
tracking_sources/results.csv
Normal file
10
tracking_sources/results.csv
Normal file
|
@ -0,0 +1,10 @@
|
|||
reel,r1m1,r1m2,r2m1,r2m2,r3m1,r4m1
|
||||
2,1.92,1.72,1.8,1.72,2.02,2.21
|
||||
2.5,2.42,2.16,2.3,2.11,2.59,2.84
|
||||
3,3,2.6,2.78,2.53,3.16,3.49
|
||||
3.5,3.59,2.98,3.32,2.99,3.8,4.14
|
||||
4,4.24,3.45,3.94,3.29,4.43,4.84
|
||||
4.5,5.12,3.5,4.5,3.77,5.12,5.63
|
||||
5,5.63,4.14,5.1,4.27,5.83,6.25
|
||||
5.5,6.32,4.9,5.67,4.7,6.55,7.10
|
||||
6,7,5.19,6.32,5.1,,7.93
|
|
28
tracking_sources/shell.nix
Normal file
28
tracking_sources/shell.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ pkgs ? import <nixpkgs> {}}:
|
||||
let
|
||||
fhs = pkgs.buildFHSUserEnv {
|
||||
name = "my-fhs-environment";
|
||||
|
||||
targetPkgs = _: [
|
||||
pkgs.micromamba
|
||||
pkgs.zlib
|
||||
pkgs.libGL
|
||||
pkgs.glib
|
||||
pkgs.python310
|
||||
pkgs.pkg-config
|
||||
];
|
||||
|
||||
profile = ''
|
||||
set -e
|
||||
eval "$(micromamba shell hook --shell=posix)"
|
||||
export MAMBA_ROOT_PREFIX=${builtins.getEnv "PWD"}/.mamba
|
||||
if ! test -d $MAMBA_ROOT_PREFIX/envs/m2; then
|
||||
micromamba create --yes -q -n m2 python=3.10 -c conda-forge
|
||||
fi
|
||||
micromamba activate m2
|
||||
micromamba install --yes -f conda-requirements.txt -c conda-forge
|
||||
set +e
|
||||
'';
|
||||
};
|
||||
in fhs.env
|
||||
|
257
tracking_sources/tracking.py
Normal file
257
tracking_sources/tracking.py
Normal file
|
@ -0,0 +1,257 @@
|
|||
import cv2
|
||||
import urllib.request
|
||||
import requests
|
||||
import numpy as np
|
||||
import math
|
||||
import pandas as pd
|
||||
import asyncio
|
||||
import time
|
||||
import os
|
||||
import glob
|
||||
from core_functions import read_table
|
||||
from ultralytics import YOLO
|
||||
|
||||
def read_image_from_url(url):
|
||||
try:
|
||||
req = urllib.request.urlopen(url)
|
||||
img_arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
|
||||
return cv2.imdecode(img_arr, -1)
|
||||
except Exception as _:
|
||||
print("URL Error")
|
||||
exit(1)
|
||||
|
||||
def read_image_from_fs(path):
|
||||
return cv2.imread(path)
|
||||
|
||||
async def analyze(model, img, name):
|
||||
# Run YOLOv8 tracking on the frame, persisting tracks between frames
|
||||
# results = model(img, conf=conf, classes=classes)
|
||||
# results = model.track(img, conf=conf, classes=classes, persist=True)
|
||||
results = model.track(img, conf=conf, classes=classes, persist=True, max_det=1, imgsz=1600)
|
||||
|
||||
if draw:
|
||||
# Visualize the results on the frame
|
||||
annotated_frame = results[0].plot()
|
||||
# Display the annotated frame
|
||||
cv2.imshow(name, annotated_frame)
|
||||
|
||||
# Gather the coordinates of the box
|
||||
boxes = results[0].boxes
|
||||
if len(boxes) == 0:
|
||||
print("No objects detected in " + name)
|
||||
return -1, -1
|
||||
|
||||
x1, _, x2, _ = boxes.xyxyn[0].numpy()
|
||||
x = (x1 + x2) / 2
|
||||
width = x2 - x1
|
||||
|
||||
return x, width
|
||||
|
||||
def interpolate(ratio):
|
||||
# N = 9
|
||||
# cal_ratio = [0.06, 0.18, 0.28, 0.39, 0.49, 0.60, 0.70, 0.82, 0.92]
|
||||
# cal_angledeg = [-25.27, -19.20, -13.46, -6.68, -0.58, 6.40, 12.37, 18.86, 24.24]
|
||||
N, cal_ratio, cal_angledeg = read_table("configs/config4.csv")
|
||||
if trace:
|
||||
print(f"Interpolate {ratio}")
|
||||
for i in range(1, N):
|
||||
ratiomin = cal_ratio[i - 1]
|
||||
ratiomax = cal_ratio[i]
|
||||
anglemin = cal_angledeg[i - 1]
|
||||
anglemax = cal_angledeg[i]
|
||||
if ratiomin <= ratio < ratiomax:
|
||||
if trace:
|
||||
print(f" i={i}, Ratio[{i - 1}]={ratiomin}, Ratio[{i}]={ratiomax}")
|
||||
print(f" i={i}, Angledeg[{i - 1}]={anglemin}, Angledeg[{i}]={anglemax}")
|
||||
deltay = anglemax - anglemin
|
||||
deltax = ratiomax - ratiomin
|
||||
slope = deltay / deltax
|
||||
if trace:
|
||||
print(f" deltax={deltax}, deltay={deltay}, slope={slope}°/m")
|
||||
delta = ratio - ratiomin
|
||||
angle = anglemin + slope * delta
|
||||
if trace:
|
||||
print(f" delta={delta}, angle={angle}°")
|
||||
return angle
|
||||
print(f"Error: unable to interpolate {ratio}")
|
||||
exit(0)
|
||||
|
||||
|
||||
def estimate(leftd, rightd, alphar, betar, widthr, width):
|
||||
alphadeg, betadeg, thetadeg = 0.0, 0.0, 0.0
|
||||
alpharad, betarad, thetarad = 0.0, 0.0, 0.0
|
||||
alphatan, betatan, thetatan = 0.0, 0.0, 0.0
|
||||
gammadeg, gammarad, gammatan = 0.0, 0.0, 0.0
|
||||
distance = 0.0
|
||||
if trace:
|
||||
print("Estimation")
|
||||
# interpolate to get angles
|
||||
alphadeg = -interpolate(alphar)
|
||||
if trace:
|
||||
print(f" interpolate: alphar={alphar} (ratio) -> alphadeg={alphadeg}°")
|
||||
betadeg = interpolate(betar)
|
||||
if trace:
|
||||
print(f"interpolate: betar={betar} (ratio) -> betadeg={betadeg}°")
|
||||
gammadeg = interpolate(0.5 + widthr)
|
||||
if trace:
|
||||
print(f"interpolate: widthr={widthr} (ratio) -> gammadeg={gammadeg}°")
|
||||
# convert to radians
|
||||
alpharad = math.radians(alphadeg)
|
||||
if trace:
|
||||
print(f"to radians: alphadeg={alphadeg} -> alpharad={alpharad}")
|
||||
betarad = math.radians(betadeg)
|
||||
if trace:
|
||||
print(f"to radians: betadeg={betadeg} -> betarad={betarad}")
|
||||
# get tan
|
||||
alphatan = math.tan(alpharad)
|
||||
betatan = math.tan(betarad)
|
||||
if trace:
|
||||
print(f"tan(): alphatan={alphatan}, betatan={betatan}")
|
||||
# (x, y)
|
||||
y = (leftd + rightd) / (alphatan + betatan)
|
||||
x = y * alphatan - leftd
|
||||
if trace:
|
||||
print(f"position: x={x}, y={y}")
|
||||
# (distance, angle)
|
||||
distance_1 = math.sqrt(x * x + y * y)
|
||||
thetatan = x / y
|
||||
thetarad = math.atan(thetatan)
|
||||
thetadeg = math.degrees(thetarad)
|
||||
print(f"distance={distance_1}, thetatan={thetatan}, theta={thetadeg}, thetarad={thetarad}")
|
||||
# print(f"distance = {distance}")
|
||||
gammarad = math.radians(gammadeg)
|
||||
gammatan = math.tan(gammarad)
|
||||
distance_2 = width / gammatan
|
||||
print(f"distance={distance_2}, gammatan={gammatan}, gamma={gammadeg}, gammarad={gammarad}")
|
||||
return distance_1, distance_2, thetadeg
|
||||
|
||||
|
||||
|
||||
|
||||
async def get_image_stream(cap):
|
||||
ret, img = cap.read()
|
||||
if not ret:
|
||||
print("Error: Unable to read frame.")
|
||||
exit()
|
||||
return img
|
||||
|
||||
async def get_images_stream(l_cap, r_cap, l_imgs_buffer, r_imgs_buffer, n_image):
|
||||
current_img = n_image % 2
|
||||
l_img = await l_imgs_buffer[current_img]
|
||||
r_img = await r_imgs_buffer[current_img]
|
||||
l_imgs_buffer[current_img] = asyncio.create_task(get_image_stream(l_cap))
|
||||
r_imgs_buffer[current_img] = asyncio.create_task(get_image_stream(r_cap))
|
||||
return l_img, r_img
|
||||
|
||||
def init_stream(url):
|
||||
# Set quality
|
||||
requests.get(url + "/control?var=framesize&val=13")
|
||||
# requests.get(url + "/control?var=framesize&val=8")
|
||||
# Open stream
|
||||
stream_url = url + ":81/stream"
|
||||
print(stream_url)
|
||||
cap = cv2.VideoCapture(stream_url)
|
||||
if not cap.isOpened():
|
||||
print("Error: Unable to open the stream.")
|
||||
exit()
|
||||
return cap
|
||||
|
||||
|
||||
async def main():
|
||||
print("Loading models")
|
||||
l_model = YOLO('yolov8n.pt')
|
||||
r_model = YOLO('yolov8n.pt')
|
||||
l_model()
|
||||
r_model()
|
||||
|
||||
|
||||
print("Init streams")
|
||||
l_cap = init_stream(l_url)
|
||||
r_cap = init_stream(r_url)
|
||||
ti1 = asyncio.create_task(get_image_stream(l_cap))
|
||||
ti2 = asyncio.create_task(get_image_stream(r_cap))
|
||||
|
||||
n_images = -1
|
||||
|
||||
results = (0, 0, 0)
|
||||
l_img_save = None
|
||||
r_img_save = None
|
||||
|
||||
|
||||
print("Loop start")
|
||||
init_time = time.time()
|
||||
with open("frametime.txt", 'w') as file:
|
||||
while True:
|
||||
n_images += 1
|
||||
st_request = time.time()
|
||||
|
||||
l_img = await ti1
|
||||
r_img = await ti2
|
||||
ti1 = asyncio.create_task(get_image_stream(l_cap))
|
||||
ti2 = asyncio.create_task(get_image_stream(r_cap))
|
||||
dt_request = time.time() - st_request
|
||||
print(f"imgs read in {dt_request}")
|
||||
|
||||
|
||||
st_analyze = time.time()
|
||||
t1 = asyncio.create_task(analyze(l_model, l_img, "left"))
|
||||
t2 = asyncio.create_task(analyze(r_model, r_img, "right"))
|
||||
lx, l_width = await t1
|
||||
rx, r_width = await t2
|
||||
|
||||
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||
break
|
||||
|
||||
if n_images == 100:
|
||||
break
|
||||
|
||||
|
||||
|
||||
width = (l_width + r_width) / 2
|
||||
if lx != -1 and rx != -1:
|
||||
results = estimate(0, 0.72, lx, rx, width, obj_size)
|
||||
l_img_save = l_img
|
||||
r_img_save = r_img
|
||||
|
||||
dt_analyze = time.time() - st_analyze
|
||||
print(f"analyse done in {dt_analyze}")
|
||||
dt_total = time.time() - st_request
|
||||
print(f"total time {dt_total}")
|
||||
file.write(f"{dt_request} {dt_analyze} {dt_total}\n")
|
||||
print("\n\n\n")
|
||||
|
||||
l_cap.release()
|
||||
r_cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
print("\n\n\n")
|
||||
|
||||
total_time = time.time() - init_time
|
||||
print(f"total time {total_time}")
|
||||
print(f"avrg time {total_time / n_images}")
|
||||
print(f"resutlts {results}")
|
||||
|
||||
folder_path = 'imgs/'
|
||||
num_files = len(glob.glob(os.path.join(folder_path, '*'))) / 2
|
||||
cv2.imwrite(folder_path + str(num_files) + "_left.png", l_img_save)
|
||||
cv2.imwrite(folder_path + str(num_files) + "_right.png", r_img_save)
|
||||
print("done saving")
|
||||
|
||||
|
||||
|
||||
|
||||
draw = True;
|
||||
trace = False;
|
||||
|
||||
# classes = None
|
||||
# classes = [32] # Sport ball
|
||||
classes = [39] # Sport ball
|
||||
# classes = [64] # Mouse
|
||||
|
||||
conf = 0.05
|
||||
obj_size = 0.08
|
||||
|
||||
l_url = "http://192.168.0.151"
|
||||
r_url = "http://192.168.0.152"
|
||||
|
||||
asyncio.run(main())
|
168
tracking_sources/verif.py
Normal file
168
tracking_sources/verif.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
import os
|
||||
import cv2
|
||||
import math
|
||||
from core_functions import read_table
|
||||
from ultralytics import YOLO
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def analyze(model, img, name):
|
||||
# Run YOLOv8 tracking on the frame, persisting tracks between frames
|
||||
# results = model(img, conf=conf, classes=classes)
|
||||
# results = model.track(img, conf=conf, classes=classes, persist=True)
|
||||
results = model.track(img, conf=0.05, classes=[39], persist=True, max_det=1, imgsz=1600)
|
||||
|
||||
# Gather the coordinates of the box
|
||||
boxes = results[0].boxes
|
||||
if len(boxes) == 0:
|
||||
print("No objects detected in " + name)
|
||||
return -1, -1
|
||||
|
||||
x1, _, x2, _ = boxes.xyxyn[0].numpy()
|
||||
x = (x1 + x2) / 2
|
||||
width = x2 - x1
|
||||
|
||||
return x, width
|
||||
|
||||
def interpolate(ratio):
|
||||
# N = 9
|
||||
# cal_ratio = [0.06, 0.18, 0.28, 0.39, 0.49, 0.60, 0.70, 0.82, 0.92]
|
||||
# cal_angledeg = [-25.27, -19.20, -13.46, -6.68, -0.58, 6.40, 12.37, 18.86, 24.24]
|
||||
N, cal_ratio, cal_angledeg = read_table("configs/config4.csv")
|
||||
print(cal_angledeg)
|
||||
if trace:
|
||||
print(f"Interpolate {ratio}")
|
||||
for i in range(1, N):
|
||||
ratiomin = cal_ratio[i - 1]
|
||||
ratiomax = cal_ratio[i]
|
||||
anglemin = cal_angledeg[i - 1]
|
||||
anglemax = cal_angledeg[i]
|
||||
if ratiomin <= ratio < ratiomax:
|
||||
if trace:
|
||||
print(f" i={i}, Ratio[{i - 1}]={ratiomin}, Ratio[{i}]={ratiomax}")
|
||||
print(f" i={i}, Angledeg[{i - 1}]={anglemin}, Angledeg[{i}]={anglemax}")
|
||||
deltay = anglemax - anglemin
|
||||
deltax = ratiomax - ratiomin
|
||||
slope = deltay / deltax
|
||||
if trace:
|
||||
print(f" deltax={deltax}, deltay={deltay}, slope={slope}°/m")
|
||||
delta = ratio - ratiomin
|
||||
angle = anglemin + slope * delta
|
||||
if trace:
|
||||
print(f" delta={delta}, angle={angle}°")
|
||||
return angle
|
||||
print(f"Error: unable to interpolate {ratio}")
|
||||
exit(0)
|
||||
|
||||
|
||||
def estimate(leftd, rightd, alphar, betar, widthr, width):
|
||||
alphadeg, betadeg, thetadeg = 0.0, 0.0, 0.0
|
||||
alpharad, betarad, thetarad = 0.0, 0.0, 0.0
|
||||
alphatan, betatan, thetatan = 0.0, 0.0, 0.0
|
||||
gammadeg, gammarad, gammatan = 0.0, 0.0, 0.0
|
||||
distance = 0.0
|
||||
if trace:
|
||||
print("Estimation")
|
||||
# interpolate to get angles
|
||||
alphadeg = -interpolate(alphar)
|
||||
if trace:
|
||||
print(f" interpolate: alphar={alphar} (ratio) -> alphadeg={alphadeg}°")
|
||||
betadeg = interpolate(betar)
|
||||
if trace:
|
||||
print(f"interpolate: betar={betar} (ratio) -> betadeg={betadeg}°")
|
||||
gammadeg = interpolate(0.5 + widthr)
|
||||
if trace:
|
||||
print(f"interpolate: widthr={widthr} (ratio) -> gammadeg={gammadeg}°")
|
||||
# convert to radians
|
||||
alpharad = math.radians(alphadeg)
|
||||
if trace:
|
||||
print(f"to radians: alphadeg={alphadeg} -> alpharad={alpharad}")
|
||||
betarad = math.radians(betadeg)
|
||||
if trace:
|
||||
print(f"to radians: betadeg={betadeg} -> betarad={betarad}")
|
||||
# get tan
|
||||
alphatan = math.tan(alpharad)
|
||||
betatan = math.tan(betarad)
|
||||
if trace:
|
||||
print(f"tan(): alphatan={alphatan}, betatan={betatan}")
|
||||
# (x, y)
|
||||
y = (leftd + rightd) / (alphatan + betatan)
|
||||
x = y * alphatan - leftd
|
||||
if trace:
|
||||
print(f"position: x={x}, y={y}")
|
||||
# (distance, angle)
|
||||
distance_1 = math.sqrt(x * x + y * y)
|
||||
thetatan = x / y
|
||||
thetarad = math.atan(thetatan)
|
||||
thetadeg = math.degrees(thetarad)
|
||||
print(f"distance={distance_1}, thetatan={thetatan}, theta={thetadeg}, thetarad={thetarad}")
|
||||
# print(f"distance = {distance}")
|
||||
gammarad = math.radians(gammadeg)
|
||||
gammatan = math.tan(gammarad)
|
||||
distance_2 = width / gammatan
|
||||
print(f"distance={distance_2}, gammatan={gammatan}, gamma={gammadeg}, gammarad={gammarad}")
|
||||
return distance_1, distance_2, thetadeg
|
||||
|
||||
|
||||
trace = False
|
||||
folder_path = "imgs/"
|
||||
model = YOLO('yolov8n.pt')
|
||||
|
||||
image_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff', '.tif'))]
|
||||
|
||||
# Sort the image files to maintain a consistent order
|
||||
image_files.sort()
|
||||
|
||||
dist = [2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6]
|
||||
t_results = []
|
||||
|
||||
# Iterate over the images in pairs
|
||||
for i in range(0, len(image_files), 2):
|
||||
# Check if there are at least two images remaining
|
||||
if i + 1 < len(image_files):
|
||||
img1_path = os.path.join(folder_path, image_files[i])
|
||||
img2_path = os.path.join(folder_path, image_files[i + 1])
|
||||
|
||||
# Read the images
|
||||
img1 = cv2.imread(img1_path)
|
||||
img2 = cv2.imread(img2_path)
|
||||
|
||||
# Process the images (example: print their names)
|
||||
print(f'Processing images: {image_files[i]} and {image_files[i + 1]}')
|
||||
|
||||
lx, l_width = analyze(model, img1, "left")
|
||||
rx, r_width = analyze(model, img2, "right")
|
||||
width = (l_width + r_width) / 2
|
||||
|
||||
results = estimate(0, 0.72, lx, rx, width, 0.08)
|
||||
print("\n\n\n")
|
||||
t_results.append(results[0])
|
||||
|
||||
|
||||
# (Optional) Display the images
|
||||
cv2.imshow('Image 1', img1)
|
||||
cv2.imshow('Image 2', img2)
|
||||
else:
|
||||
# If there's an odd number of images, the last one will be left without a pair
|
||||
print(f'Single image left without a pair: {image_files[i]}')
|
||||
|
||||
print("results")
|
||||
print(t_results)
|
||||
|
||||
errors = [abs(dist[i]-t_results[i]) for i in range(len(dist))]
|
||||
print("errors")
|
||||
print(errors)
|
||||
|
||||
cv2.waitKey(0) # Wait for a key press to close the images
|
||||
cv2.destroyAllWindows()
|
||||
# Plotting the error over distance
|
||||
# plt.plot(df["reel"], df["dr1m1"], label="r1m1")
|
||||
# plt.plot(df["reel"], df["dr2m1"], label="r2m1")
|
||||
# plt.plot(df["reel"], df["dr3m1"], label="r3m1")
|
||||
plt.plot(dist, errors)
|
||||
plt.xlabel("Distance (m)")
|
||||
plt.ylabel("Error (m)")
|
||||
plt.title("Tracking Error over Distance")
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
|
BIN
tracking_sources/yolov8n.pt
Normal file
BIN
tracking_sources/yolov8n.pt
Normal file
Binary file not shown.
Loading…
Reference in a new issue