树莓派视觉小车实战:OpenCV寻迹避障与图像识别全解析

简介:基于树莓派视觉图像识别的智能寻迹避障小车项目源码包,面向人工智能、物联网、自动化等方向的在校学生、教师及竞赛选手,以树莓派为核心实现视觉寻迹与避障,代码带详细注释,新手也能上手,适合作为毕业设计、课程设计或竞赛完整方案,经过调试可直接部署运行。资源包为zip格式,共12个文件,含4个Python脚本、3个XML配置、2个Markdown说明、1个文本说明及1张实物图片,压缩包仅197KB。Python脚本覆盖树莓派端与电脑端控制逻辑,XML对应视觉识别分类器配置,Markdown文档提供项目结构与使用指引,整体轻量清晰。该资源已有826人学习下载,作为高分毕业设计与竞赛项目分享,含完整代码和注释,并附文档辅助理解,可在现有基础上修改功能或直接用于项目初期演示。适用于毕设、课设、作业或竞赛项目参考,从入门到进阶皆可受益。

1. 树莓派视觉小车:为什么图像识别让寻迹避障小车摆脱红外对管的局限

做毕业设计或竞赛小车,最怕的不是算法写不出来,而是选了一个“看起来稳、实际全看环境脸色”的方案。红外对管循迹是典型:在实验室白底黑线上调好,推到阳台日光灯下就开始乱跑,因为环境光里恰好有同波段红外成分,阈值怎么压都压不住。换成摄像头以后,树莓派看到的不是电压跳变,而是一张真实的赛道图像——怎么识别、怎么转向、怎么避障,每一步都有画面和数据可查。这套基于树莓派视觉图像识别的智能寻迹避障小车,用 CSI 摄像头采集赛道,OpenCV 做图像识别,再配合超声波避障,源码带注释,完整跑通一条“采集—识别—决策—控制”的链路,适合毕业设计选型、课程项目参考,也适合竞赛队伍直接拿来做底子。

2. 硬件选型与图像采集链路:算力边界、摄像头接口与电机驱动的配合

小车的整体链路是:摄像头采集一帧画面 → 树莓派上的 OpenCV 处理 → 输出方向偏差 → GPIO 转 PWM → 电机驱动模块 → 左右轮差速转向;同时超声波模块单独占用一组 GPIO,测距值低于阈值时切入避障状态,暂停寻迹逻辑。这条链路决定了选硬件时的三个核心约束:主控算力能不能兜住图像处理帧率、摄像头用什么接口才不掉帧、电机启动的浪涌电流会不会把主控拉重启。下面逐个说。

2.1 主控算力与选型:为什么树莓派是这个项目的主流选择

做这类视觉小车,常见的主控是树莓派 4B,而不是性能更高的 Jetson Nano。原因不是树莓派算力强,而是它的生态完整:GPIO 直出 PWM、CSI 摄像头接口、完整的 Linux 环境、Python 直接装 OpenCV,整条链路不需要额外的单片机中转。算力上,一张 320×240 的 BGR 帧,转 HSV、做二值化、形态学处理、提取中线,整套流程在树莓派 4B 的 CPU 上大约跑 20 到 40 毫秒,对应 25 到 50 帧每秒的控制节奏,对循迹小车绰绰有余。

Jetson Nano 的 GPU 能跑得更快,但代价是小车底盘的电源要同时伺候 5W 起步的功耗、散热风扇和稳压电路,稳定性反而更难做。所以我在设计时会把分辨率定死在 320×240,而不是一味上 720p——分辨率翻一倍,处理周期往往从 30 毫秒飙升到 80 毫秒以上,控制延迟变大,弯道里车子会明显“慢半拍”。先把分辨率压下来,优先级永远高于提升画质。

2.2 摄像头采集:CSI 接口、UVC 与帧率稳定性的取舍

摄像头有两条路:树莓派官方 CSI 接口模块,或者 USB UVC 摄像头。CSI 模块走专用接口,图像数据不经过 USB 总线,CPU 占用低,帧率稳定;缺点是要用排线连到主板上,安装位置灵活性小。USB 摄像头胜在即插即用,可以用长线把镜头架到车头任何位置,问题在于 UVC 协议的数据搬运走的是 USB 总线,和 WiFi、蓝牙共享资源,跑起来偶尔会丢帧。

