yolov8 可以将图片保存为 jpg
from ultralytics import YOLOimport cv2# 加载模型model = YOLO('yolov8n.pt')# 预测(不自动保存)results = model('input.jpg', save=False)# 获取带标注的图片(numpy数组)annotated_frame = results[0].plot() # 绘制所有检测框# 保存为JPGcv2.imwrite('output.jpg', annotated_frame)# 或转换为RGB后保存(OpenCV默认BGR)from PIL import Imagergb_frame = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)Image.fromarray(rgb_frame).save('output_rgb.jpg', quality=95)上面仅仅是 实例代码,不能完整执行;
那么我们如何将这个结果通过uvc-gadget呢?
下载 编译 uvc-gadget
编译 uvc-gadget程序
git clone https://gitlab.freedesktop.org/camera/uvc-gadget.git我的代码是从这里下载的,编译方法参加这里的文档交叉编译
more cross-arm.txt [binaries]c = 'aarch64-linux-gnu-gcc'cpp = 'aarch64-linux-gnu-g++'ar = 'aarch64-linux-gnu-ar'windres = 'aarch64-linux-gnu-windres'strip = 'aarch64-linux-gnu-strip'exe_wrapper = 'wine64'[host_machine]system = 'linux'cpu_family = 'x86_64'cpu = 'x86_64'endian = 'little'编译后会生成
file build/src/uvc-gadgetbuild/src/uvc-gadget: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=373fb1f9f6f6d8cdaa8036dc05ad5751641fd1af, for GNU/Linux 3.7.0, with debug_info, not stripped方法一
在板子上执行
./uvc-gadget uvc.0 -i output.jpg但是这时候 output.jpg 不会自动更新 需要修改程序
我们需要修改程序: uvc-gadget$ vim lib/jpg-source.c
static void jpg_source_fill_buffer(struct video_source *s, struct video_buffer *buf){ struct jpg_source *src = to_jpg_source(s); unsigned int size; reload_jpeg(s); /* * Nothing currently stops the user from providing a source file which is * larger than the buffer size calculated from the format we have set. * Clamp the size of the buffer we copy to be sure we don't overflow the * buffer we was allocated to receive it. */ size = min(src->imgsize, buf->size); memcpy(buf->mem, src->imgdata, size); buf->bytesused = size; /* * Wait for the timer to elapse to ensure that our configured frame rate * is adhered to. */ if (src->streaming) timer_wait(src->timer);}这里增加了 reload_jpeg函数 ,内容如下:
#define to_jpg_source(s) container_of(s, struct jpg_source, src)static void reload_jpeg(struct video_source *s){ struct jpg_source *src = to_jpg_source(s); int fd; int ret; if (src->imgdata) free(src->imgdata); fd = open(src->stream_path, O_RDONLY); if (fd == -1) { printf("Unable to open MJPEG image '%s'\n", src->stream_path); return ; } src->imgsize = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); src->imgdata = malloc(src->imgsize); if (src->imgdata == NULL) { printf("Unable to allocate memory for MJPEG image\n"); return ; } ret = read(fd, src->imgdata, src->imgsize); if (ret < 0) { fprintf(stderr, "error reading data from %s: %d\n", src->stream_path, errno); return ; } close(fd);}方法二、
需要修改 main.c 让其变成一个库 不在是 一个可执行文件把
vc-gadget$ ls lib/compat events.c libcamera-source.cpp meson.build-shared slideshow-source.c test-source.c tools.h uvc-formats.h v4l2.c v4l2-source.c video-buffers.hconfigfs.c jpg-source.c meson.build mjpeg_encoder.cpp stream.c timer.c uvc.c uvc.h v4l2.h video-buffers.c video-source.c嵌入到项目
修改 src/main.c
让其 入口main 函数变成一个 线程入口,参数还是传递 uvc.0 -i output.jpg 这个时候 这些都不变。
注意 真的要放一个 output.jpg文件
修改 reload_jpg 函数
直接将 yolov8 输出的 jpg 数据不存放到硬盘, 复制到 src 里即可。
src->imgdata, src->imgsize