diff --git a/examples/ESP32cam.html b/examples/CameraSettings.html similarity index 99% rename from examples/ESP32cam.html rename to examples/CameraSettings.html index 8e35f59..27e7447 100644 --- a/examples/ESP32cam.html +++ b/examples/CameraSettings.html @@ -161,7 +161,7 @@
-

ESP32 Camera Stream

+

Micropython Camera Stream

@@ -309,7 +309,7 @@

ESP32 Camera Stream

- + Loading stream...
diff --git a/examples/CameraSettings.py b/examples/CameraSettings.py index 2ce802f..c8f61fd 100644 --- a/examples/CameraSettings.py +++ b/examples/CameraSettings.py @@ -17,12 +17,14 @@ print(f'Connected! IP: {station.ifconfig()[0]}. Open this IP in your browser') -with open("ESP32cam.html", 'r') as file: +with open("CameraSettings.html", 'r') as file: html = file.read() async def stream_camera(writer): try: cam.init() + if not cam.get_bmp_out() and cam.get_pixel_format() != PixelFormat.JPEG: + cam.set_bmp_out(True) writer.write(b'HTTP/1.1 200 OK\r\nContent-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n') await writer.drain() @@ -30,7 +32,10 @@ async def stream_camera(writer): while True: frame = cam.capture() if frame: - writer.write(b'--frame\r\nContent-Type: image/jpeg\r\n\r\n') + if cam.get_pixel_format() == PixelFormat.JPEG: + writer.write(b'--frame\r\nContent-Type: image/jpeg\r\n\r\n') + else: + writer.write(b'--frame\r\nContent-Type: image/bmp\r\n\r\n') writer.write(frame) await writer.drain() diff --git a/examples/WebCam.py b/examples/SimpleWebCam.py similarity index 100% rename from examples/WebCam.py rename to examples/SimpleWebCam.py diff --git a/examples/benchmark.py b/examples/benchmark.py new file mode 100644 index 0000000..7c7e433 --- /dev/null +++ b/examples/benchmark.py @@ -0,0 +1,96 @@ +from camera import Camera, FrameSize, PixelFormat +import time +import gc +gc.enable() + +def measure_fps(duration=2): + start_time = time.time() + while time.time() - start_time < 0.5: + cam.capture() + + start_time = time.time() + frame_count = 0 + + while time.time() - start_time < duration: + cam.capture() + frame_count += 1 + + end_time = time.time() + fps = frame_count / (end_time - start_time) + return fps + +def print_summary_table(results): + print("\nSummary Table (FPS values):") + + pixel_formats = list(results.keys()) + print(f"{'Frame Size':<15}", end="") + for p in pixel_formats: + print(f"{p:<15}", end="") + print() + + frame_size_names = {getattr(FrameSize, f): f for f in dir(FrameSize) if not f.startswith('_')} + frame_sizes = list(next(iter(results.values())).keys()) + + for f in frame_sizes: + frame_size_name = frame_size_names.get(f, str(f)) + print(f"{frame_size_name:<15}", end="") + for p in pixel_formats: + fps = results[p].get(f, "N/A") + print(f"{fps:<15}", end="") + print() + +if __name__ == "__main__": + cam = Camera() + results = {} + + try: + for p in dir(PixelFormat): + if not p.startswith('_'): + p_value = getattr(PixelFormat, p) + if p_value == PixelFormat.RGB888 and cam.get_sensor_name() == "OV2640": + continue + try: + cam.reconfigure(pixel_format=p_value) + results[p] = {} + except Exception as e: + print('ERR:', e) + continue + + for f in dir(FrameSize): + if not f.startswith('_'): + f_value = getattr(FrameSize, f) + if f_value > cam.get_max_frame_size(): + continue + gc.collect() + print('Set', p, f, ':') + + try: + cam.reconfigure(frame_size=f_value) + time.sleep_ms(10) + img = cam.capture() + + if img: + print('---> Image size:', len(img)) + fps = measure_fps(2) + print(f"---> FPS: {fps}") + results[p][f_value] = fps # FPS in Dictionary speichern + else: + print('No image captured') + results[p][f_value] = 'No image' + + print(f"---> Free Memory: {gc.mem_free()}") + except Exception as e: + print('ERR:', e) + results[p][f_value] = 'ERR' + finally: + time.sleep_ms(250) + gc.collect() + print('') + + except KeyboardInterrupt: + print("\nScript interrupted by user.") + + finally: + cam.deinit() + print_summary_table(results) # Tabelle am Ende ausgeben + diff --git a/src/modcamera.c b/src/modcamera.c index 56aee8e..e29a01a 100644 --- a/src/modcamera.c +++ b/src/modcamera.c @@ -90,6 +90,10 @@ static inline int get_mapped_jpeg_quality(int8_t quality) { return map(quality, 0, 100, 63, 0); } +// static bool validate_pixel_format(mp_camera_obj_t *self, mp_camera_pixformat_t pixel_format) { + +// } + // Camera HAL Funcitons void mp_camera_hal_construct( mp_camera_obj_t *self, @@ -247,7 +251,7 @@ void mp_camera_hal_reconfigure(mp_camera_obj_t *self, mp_camera_framesize_t fram } } -mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, mp_camera_pixformat_t out_format) { +mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format) { if (!self->initialized) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to capture image: Camera not initialized")); } @@ -271,7 +275,7 @@ mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, mp_camera_pixformat_t out_ return mp_const_none; } - if (out_format != self->camera_config.pixel_format) { + if (out_format >= 0 && (mp_camera_pixformat_t)out_format != self->camera_config.pixel_format) { switch (out_format) { case PIXFORMAT_JPEG: if (frame2jpg(self->captured_buffer, self->camera_config.jpeg_quality, &out_buf, &out_len)) { @@ -473,10 +477,17 @@ void mp_camera_hal_set_frame_size(mp_camera_obj_t * self, framesize_t value) { if (!self->initialized) { mp_raise_ValueError(MP_ERROR_TEXT("Camera not initialized")); } + sensor_t *sensor = esp_camera_sensor_get(); if (!sensor->set_framesize) { mp_raise_ValueError(MP_ERROR_TEXT("No attribute frame_size")); } + + if (self->captured_buffer) { + esp_camera_return_all(); + self->captured_buffer = NULL; + } + if (sensor->set_framesize(sensor, value) < 0) { mp_raise_ValueError(MP_ERROR_TEXT("Invalid setting for frame_size")); } else { diff --git a/src/modcamera.h b/src/modcamera.h index 1fd4643..1e1305b 100644 --- a/src/modcamera.h +++ b/src/modcamera.h @@ -198,7 +198,7 @@ extern void mp_camera_hal_reconfigure(mp_camera_obj_t *self, mp_camera_framesize * @param out_format Output pixelformat format. * @return Captured image as micropython object. */ -extern mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, mp_camera_pixformat_t out_format); +extern mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format); /** * @brief Table mapping pixel formats API to their corresponding values at HAL.