Skip to content

Commit fa295e7

Browse files
camtest: add webcam support
1 parent 35303d3 commit fa295e7

File tree

3 files changed

+46
-16
lines changed

3 files changed

+46
-16
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ Building for desktop
107107
====================
108108
Building to run as an app on the Linux desktop or MacOS (untested) is supported.
109109

110-
To do so, make sure you have the necessary dependencies (see https://github.com/lvgl-micropython/) and then run:
110+
To do so, make sure you have the necessary dependencies:
111+
- see https://github.com/lvgl-micropython/
112+
- sudo apt install libv4l-dev # for webcam.c
113+
114+
...and then run:
111115

112116
```
113117
~/sources/PiggyOS/scripts/build_lvgl_micropython.sh unix

c_mpos/src/webcam.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//#include <Python.h>
21
#include <stdio.h>
32
#include <stdlib.h>
43
#include <fcntl.h>
@@ -17,8 +16,8 @@
1716

1817
// Default webcam device
1918
#define VIDEO_DEVICE "/dev/video0"
20-
#define WIDTH 640
21-
#define HEIGHT 480
19+
#define WIDTH 240
20+
#define HEIGHT 240
2221

2322
// Structure to hold webcam state
2423
typedef struct {
@@ -34,6 +33,27 @@ static void yuyv_to_grayscale(uint8_t *src, uint8_t *dst, size_t width, size_t h
3433
}
3534
}
3635

36+
// Resize 640x480 grayscale to 240x240
37+
static void resize_640x480_to_240x240(uint8_t *src, uint8_t *dst) {
38+
const int src_width = 640;
39+
const int src_height = 480;
40+
const int dst_width = 240;
41+
const int dst_height = 240;
42+
43+
// Scaling factors
44+
float x_ratio = (float)src_width / dst_width;
45+
float y_ratio = (float)src_height / dst_height;
46+
47+
for (int y = 0; y < dst_height; y++) {
48+
for (int x = 0; x < dst_width; x++) {
49+
// Nearest-neighbor interpolation
50+
int src_x = (int)(x * x_ratio);
51+
int src_y = (int)(y * y_ratio);
52+
dst[y * dst_width + x] = src[src_y * src_width + src_x];
53+
}
54+
}
55+
}
56+
3757
// Function to capture a grayscale image
3858
static mp_obj_t webcam_capture_grayscale(void) {
3959
webcam_t cam = { .fd = -1, .buffer = NULL, .buffer_length = 0 };

internal_filesystem/apps/com.example.camtest/assets/camtest.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
image_dsc = None
1313
image = None
1414
qr_label = None
15+
use_webcam = False
1516

1617

1718
def print_qr_buffer(buffer):
@@ -92,12 +93,12 @@ def qr_button_click(e):
9293

9394

9495
def try_capture():
95-
global current_cam_buffer, image_dsc, image
96-
if cam.frame_available():
97-
# Get new memoryview from camera
96+
global current_cam_buffer, image_dsc, image, use_webcam
97+
if use_webcam:
98+
new_cam_buffer = webcam.capture_grayscale()
99+
elif cam.frame_available():
98100
new_cam_buffer = cam.capture() # Returns memoryview
99-
# Verify buffer size
100-
#if len(new_cam_buffer) != width * height * 2:
101+
if len(new_cam_buffer):
101102
# print("Invalid buffer size:", len(new_cam_buffer))
102103
# cam.free_buffer()
103104
# return
@@ -107,12 +108,11 @@ def try_capture():
107108
image.set_src(image_dsc)
108109
#image.invalidate() #does not work
109110
# Free the previous buffer (if any) after setting new data
110-
if current_cam_buffer is not None:
111+
if current_cam_buffer is not None and not use_webcam:
111112
cam.free_buffer() # Free the old buffer
112113
current_cam_buffer = new_cam_buffer # Store new buffer reference
113114

114115

115-
116116
def build_ui():
117117
global image, image_dsc,qr_label
118118
cont = lv.obj(appscreen)
@@ -195,16 +195,22 @@ def init_cam():
195195

196196
cam = init_cam()
197197
if not cam:
198-
print("init cam failed, retrying...")
199-
time.sleep(5)
200-
cam = init_cam()
198+
print("init cam failed, retrying with webcam...")
199+
try:
200+
import webcam
201+
current_cam_buffer = webcam.capture_grayscale()
202+
use_webcam = True
203+
except Exception as e:
204+
print(f"camtest.py: webcam exception: {e}")
201205

202-
if cam:
206+
if cam or use_webcam:
203207
build_ui()
204208
while appscreen == lv.screen_active() and keepgoing is True:
205209
try_capture()
206210
time.sleep_ms(100) # Allow for the MicroPython REPL to still work. Reducing it doesn't seem to affect the on-display FPS.
207211
print("App backgrounded, deinitializing camera...")
208212
cam.deinit()
209-
show_launcher()
213+
else:
214+
print("No camera found, exiting...")
210215

216+
show_launcher()

0 commit comments

Comments
 (0)