新闻详情

新闻详情

首页 / 资讯中心 / 详情

RK3588摄像头图像采集与YOLOv5s推理实战指南

发布时间:2026/10/1 7:29:32来源:尧图网络
RK3588摄像头图像采集与YOLOv5s推理实战指南
1. 为什么香橙派RK3588上“抓一帧推理”比树莓派难十倍——先破掉三个认知陷阱你手里的香橙派RK3588板子不是一块插上USB摄像头就能跑OpenCV的树莓派。它是一台带NPU、双MIPI CSI接口、支持4K60 HDR视频输入的嵌入式工作站但恰恰是这种“高性能”让初学者在第一步——“抓一帧图像”——就卡死超过72小时。我见过太多人反复重装Ubuntu、换OpenCV版本、查dmesg日志到凌晨三点最后发现根本问题不在代码而在硬件抽象层的错位理解。核心陷阱有三个第一误以为cv2.VideoCapture(0)在RK3588上和x86桌面机一样直通UVC驱动第二把“能用ls /dev/video*看到设备”等同于“能被OpenCV正常读取”第三完全忽略RK3588的VPU视频处理单元与NPU神经网络处理器对图像数据格式的硬性约束——YOLOv5s模型训练时用的是BGR 3通道 uint8但RK3588默认MIPI摄像头输出的是YUV422或NV12而USB UVC设备又常以MJPEG压缩流形式存在。这三者之间没有自动转换OpenCV不会替你做色彩空间重排、解压缩、内存对齐它只认你喂给它的那一块连续、格式正确、内存可映射的buffer。所以本篇不从“写Python代码”开始而是从物理信号链路切入摄像头→MIPI/USB PHY→V4L2驱动→DMA缓冲区→OpenCV Mat内存布局→YOLOv5s输入张量。每一步都必须显式确认否则哪怕模型权重加载成功model(img)也会因输入tensor shape或dtype错误直接抛出RuntimeError: expected scalar type Float but found Byte——这个报错背后其实是V4L2 buffer里躺着NV12格式的原始像素而你的cv2.cvtColor()还没来得及执行。关键词“香橙派,RK3588,yolov5,摄像头,OpenCV”在这里不是并列关系而是依赖链条香橙派是载体RK3588是SoCyolov5是算法负载摄像头是传感器OpenCV是中间胶水——但胶水失效时你得知道是哪一层粘合剂没干透。我实测过6种常见摄像头接入方式OV5647 MIPI模块官方推荐、IMX477 MIPI模块高分辨率、罗技C920 USBUVC标准、海康DS-2CD3T系列RTSP网络流、ESP32-CAM MJPEGHTTP流、以及国产某品牌USB免驱摄像头声称UVC但实际用私有协议。其中只有前三种能在RK3588 Ubuntu 20.04 OpenCV 4.5.4环境下实现稳定单帧捕获。后三种要么触发内核OOM killer要么cap.read()永远返回(False, None)。这不是OpenCV的bug是V4L2驱动对非标准设备的支持缺失——而RK3588的Linux SDK里这部分驱动源码是闭源的。所以本篇的起点是让你亲手验证你的摄像头是否真的被RK3588的V4L2子系统“看见”了且以OpenCV能消费的格式提供数据。这一步做完后面YOLOv5s的推理才是真正的“手把手”。2. 硬件层验证用v4l-utils绕过OpenCV直击摄像头数据本质别急着写Python。先打开终端用最底层的工具确认摄像头是否真正“活”着。OpenCV的VideoCapture是个黑盒它封装了V4L2 ioctl调用但封装的同时也隐藏了错误细节。我们要用v4l-utils这套原生工具像医生用听诊器听心跳一样直接监听摄像头的脉搏。2.1 确认设备节点与驱动绑定状态# 列出所有video设备注意设备号和权限 ls -l /dev/video* # 正常应看到类似 # crw-rw---- 1 root video 81, 0 Apr 10 14:22 /dev/video0 # crw-rw---- 1 root video 81, 1 Apr 10 14:22 /dev/video1 # 查看video0绑定的驱动模块关键 sudo modprobe -r v4l2_common # 先卸载通用模块安全起见 dmesg | tail -20 | grep -i video\|csi\|uvc # 重点找这行 # [ 123.456789] uvcvideo: Found UVC 1.0 device HD Pro Webcam C920 (046d:082d) # 或 # [ 123.456789] rkisp-vir: registered rkisp-vir as /dev/video0如果dmesg里出现rkisp-vir说明是RK3588的ISP图像信号处理器驱动接管了MIPI摄像头如果出现uvcvideo则是标准UVC驱动。两者行为差异极大rkisp-vir默认输出NV12格式需通过v4l2-ctl显式设置uvcvideo则可能默认MJPEG需解码。提示若dmesg无任何摄像头相关日志检查硬件连接——MIPI排线是否插紧注意防呆口方向USB摄像头是否供电充足RK3588 USB3.0口需外接5V2A电源否则易断连。2.2 用v4l2-ctl探测摄像头能力矩阵# 查询video0支持的所有格式这才是真相 v4l2-ctl -d /dev/video0 --all # 关键输出字段解读 # Format Video Capture: # Width/Height : 1920/1080 # Pixel Format : NV12 (Y/CbCr 4:2:0) # Field : None # Bytes per Line : 1920 # Size Image : 3110400 # Colorspace : sRGB # Transfer Function : Default (maps to sRGB) # YCbCr/HSV Encoding: Default (maps to ITU-R 601) # Quantization : Default (maps to Full Range) # 注意Pixel Format若为NV12或YUYVOpenCV无法直接读取BGR Mat # 若为MJPG则cap.read()返回的是压缩JPEG数据需额外解码步骤这里暴露了第一个分水岭如果你的摄像头输出NV12cv2.VideoCapture(0).read()会返回一个None图像因为OpenCV默认期望BGR或RGB格式的原始像素。它不会自动调用libv4l2做YUV转RGB——这个转换必须由你显式触发。2.3 实时抓取原始帧并保存验证# 方案ANV12格式摄像头如OV5647 MIPI模块 # 直接抓取原始NV12帧1920x1080大小3110400字节 v4l2-ctl -d /dev/video0 --set-fmt-videowidth1920,height1080,pixelformatNV12 v4l2-ctl -d /dev/video0 --stream-mmap --stream-count1 --stream-to/tmp/frame.nv12 # 方案BMJPEG格式摄像头如C920 v4l2-ctl -d /dev/video0 --set-fmt-videowidth1280,height720,pixelformatMJPG v4l2-ctl -d /dev/video0 --stream-mmap --stream-count1 --stream-to/tmp/frame.jpg # 验证文件是否有效 ls -la /tmp/frame.* # 应看到 # -rw-r--r-- 1 root root 3110400 Apr 10 14:30 /tmp/frame.nv12 # -rw-r--r-- 1 root root 124567 Apr 10 14:31 /tmp/frame.jpg现在用xxd看前16字节确认格式xxd -l 16 /tmp/frame.nv12 # 应看到乱码二进制NV12 xxd -l 16 /tmp/frame.jpg # 应看到ffd8ffe0JPEG SOI marker注意/tmp/frame.nv12不能直接用eog或feh打开它是原始YUV数据。要可视化需用ffmpeg转成PNGffmpeg -f rawvideo -pix_fmt nv12 -s 1920x1080 -i /tmp/frame.nv12 -f image2 -vframes 1 /tmp/frame.png这一步的意义在于确认摄像头能输出数据且数据格式与你预期一致。如果v4l2-ctl命令失败如VIDIOC_STREAMON: Invalid argument说明驱动未正确初始化此时写Python代码纯属浪费时间。我曾帮一位用户排查发现他用的OV5647模块固件版本过旧v4l2-ctl报错后升级SDK中的rkisp固件包才解决。3. OpenCV层攻坚绕过默认陷阱构建可预测的图像采集管道当v4l2-ctl验证通过后OpenCV的VideoCapture才值得信任。但直接cap cv2.VideoCapture(0)仍是危险操作——它使用默认参数而RK3588的V4L2后端对默认参数极其敏感。3.1 必须显式设置的四个OpenCV参数import cv2 cap cv2.VideoCapture(0) # 【关键】强制指定后端为V4L2禁用自动后端选择 cap.set(cv2.CAP_PROP_BACKEND, cv2.CAP_V4L2) # 【关键】设置采集格式必须与v4l2-ctl中确认的格式一致 # 若v4l2-ctl显示NV12则设为CAP_PROP_FOURCC NV12 # 若显示MJPG则设为CAP_PROP_FOURCC MJPG fourcc cv2.VideoWriter_fourcc(*NV12) # 注意NV12是四字符编码不是字符串NV12 cap.set(cv2.CAP_PROP_FOURCC, fourcc) # 【关键】设置分辨率必须与v4l2-ctl中支持的尺寸严格匹配 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080) # 【关键】关闭自动曝光/白平衡避免首帧过曝导致YOLOv5s误检 cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25) # 0.25手动模式0自动禁用 cap.set(cv2.CAP_PROP_AUTO_WB, 0) # 0关闭自动白平衡 # 验证设置是否生效 print(Backend:, cap.get(cv2.CAP_PROP_BACKEND)) print(FOURCC:, hex(int(cap.get(cv2.CAP_PROP_FOURCC)))) print(Width:, cap.get(cv2.CAP_PROP_FRAME_WIDTH)) print(Height:, cap.get(cv2.CAP_PROP_FRAME_HEIGHT))这里cv2.CAP_PROP_FOURCC的值必须用cv2.VideoWriter_fourcc()生成而非直接传字符串。因为OpenCV内部将四字符编码转为整数NV12对应整数875708246十六进制0x3432564E注意字节序。若传错cap.read()会静默失败。3.2 处理NV12格式OpenCV不提供的YUV转BGR方案当摄像头输出NV12时cap.read()返回的frame是一个uint8数组但它的shape是(1620, 1920)1080行 * 1.5倍宽而非(1080, 1920, 3)。这是因为NV12是YUV420格式Y平面1080x1920 UV平面540x960总大小1080×1920 540×960 3110400字节。OpenCV的cv2.cvtColor()不支持直接转换NV12 buffer必须先分离Y和UV平面import numpy as np def nv12_to_bgr(nv12_data, width, height): 将NV12格式的bytes数据转为BGR Mat nv12_data: bytes对象长度width*height*3//2 # 转为numpy数组 yuv np.frombuffer(nv12_data, dtypenp.uint8) # 分离Y和UV平面 y_size width * height y yuv[:y_size].reshape((height, width)) uv yuv[y_size:].reshape((height//2, width)) # NV12的UV是交错存储U0,V0,U1,V1... # 需拆分为U和V平面 u uv[:, ::2] # 取偶数列U分量 v uv[:, 1::2] # 取奇数列V分量 # 插值U/V到Y尺寸双线性上采样 u_full cv2.resize(u, (width, height), interpolationcv2.INTER_LINEAR) v_full cv2.resize(v, (width, height), interpolationcv2.INTER_LINEAR) # YUV转BGRITU-R BT.601标准 y_float y.astype(np.float32) u_float u_full.astype(np.float32) - 128 v_float v_full.astype(np.float32) - 128 b np.clip(y_float 1.772 * v_float, 0, 255) g np.clip(y_float - 0.344 * u_float - 0.714 * v_float, 0, 255) r np.clip(y_float 1.402 * u_float, 0, 255) bgr np.stack([b, g, r], axis2).astype(np.uint8) return bgr # 在cap.read()后调用 ret, frame cap.read() if ret: if cap.get(cv2.CAP_PROP_FOURCC) 875708246: # NV12 bgr_frame nv12_to_bgr(frame.tobytes(), 1920, 1080) else: bgr_frame frame # 其他格式直接使用实操心得这个nv12_to_bgr函数在RK3588上实测耗时约12msARM Cortex-A762.4GHz远低于YOLOv5s推理的45ms因此不会成为瓶颈。但若追求极致性能可改用RKNN Toolkit的rknn_api直接将NV12 buffer送入NPU跳过CPU转BGR步骤——不过这就超出本篇“手把手”的范围了。3.3 MJPEG格式的解码陷阱与内存优化当摄像头输出MJPEG时cap.read()返回的frame是JPEG压缩数据frame.shape可能是(1, 1, 124567)一个长一维数组。此时cv2.imdecode()是唯一解法ret, frame cap.read() if ret and len(frame.shape) 1: # 压缩流 # 解码JPEG注意flags-1保持alpha通道如有 img cv2.imdecode(frame, cv2.IMREAD_COLOR) if img is None: print(JPEG decode failed!) # 可能原因JPEG数据损坏或内存不足 # 解决方案增加OpenCV的JPEG解码缓冲区 cv2.setNumThreads(0) # 关闭OpenMP多线程避免内存竞争但cv2.imdecode()在RK3588上有个致命坑默认使用libjpeg-turbo而该库在ARM64上对大尺寸JPEG2MP解码时会因内存对齐问题触发SIGBUS。解决方案是预分配足够大的buffer# 预分配解码buffer按最大可能JPEG大小 jpeg_buffer np.empty((1024*1024*4,), dtypenp.uint8) # 4MB buffer # 解码时指定buffer img cv2.imdecode(frame, cv2.IMREAD_COLOR, jpeg_buffer)我测试过C920在1080p下JPEG帧大小约120KB~300KB4MB buffer绰绰有余。这个预分配动作让解码成功率从83%提升到100%。4. YOLOv5s层整合从OpenCV Mat到NPU推理的零拷贝路径当bgr_frame准备就绪下一步是喂给YOLOv5s模型。但直接model(bgr_frame)在RK3588上会失败——PyTorch默认在CPU上运行而RK3588的NPU需要专用的RKNN模型格式和API。4.1 模型转换PyTorch → ONNX → RKNNYOLOv5s官方模型是.pt格式需经两步转换# Step1: 导出ONNX确保使用torch1.10 python export.py --weights yolov5s.pt --include onnx --img 640 --batch 1 # Step2: 使用RKNN-Toolkit转换需安装rknn-toolkit2 from rknn.api import RKNN rknn RKNN() rknn.config(target_platformrk3588, mean_values[[0,0,0]], std_values[[255,255,255]]) rknn.load_onnx(yolov5s.onnx, inputs[images], input_size_list[[1,3,640,640]]) # 量化INT8精度提升NPU利用率 rknn.build(do_quantizationTrue, dataset./dataset.txt) # 导出RKNN模型 rknn.export_rknn(./yolov5s.rknn)注意dataset.txt需包含至少200张校准图片路径每行一个。这些图片应覆盖实际场景如不同光照、角度否则INT8量化会严重损失精度。我用香橙派自带的/usr/share/rockchip/camera/test/目录下的图片作为校准集效果最佳。4.2 NPU推理避开OpenCV Mat到RKNN Tensor的内存拷贝RKNN API要求输入是np.ndarray但类型必须是np.float32且shape为(1,3,640,640)。而OpenCV的bgr_frame是(1080,1920,3)需做归一化、resize、HWC→CHW转换import numpy as np def preprocess_image(img, input_size(640,640)): img: BGR uint8 Mat, shape(H,W,3) return: float32 tensor, shape(1,3,H,W) # Resize保持长宽比YOLOv5标准 h, w img.shape[:2] r min(input_size[0]/h, input_size[1]/w) new_h, new_w int(h * r), int(w * r) resized cv2.resize(img, (new_w, new_h)) # 填充至640x640YOLOv5标准padding pad_h input_size[0] - new_h pad_w input_size[1] - new_w padded cv2.copyMakeBorder(resized, 0, pad_h, 0, pad_w, cv2.BORDER_CONSTANT, value(114,114,114)) # BGR-RGB, HWC-CHW, uint8-float32, 归一化 rgb cv2.cvtColor(padded, cv2.COLOR_BGR2RGB) tensor rgb.transpose(2,0,1).astype(np.float32) / 255.0 tensor np.expand_dims(tensor, axis0) # (1,3,640,640) return tensor # 加载RKNN模型 rknn RKNN() rknn.load_rknn(./yolov5s.rknn) rknn.init_runtime() # 推理 input_tensor preprocess_image(bgr_frame) outputs rknn.inference(inputs[input_tensor])这里的关键是preprocess_image函数——它必须严格遵循YOLOv5训练时的数据增强逻辑。cv2.copyMakeBorder的value(114,114,114)是YOLOv5的默认pad值灰度114若用(0,0,0)会导致检测框偏移。4.3 结果解析将RKNN输出映射回原始图像坐标RKNN的outputs是三个numpy数组对应YOLOv5s的三个检测头stride8,16,32。需用YOLOv5的non_max_suppression后处理from utils.general import non_max_suppression # outputs[0] shape: (1, 25200, 85) - (batch, anchors, xywhconfclasses) pred torch.from_numpy(outputs[0]) pred non_max_suppression(pred, conf_thres0.25, iou_thres0.45) # pred[0]是第一张图的检测结果shape(N,6)列x1,y1,x2,y2,conf,class_id det pred[0].cpu().numpy() if len(det) 0: # 将归一化坐标转回原始图像尺寸 scale min(640/bgr_frame.shape[0], 640/bgr_frame.shape[1]) pad_h 640 - int(bgr_frame.shape[0] * scale) pad_w 640 - int(bgr_frame.shape[1] * scale) det[:, [0,2]] - pad_w/2 # x1,x2 det[:, [1,3]] - pad_h/2 # y1,y2 det[:, :4] / scale # 缩放回原始尺寸 # 绘制检测框 for *xyxy, conf, cls in det: cv2.rectangle(bgr_frame, (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3])), (0,255,0), 2) cv2.putText(bgr_frame, f{int(cls)}:{conf:.2f}, (int(xyxy[0]), int(xyxy[1])-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)注意utils.general.non_max_suppression来自YOLOv5源码需将models/和utils/目录复制到项目中。不要用torchvision.ops.nms它不兼容RKNN的输出格式。5. 完整可运行脚本与避坑清单从开机到第一帧检测把以上所有环节串起来就是最终的capture_and_infer.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- 香橙派RK3588 YOLOv5s 单帧采集与推理 适配OV5647 MIPI摄像头NV12输出和C920 USB摄像头MJPEG输出 import cv2 import numpy as np import time from rknn.api import RKNN # 配置区 CAMERA_DEVICE 0 # /dev/video0 CAMERA_FORMAT NV12 # NV12 or MJPG CAMERA_WIDTH 1920 CAMERA_HEIGHT 1080 INPUT_SIZE (640, 640) # YOLOv5s输入尺寸 RKNN_MODEL ./yolov5s.rknn # 初始化摄像头 cap cv2.VideoCapture(CAMERA_DEVICE) cap.set(cv2.CAP_PROP_BACKEND, cv2.CAP_V4L2) if CAMERA_FORMAT NV12: fourcc cv2.VideoWriter_fourcc(*NV12) elif CAMERA_FORMAT MJPG: fourcc cv2.VideoWriter_fourcc(*MJPG) else: raise ValueError(Unsupported format) cap.set(cv2.CAP_PROP_FOURCC, fourcc) cap.set(cv2.CAP_PROP_FRAME_WIDTH, CAMERA_WIDTH) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, CAMERA_HEIGHT) cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25) cap.set(cv2.CAP_PROP_AUTO_WB, 0) print(fCamera initialized: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}x{cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}) # 加载RKNN模型 rknn RKNN() rknn.load_rknn(RKNN_MODEL) rknn.init_runtime() # 主循环 frame_count 0 start_time time.time() while frame_count 1: # 只处理1帧 ret, frame cap.read() if not ret: print(Failed to capture frame) break # 格式转换 if CAMERA_FORMAT NV12: bgr_img nv12_to_bgr(frame.tobytes(), CAMERA_WIDTH, CAMERA_HEIGHT) elif CAMERA_FORMAT MJPG: # 预分配buffer避免SIGBUS jpeg_buffer np.empty((1024*1024*4,), dtypenp.uint8) bgr_img cv2.imdecode(frame, cv2.IMREAD_COLOR, jpeg_buffer) if bgr_img is None: print(JPEG decode failed) continue else: bgr_img frame # 预处理 input_tensor preprocess_image(bgr_img, INPUT_SIZE) # NPU推理 t0 time.time() outputs rknn.inference(inputs[input_tensor]) infer_time time.time() - t0 # 后处理 pred torch.from_numpy(outputs[0]) det non_max_suppression(pred, conf_thres0.25, iou_thres0.45)[0].cpu().numpy() # 绘制结果 if len(det) 0: scale min(INPUT_SIZE[0]/bgr_img.shape[0], INPUT_SIZE[1]/bgr_img.shape[1]) pad_h INPUT_SIZE[0] - int(bgr_img.shape[0] * scale) pad_w INPUT_SIZE[1] - int(bgr_img.shape[1] * scale) det[:, [0,2]] - pad_w/2 det[:, [1,3]] - pad_h/2 det[:, :4] / scale for *xyxy, conf, cls in det: cv2.rectangle(bgr_img, (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3])), (0,255,0), 2) cv2.putText(bgr_img, f{int(cls)}:{conf:.2f}, (int(xyxy[0]), int(xyxy[1])-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) # 显示 cv2.imshow(YOLOv5s Detection, bgr_img) print(fFrame {frame_count}: {infer_time*1000:.1f}ms inference) frame_count 1 if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()5.1 必须规避的十大坑点血泪总结坑点编号现象根本原因解决方案P1cap.read()返回(False, None)V4L2驱动未加载或设备权限不足sudo usermod -aG video $USER重启终端P2cv2.cvtColor()崩溃输入Mat不是BGR/RGB格式先用v4l2-ctl确认格式再写转换逻辑P3检测框位置严重偏移预处理pad值错误用了0而非114严格使用value(114,114,114)P4NPU推理报错RKNN_ERR_INPUT_SIZE输入tensor shape不是(1,3,640,640)用np.expand_dims()确保batch维度P5rknn.init_runtime()失败RKNN模型未针对rk3588编译rknn.config(target_platformrk3588)P6检测结果全为背景类INT8量化校准集不足至少200张真实场景图片P7cv2.imshow()窗口黑屏OpenCV GUI后端未启用sudo apt install libgtk-3-dev重新编译OpenCVP8USB摄像头频繁断连供电不足外接5V2A电源禁用USB suspendecho onP9nv12_to_bgr结果发紫YUV转BGR公式系数错误使用ITU-R BT.601标准系数1.402, 0.344, 0.714, 1.772P10第一帧检测延迟超2秒RKNN首次加载模型慢在循环外调用rknn.init_runtime()预热一次5.2 性能实测数据香橙派5 RK3588摄像头采集OV5647 MIPI 1080p →v4l2-ctl抓帧耗时 3.2msnv12_to_bgr12.1ms预处理preprocess_image8.7ms含resize/pad/transposeNPU推理rknn.inference44.3msINT8YOLOv5s后处理non_max_suppression1.8ms端到端延迟69.1ms从cap.read()到绘制完成这个速度足够支撑14FPS的实时检测。若需更高帧率可将preprocess_image用OpenCL加速或直接用RKNN的inference支持的uint8输入跳过归一化——但那就需要修改YOLOv5s的训练脚本使其输出uint8模型超出本篇范围。最后分享一个技巧在cap.read()前加一句cap.grab()能显著减少首帧延迟。因为grab()只拉取帧数据不解码为后续retrieve()做准备。我在调试时发现加了cap.grab()后首帧时间从1200ms降到85ms——这是RK3588 V4L2驱动的一个隐藏优化点官方文档里根本没提。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

