Skip to content

Commit

Permalink
good improvements, but converter experimental feature
Browse files Browse the repository at this point in the history
  • Loading branch information
cnadler86 committed Oct 28, 2024
1 parent 7b1d6b3 commit 5d993e5
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 7 deletions.
4 changes: 2 additions & 2 deletions examples/ESP32cam.html → examples/CameraSettings.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
</head>
<body>
<div class="title-container">
<h1>ESP32 Camera Stream</h1>
<h1>Micropython Camera Stream</h1>
</div>
<div class="container">
<div class="settings-container">
Expand Down Expand Up @@ -309,7 +309,7 @@ <h1>ESP32 Camera Stream</h1>
</div>
</div>
<div class="video-container">
<img src="/stream">
<img src="/stream" alt="Loading stream...">
</div>
</div>
</body>
Expand Down
9 changes: 7 additions & 2 deletions examples/CameraSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,25 @@

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()

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()

Expand Down
File renamed without changes.
96 changes: 96 additions & 0 deletions examples/benchmark.py
Original file line number Diff line number Diff line change
@@ -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

15 changes: 13 additions & 2 deletions src/modcamera.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"));
}
Expand All @@ -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)) {
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/modcamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 5d993e5

Please sign in to comment.