You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
camtest: add webcam support
This commit is contained in:
@@ -107,7 +107,11 @@ Building for desktop
|
||||
====================
|
||||
Building to run as an app on the Linux desktop or MacOS (untested) is supported.
|
||||
|
||||
To do so, make sure you have the necessary dependencies (see https://github.com/lvgl-micropython/) and then run:
|
||||
To do so, make sure you have the necessary dependencies:
|
||||
- see https://github.com/lvgl-micropython/
|
||||
- sudo apt install libv4l-dev # for webcam.c
|
||||
|
||||
...and then run:
|
||||
|
||||
```
|
||||
~/sources/PiggyOS/scripts/build_lvgl_micropython.sh unix
|
||||
|
||||
+23
-3
@@ -1,4 +1,3 @@
|
||||
//#include <Python.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
@@ -17,8 +16,8 @@
|
||||
|
||||
// Default webcam device
|
||||
#define VIDEO_DEVICE "/dev/video0"
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
#define WIDTH 240
|
||||
#define HEIGHT 240
|
||||
|
||||
// Structure to hold webcam state
|
||||
typedef struct {
|
||||
@@ -34,6 +33,27 @@ static void yuyv_to_grayscale(uint8_t *src, uint8_t *dst, size_t width, size_t h
|
||||
}
|
||||
}
|
||||
|
||||
// Resize 640x480 grayscale to 240x240
|
||||
static void resize_640x480_to_240x240(uint8_t *src, uint8_t *dst) {
|
||||
const int src_width = 640;
|
||||
const int src_height = 480;
|
||||
const int dst_width = 240;
|
||||
const int dst_height = 240;
|
||||
|
||||
// Scaling factors
|
||||
float x_ratio = (float)src_width / dst_width;
|
||||
float y_ratio = (float)src_height / dst_height;
|
||||
|
||||
for (int y = 0; y < dst_height; y++) {
|
||||
for (int x = 0; x < dst_width; x++) {
|
||||
// Nearest-neighbor interpolation
|
||||
int src_x = (int)(x * x_ratio);
|
||||
int src_y = (int)(y * y_ratio);
|
||||
dst[y * dst_width + x] = src[src_y * src_width + src_x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to capture a grayscale image
|
||||
static mp_obj_t webcam_capture_grayscale(void) {
|
||||
webcam_t cam = { .fd = -1, .buffer = NULL, .buffer_length = 0 };
|
||||
|
||||
@@ -12,6 +12,7 @@ current_cam_buffer = None
|
||||
image_dsc = None
|
||||
image = None
|
||||
qr_label = None
|
||||
use_webcam = False
|
||||
|
||||
|
||||
def print_qr_buffer(buffer):
|
||||
@@ -92,12 +93,12 @@ def qr_button_click(e):
|
||||
|
||||
|
||||
def try_capture():
|
||||
global current_cam_buffer, image_dsc, image
|
||||
if cam.frame_available():
|
||||
# Get new memoryview from camera
|
||||
global current_cam_buffer, image_dsc, image, use_webcam
|
||||
if use_webcam:
|
||||
new_cam_buffer = webcam.capture_grayscale()
|
||||
elif cam.frame_available():
|
||||
new_cam_buffer = cam.capture() # Returns memoryview
|
||||
# Verify buffer size
|
||||
#if len(new_cam_buffer) != width * height * 2:
|
||||
if len(new_cam_buffer):
|
||||
# print("Invalid buffer size:", len(new_cam_buffer))
|
||||
# cam.free_buffer()
|
||||
# return
|
||||
@@ -107,12 +108,11 @@ def try_capture():
|
||||
image.set_src(image_dsc)
|
||||
#image.invalidate() #does not work
|
||||
# Free the previous buffer (if any) after setting new data
|
||||
if current_cam_buffer is not None:
|
||||
if current_cam_buffer is not None and not use_webcam:
|
||||
cam.free_buffer() # Free the old buffer
|
||||
current_cam_buffer = new_cam_buffer # Store new buffer reference
|
||||
|
||||
|
||||
|
||||
def build_ui():
|
||||
global image, image_dsc,qr_label
|
||||
cont = lv.obj(appscreen)
|
||||
@@ -195,16 +195,22 @@ def init_cam():
|
||||
|
||||
cam = init_cam()
|
||||
if not cam:
|
||||
print("init cam failed, retrying...")
|
||||
time.sleep(5)
|
||||
cam = init_cam()
|
||||
print("init cam failed, retrying with webcam...")
|
||||
try:
|
||||
import webcam
|
||||
current_cam_buffer = webcam.capture_grayscale()
|
||||
use_webcam = True
|
||||
except Exception as e:
|
||||
print(f"camtest.py: webcam exception: {e}")
|
||||
|
||||
if cam:
|
||||
if cam or use_webcam:
|
||||
build_ui()
|
||||
while appscreen == lv.screen_active() and keepgoing is True:
|
||||
try_capture()
|
||||
time.sleep_ms(100) # Allow for the MicroPython REPL to still work. Reducing it doesn't seem to affect the on-display FPS.
|
||||
print("App backgrounded, deinitializing camera...")
|
||||
cam.deinit()
|
||||
show_launcher()
|
||||
else:
|
||||
print("No camera found, exiting...")
|
||||
|
||||
show_launcher()
|
||||
|
||||
Reference in New Issue
Block a user