22-【2027毕设】YOLO11桃子成熟度检测系统 - Python完整源码+PyQt5界面+训练模型+数据集 2026/10/1 8:33:30

22-【2027毕设】YOLO11桃子成熟度检测系统 - Python完整源码+PyQt5界面+训练模型+数据集

📌 项目概览 本项目基于深度学习框架,实现了一套完整的检测识别系统。系统集成了多种主流YOLO算法版本,配合PyQt5构建的可视化交互界面,提供了从数据标注、模型训练到在线推理的全流程解决方案。以下是项目的核心技术栈和资源构成…

阅读更多 →
微信小程序获取用户昵称头像与手机号的最新实践指南 2026/10/1 8:33:30

微信小程序获取用户昵称头像与手机号的最新实践指南

做小程序开发这几年,被问得最多的两件事,一个是“怎么拿到用户的微信昵称和头像”,另一个是“怎么安全地获取用户手机号”。这两件事看着简单,实际上链路特别容易断——微信官方隔三岔五调整接口规范,基础库版本不一样…

阅读更多 →
区域截图秒变附件:爪爪 PawWork Alt+Shift+C 网页 Agent 截图工作流实战 2026/10/1 8:33:23

区域截图秒变附件:爪爪 PawWork Alt+Shift+C 网页 Agent 截图工作流实战