项目CSI 摄像头模块USB UVC 摄像头
CPU 占用较低较高
帧率稳定性稳定可能丢帧
安装灵活性差,排线短好,可装支架
供电主板供电可能需额外供电
适用场景固定机位车头需要移动镜头

我的做法是优先 CSI。小车车头固定,摄像头位置本来就不需要频繁挪,CSI 的低占用和稳定帧率能把系统负载让给图像处理和控制逻辑。装好后先跑两条命令确认采集链路是通的:

# 查看是否有 USB 摄像头枚举,CSI 摄像头不在这里 lsusb | grep -i camera # CSI 摄像头测试:输出 5 秒预览,窗口能看到就说明通路正常 rpicam-hello -t 5000 --width 640 --height 480 # 顺手用 OpenCV 写一帧图片,验证 Python 侧能读到画面 python3 -c "import cv2; cap = cv2.VideoCapture(0); ok, frame = cap.read(); cv2.imwrite('frame_test.jpg', frame) if ok else print('no frame')"

-t 5000是预览时长 5000 毫秒,640×480 已经够做算法验证;VideoCapture(0)表示读取编号为 0 的摄像头设备。如果最后一条命令打印no frame,先检查设备号 0 是否被其他进程占用,或者换个设备号 1 试试。CSI 摄像头正常时,lsusb里是看不到它的,别被这条命令误导。

2.3 电机驱动与供电:PWM 频率、GPIO 接线与双电源规则

驱动部分我用 L298N 双 H 桥模块,一路驱动左电机,一路驱动右电机,四个输入引脚控制方向,两个使能引脚接 PWM 调速。下面这组接线是我常用的,BCM 引脚编号可以换,但 PWM 引脚尽量选树莓派硬件 PWM,软件模拟 PWM 在低速段抖得厉害:

L298N 引脚树莓派 GPIO(BCM)作用
IN1GPIO18左电机正转
IN2GPIO23左电机反转
IN3GPIO24右电机正转
IN4GPIO25右电机反转
ENAGPIO12左电机调速 PWM
ENBGPIO13右电机调速 PWM

L298N 上 ENA 和 ENB 各有一个跳线帽,默认插着是让电机全速转;拔掉之后才能用 GPIO 的 PWM 信号控制速度。整台车最容易翻车的地方不是接线,而是供电。电机电源必须用独立的电池组接 L298N 的 12V 输入,树莓派再单独用一路 5V 供电,然后两套电源的负极(GND)必须接在一起,否则 GPIO 电平没有共同参考点,控制信号全乱。

我见过很多次有人图省事用一块电池分压同时给电机和树莓派供电,结果电机一转,电压瞬间掉下去,树莓派直接重启。接好线后,可以用一段小脚本验证 PWM 是否真的输出到了电机:

python3 -c " import RPi.GPIO as GPIO, time GPIO.setmode(GPIO.BCM) GPIO.setup(12, GPIO.OUT) pwm = GPIO.PWM(12, 1000) pwm.start(50) time.sleep(3) pwm.stop() GPIO.cleanup() "

GPIO.PWM(12, 1000)是在 GPIO12 上生成 1000Hz 的 PWM 波,占空比 50%。频率不要盲目拉高,我一般从 500Hz 起步,1000Hz 是折中值——频率太高电机会有高频啸叫,太低了低速段扭矩不稳。这段只是验证,实际控制里占空比会由 PID 动态计算。

3. OpenCV 视觉识别:赛道提取、中线计算与控制输出的完整流程

写这章之前先说结论:小车能不能沿赛道走,核心就四步——判断每个像素是不是赛道、把赛道区域从画面里分离出来、找到赛道的中线、算出中线与画面中心的偏差并转成转向量。整个处理用 Python 和 OpenCV 实现,源码包里对应到lane_detect.py到control.py这一段。

3.1 HSV 色域分割:为什么不能直接在 BGR 下做阈值

摄像头默认输出的颜色空间是 BGR,但 BGR 的三个通道都跟随亮度变化,光照一变,同样的赛道颜色在数值上会漂出预设范围。HSV 空间把色相 H、饱和度 S、明度 V 分开,主色调放在 H 通道,受亮度干扰小。所以第一步永远是cv2.cvtColor(frame, cv2.COLOR_BGR2HSV),而不是在原来的 BGR 图上做阈值。

调试阈值最常用的手段是拖滑动条可视化,这比反复改代码快得多:

import cv2 import numpy as np def nothing(x): pass cv2.namedWindow("calib") cv2.createTrackbar("H_low", "calib", 0, 179, nothing) cv2.createTrackbar("S_low", "calib", 0, 255, nothing) cv2.createTrackbar("V_low", "calib", 180, 255, nothing) cv2.createTrackbar("H_high", "calib", 179, 179, nothing) cv2.createTrackbar("S_high", "calib", 255, 255, nothing) cv2.createTrackbar("V_high", "calib", 255, 255, nothing) cap = cv2.VideoCapture(0) while True: ok, frame = cap.read() if not ok: break hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) h_low = cv2.getTrackbarPos("H_low", "calib") s_low = cv2.getTrackbarPos("S_low", "calib") v_low = cv2.getTrackbarPos("V_low", "calib") h_high = cv2.getTrackbarPos("H_high", "calib") s_high = cv2.getTrackbarPos("S_high", "calib") v_high = cv2.getTrackbarPos("V_high", "calib") lower = np.array([h_low, s_low, v_low]) upper = np.array([h_high, s_high, v_high]) mask = cv2.inRange(hsv, lower, upper) cv2.imshow("mask", mask) cv2.imshow("frame", frame) if cv2.waitKey(1) == ord("q"): break cap.release() cv2.destroyAllWindows()

这段代码的每个滑条都对应 HSV 的一个通道范围:H 在 OpenCV 里的范围是 0 到 179,S 和 V 都是 0 到 255。如果赛道是白色,V_low 往往要拉到 180 以上,S_low 放低到 0 附近;如果赛道是红色,要注意 H 空间是环形的,0 到 10 和 170 到 179 两段都要保留,否则正红色会被切成两截。滑动条固定在赛道最清晰的亮度下把 mask 调到“赛道全白、背景全黑”,这套参数就是后面代码里要填进去的初值。

3.2 赛道中线提取:ROI 裁剪、二值化后处理与滑动窗口

拿到 mask 之后,里面还有两类噪声:背景里零星的白点,以及赛道内部因为反光出现的黑色空洞。处理顺序是先做一次形态学开运算去掉孤立白点,再做一次闭运算把断裂的赛道区域连接起来。开运算是先腐蚀后膨胀,闭运算是先膨胀后腐蚀,核大小用 5×5 就够,太大反而会把相邻赛道糊在一起。

紧接着做 ROI 裁剪。摄像头装在车头朝前看,画面下半部分是赛道,上半部分是背景,裁剪掉上部能省大量计算。我是用多边形填充构造一个梯形 ROI,只保留画面下半部分中间的区域:

def get_center_line(binary, roi_vertices): """在 ROI 内逐行扫描,找出每行赛道区域的中点像素坐标""" roi_mask = np.zeros_like(binary) cv2.fillPoly(roi_mask, [roi_vertices], 255) roi_only = cv2.bitwise_and(binary, roi_mask) h, w = roi_only.shape roi_top = int(h * 0.35) center_list = [] for row in range(roi_top, h, 5): col_indices = np.where(roi_only[row, :] > 0)[0] if len(col_indices) == 0: center_list.append(-1) # 这一行没有赛道,标记为丢线 else: center_list.append(int(np.mean(col_indices))) return center_list

fillPoly把梯形区域填充为白色,bitwise_and让 mask 只在梯形内保留赛道像素,梯形外面的干扰全部清掉。roi_top取图像高度的 35%,是把视野上方去掉;每 5 行扫一次而不是逐行扫,是为了把计算量降下来,中线精度对 320 宽的图来说足够。np.where返回这一行所有白色像素的列坐标,取平均值就是该行赛道的中点。丢线时返回 -1,后面控制逻辑必须处理这个标记,不能把它当成 0 或者边界值参与计算。

3.3 从偏差到转向指令:限幅、滤波与差速 PWM