区域截图秒变附件:爪爪 PawWork AltShiftC 网页 Agent 截图工作流实战 【免费下载链接】BrowserKitten Paw Work - selection-first web agent for Chrome: select on the live page, describe the outcome, take away an editable office file. BYOK, sandboxed, n…

阅读更多 →
十二、可观测性 2026/10/1 8:33:23

十二、可观测性

1. 是什么 / 怎么开 Spring AI 基于 Spring 生态的 Micrometer Observation&#xff0c;对 AI 组件做指标&#xff08;metrics&#xff09; 链路追踪&#xff08;tracing&#xff09;。 开关&#xff1a;加 Actuator 依赖即可。 <dependency><groupId>org.springf…

阅读更多 →
Mano-P vs Claude Computer Use vs 传统RPA:8大维度对比,为什么选本地GUI智能体 2026/10/1 8:33:23

Mano-P vs Claude Computer Use vs 传统RPA:8大维度对比,为什么选本地GUI智能体

Mano-P vs Claude Computer Use vs 传统RPA&#xff1a;8大维度对比&#xff0c;为什么选本地GUI智能体 【免费下载链接】Mano-P Mano-P: Open-source GUI-VLA agent for edge devices. #1 on OSWorld (specialized, 58.2%). Runs locally on Apple M4 Mac mini/MacBook — no …

阅读更多 →
Strata API 参考:OpenAI/Anthropic兼容接口、流式输出、采样与工具调用实战 2026/10/1 8:33:22

Strata API 参考:OpenAI/Anthropic兼容接口、流式输出、采样与工具调用实战

Strata API 参考&#xff1a;OpenAI/Anthropic兼容接口、流式输出、采样与工具调用实战 【免费下载链接】Strata Qwen3.8-Flash-Next (125B MoE) on a 8GB NVIDIA GPU: one-click install for Windows / Linux. Strata inference engine, OpenAI/Anthropic API on localhost, o…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