中线提取出来后,取最靠近车头那一行的中心点,和画面中心(320)做差,得到偏差error。这个值直接送给控制逻辑是不够的——摄像头每一帧都有噪声,偏差会来回抖,直接映射到转向量,车就会蛇形前进。常见做法是先限幅再滤波,最后才进 PID:

# center_x 取自 3.2 返回的最后一个有效中心点 error = center_x - frame_mid_x error = max(-80, min(80, error)) # 限幅,防止突变值冲击转向 # 一阶低通滤波:0.7 是新值权重,0.3 是上一帧权重 error_smooth = 0.7 * error + 0.3 * pre_error pre_error = error_smooth # P 控制输出转向量 turn = Kp * error_smooth left_pwm = base_speed - turn right_pwm = base_speed + turn

frame_mid_x在 320 宽的图像里取 160 或者 320,取决于你的中线是相对整幅图算的还是相对 ROI 区域算的,两个坐标系别混用。base_speed是直道巡航速度,turn是转向修正量,左轮减去它、右轮加上它,形成差速转向。Kp一开始取 0.2,直道上跑不画龙、弯道能压住线就不要再动;调太大直线会抖,太小弯道会直接冲出赛道。最后一轮差分和 PWM 限幅要在输出到 GPIO 之前再做一次,防止left_pwm超出 0 到 100 的范围。

4. 寻迹避障的常见问题排查:光线、供电与跳变的三类硬坑

4.1 光线变化导致识别崩掉:HSV 阈值为什么定了还会翻车

现象:在室内白炽灯下跑得好好的,搬到走廊或者室外,mask 里赛道区域出现大片黑色空洞,或者地面阴影被当成赛道,车子开始乱转。

原因:HSV 虽然把色相和亮度拆开了,但对白色赛道这种场景,V 通道的上下限仍然直接依赖环境亮度。室内 4000K 色温、室外 6000K 色温下,同一块白色赛道拍出来的 V 值能差 30 以上,固定阈值必然失效。

解决:两条路。第一,ROI 裁剪务必做,把画面顶部、侧面、地面反光区域裁掉,减少亮度干扰进入算法;第二,开机时做一次动态校准,连续采 30 帧求平均亮度,用亮度均值偏移补偿 V 通道下限:

# 开机采集 30 帧,取灰度均值作为基准亮度 frames = [] for _ in range(30): ok, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) frames.append(gray.mean()) avg = np.mean(frames) # 以 120 为基准亮度,偏移接到 V 下限上 offset = int(avg - 120) v_low = min(255, max(0, 180 - offset))

这段补偿只在开机时跑一次,成本很低,但能把“室内调好的参数在室外崩掉”的问题解决八九成。剩下的情况就是赛道本身被阳光直射到过曝,那属于物理信息丢失,算法救不回来,只能加遮光罩。

4.2 电机一启动树莓派就重启:供电分配才是最大坑

现象:程序跑起来,PWM 信号一给到电机,电机开始转的瞬间,树莓派屏幕黑了,SSH 断开,重连后查看系统时间发现重启过。

原因:电机堵转或加速瞬间的电流能到 1 到 2 安培,如果树莓派和电机共用一路电源,瞬间电压被拉到 4.6V 以下,树莓派主板直接进入欠压保护重启。

解决:双电源结构是前提——电机电源用独立电池组接 L298N 的 12V 输入,树莓派用一路稳定的 5V 电源单独供,两路电源的 GND 连在一起。L298N 的逻辑供电可以由树莓派 5V 引脚提供,但电机供电绝对不能也挂在树莓派 5V 上。还可以在电机电源两端并一个 470 到 1000 微法的电解电容,吸收启动浪涌。

如果重启仍然偶发,用日志确认一下重启频率:

journalctl --list-boots | head

每行代表一次启动记录,如果列出来的记录都很短,说明系统反复掉电。这招能快速区分是供电问题还是程序 crash 的问题。

4.3 弯道丢失赛道后猛打方向:偏差跳变和丢线状态

现象:直道正常,进弯以后某一帧突然丢线,车头猛甩向一边,出弯后画龙,来回摆好几次才稳定。

原因:丢线时center_x返回 -1,如果不做处理,error = -1 - 160 = -161,这个数字被当成超大偏差送进 PID,转向量瞬间打满,表现出来的就是猛打方向。

解决:三件事一起做。第一,error在进 PD 之前限幅,超过 ±80 的偏差全部按 ±80 算;第二,连续丢线超过 5 帧就进入“丢失”状态,此时不再计算转向,保持上一次的 PWM 输出并降速到原来的 60%;第三,对偏差做低通滤波,把帧间噪声磨掉。丢线处理代码:

# 丢线状态判断,center_x 为 -1 表示当前帧没找到赛道 if center_x == -1: lost_count += 1 else: lost_count = 0 # 丢线超过 5 帧,降速找线,而不是原地打转 if lost_count > 5: left_pwm = int(base_speed * 0.6) right_pwm = int(base_speed * 0.6)

这里lost_count每次进避障状态时复位为 0,否则从弯道出来之后会一直保持低速,严重影响后半程效率。降速的目的是让车在丢线状态下还有时间重新捕捉到赛道,而不是因为高速冲过弯道后彻底偏航。

4.4 超声波避障盲区与反射角导致的误判

现象:墙面距离 30 厘米时避障触发正常,距离 5 厘米时反而没反应,车直接贴上墙;斜着对着墙面时,在很远的位置就急停。

原因:常见超声波测距模块发射的是锥形波,角度大概 15°,近距离时回波还没来得及被接收端捕获,自然就有 2 到 4 厘米的盲区。斜对墙面时,声波反射角偏出去,回波回不到接收面,检测距离就会严重偏大。

解决:模块安装位置抬高到离地 10 厘米以上,并向前倾斜 10 到 15 度,让声波更垂直地打在前方障碍物上;避障判定距离设在 20 到 30 厘米,提前减速而不是等贴近了再触发;每轮测距离连续读三次取中位数,滤掉单次噪声。这几条改完,竞赛场上的误判率能下降一大截。

5. 结项前的高效调试技巧:先录一段带时间戳的视频,再离线回放调参

5.1 录制测试数据

视觉小车最耗时的环节是“改一行参数 → 把车搬到赛道 → 跑一圈 → 搬回来改参数”。破局的办法是让树莓派自己录测试视频,把当时的画面完整存下来:

import cv2 import time cap = cv2.VideoCapture(0) fw = cv2.VideoWriter( "debug_track.avi", cv2.VideoWriter_fourcc(*"MJPG"), 30, (640, 480) ) while True: ok, frame = cap.read() if not ok: break cv2.putText(frame, str(int(time.time() * 1000)), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) fw.write(frame) if cv2.waitKey(1) == ord("q"): break cap.release() fw.release()

核心是把毫秒级的时间戳画进每一帧,之后和串口日志对齐时就能精确到“哪一帧丢的线”“哪一帧 PWM 打满”。录像分辨率保持 640×480,处理代码里裁到 320 的坐标换算在回放时保持一致即可。

5.2 离线回放定位问题

回到桌面后,把VideoCapture(0)改成VideoCapture("debug_track.avi"),跑完全相同的处理代码。再把每一帧的error、left_pwm、right_pwm、lost_count写进 CSV:

with open("debug.csv", "w") as f: f.write("frame,error,lost_count,left_pwm,right_pwm\n") for i, row in enumerate(results): f.write(f"{i},{row['error']},{row['lost_count']},{row['left_pwm']},{row['right_pwm']}\n")

然后打开 CSV,直接看弯道前后那 2 秒的数据:如果lost_count连续大于 5,问题在图像提取;如果error没跳变但 PWM 猛甩,问题在 PID 参数;如果两者都没问题但车还是偏移,那就是机械装配和左右电机转速不一致。这类问题在赛道上可能要反复试 10 次,在录像回放里几分钟就能定位。

从那以后我每次做视觉小车,都会强制先录一段带时间戳的视频再上板调参。省下来的搬车时间,比多写几十行调试代码都值。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

Apache DolphinScheduler年度盘点:工作流调度与生产实践全解析

Apache DolphinScheduler年度盘点:工作流调度与生产实践全解析

又到年底,朋友圈里各种年度盘点纷纷刷屏。作为常年和数据打交道的人,我脑子里第一个冒出来的盘点对象,不是别的,正是Apache DolphinScheduler。这个在开源工作流调度领域占据重要位置的项目,这一年变化其实不小。趁着年…

2026/10/20 18:23:03 阅读更多 →
AI论文写作工具怎么选?查重、逻辑与效率实测指南

AI论文写作工具怎么选?查重、逻辑与效率实测指南

2026年了,论文AI写作早就不是“要不要用”的问题,而是“用得稳不稳”的问题。过去两年,我陆陆续续帮不同背景的写作者做过工具调研和选型,从本科课程论文到硕士学位论文都上手摸过。这篇文章不打算堆一堆功能列表,而是…

2026/10/20 18:23:03 阅读更多 →
规划沟通管理实操指南:告别无效会议与信息过载

规划沟通管理实操指南:告别无效会议与信息过载

干项目管理这些年,我越来越确信一件事:项目里绝大多数麻烦,源头不在技术,而在沟通。而规避沟通灾难的第一步,就是做好“规划沟通管理”——这个在很多项目管理课程里被编为14.3的章节,负责回答“谁、需要什…

2026/10/20 18:23:03 阅读更多 →

最新新闻

MSA存储入门指南:从SAN协议到选型场景的全面解析

MSA存储入门指南:从SAN协议到选型场景的全面解析

简介:这份文档面向备考H3C认证工程师-MSA存储(H3CNE-MSA)的技术人员与H3C代理服务工程师,聚焦MSA存储设备基础配置与维护知识,帮助读者在有限时间内系统梳理考点、检验掌握程度。资源为1个docx文件,压缩包约…

2026/10/20 19:39:14 阅读更多 →
C语言大作业高分实践:工程结构、内存安全与评分对齐

C语言大作业高分实践:工程结构、内存安全与评分对齐

简介:这是一份面向高校C语言初学者与课程设计学生的高分期末大作业实战项目,完整实现了一个具备学生端与管理员双角色的学生成绩管理系统。资源包含可直接编译运行的C/Qt源码(含18个.h头文件与18个.cpp实现文件)、图形界面.ui文件…

2026/10/20 19:39:14 阅读更多 →
Redis Java客户端选型与实战:Jedis、Lettuce、Redisson对比

Redis Java客户端选型与实战:Jedis、Lettuce、Redisson对比

1. 先搞清楚需求,再选客户端写Java应用连Redis,第一步不是去翻依赖、复制代码,而是先想清楚:你的业务到底需要Redis做什么,以及你的应用是什么形态。这话可能听起来像废话,但我在实际项目里见过太多人一上来…

2026/10/20 19:39:14 阅读更多 →
轻量级AI助手ZeroClaw实战:有限算力下的部署与Agent落地

轻量级AI助手ZeroClaw实战:有限算力下的部署与Agent落地

1. 项目定位:为什么轻量级AI助手反而更实用去年年底我拿到一台配置平平的旧工作站,8GB内存、无独显、CPU还是几年前的型号,跑几个容器就喘。当时手头正好有个工具自动化需求:定时抓取内部系统数据,做简单清洗&#xff…

2026/10/20 19:39:14 阅读更多 →
单相桥式半控整流电路原理与Matlab/Simulink仿真建模分析

单相桥式半控整流电路原理与Matlab/Simulink仿真建模分析

单相桥式半控整流电路,这个名字在电力电子课程里出现的频率极高。很多电气工程专业的朋友第一次接触晶闸管整流,就是从它开始的。最近正好有人在问Matlab仿真的思路,我把自己做这个仿真报告的全过程梳理了一遍,从拓扑结构分析到模…

2026/10/20 19:39:14 阅读更多 →
Java动漫链接生成器:批量整理番剧资源链接的轻量工具

Java动漫链接生成器:批量整理番剧资源链接的轻量工具

简介:这是一款面向动漫资源采集与二次元工具开发者的轻量级命令行程序,基于Java实现,可根据指定标签批量生成动漫图片链接,适合需要批量获取Danbooru图源、做数据采集或练手Java命令行项目的开发者。资源包共17个文件,…

2026/10/20 19:38:12 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →