数独照片识别与求解:OpenCV透视校正到答案回填实战

几个月前接到个小需求:拿手机拍一张数独照片,几秒内把答案算出来并叠回原图上。我当时觉得这事不难——数独识别不就是 OCR 加回溯求解嘛,现成库一调就完事。真正动手才发现,随手拍的照片里网格是歪的、数字是糊的、反光会把白格变成灰格,光线一变阈值就崩。这个看似简单的 demo,实际上把计算机视觉里最经典的一整套流程全走了一遍:图像预处理、边缘检测、几何变换、字符识别、坐标映射。今天就把我当时怎么一步步从“照片”变成“答案图”的过程完整拆开讲,想入坑计算机视觉的朋友可以照着这条路走一遍,比单纯看理论印象深刻得多。

1. 为什么偏偏是数独:一个任务串起计算机视觉的基本功

1.1 数独图像处理要面对的真实问题

很多入门教程喜欢拿“识别一张卡牌”“检测一个红绿灯”当例子,但那些任务都太单薄了。数独这个场景最妙的地方在于,一张真实拍摄的数独照片里几乎包含了所有经典干扰:

  • 透视畸变:手机不可能完全正对着纸面拍,网格必然是个不规则的四边形,切出来是梯形的。
  • 光照不均:室内灯光、窗外阳光、手指阴影都会让同一张纸上的亮度差一大截。
  • 线条断裂:铅笔画的格子线、打印墨迹偏淡、皱褶处的反光,会让边框或内部格线断掉。
  • 前景混乱:网格旁边可能有别的文字、手指、桌面纹理,全都需要排除。
  • 数字风格多样:印刷体、手写体、粗细不一,甚至还有写一半的。

这些问题在教科书里是每个独立章节,在数独项目里是一连串必须连贯处理的现实障碍。做完这个项目,等于把图像去噪、二值化、边缘检测、轮廓查找、透视校正、图像分割、字符识别、坐标变换、结果可视化全打通了一遍。

拿我自己举例,最初我直接对原图做全局二值化,结果阴影区域里的数字全被当成背景吃掉了,后来才换成自适应阈值;最初我假定网格是正的,直接均分 9 份,结果歪了的照片切出来的格子边缘全是斜线,数字被切得七零八落。这些坑,每一个都对应一个经典知识点,踩一遍比看十遍书都管用。

1.2 从像素到答案的完整链路

整个项目我拆分成了 9 个步骤,每个步骤都有明确的输入输出:

步骤操作输入输出对应知识点
1图像加载与缩放手机照片统一尺寸的彩色图图像格式、缩放插值
2灰度化与去噪彩色图干净的灰度图色彩空间转换、高斯滤波
3二值化/边缘检测灰度图前景与背景分离的二值图阈值分割、边缘检测
4提取网格外轮廓二值图数独外边框的四个角点轮廓查找、多边形逼近
5透视校正原图+角点正视角的方形数独图单应矩阵、透视变换
6切分 9x9校正后的图81 个格子的小图投影法、图像切片
7数字识别格子小图81 个数字或空模板匹配/CNN
8数独求解81 个数字完整答案矩阵回溯搜索
9结果叠回原图答案+变换矩阵带答案的标注图逆透视、坐标映射

很多人一开始会想:能不能搞一个端到端深度学习模型,输入照片直接输出答案?技术上可行,但作为学习项目非常不推荐。端到端模型是个黑盒,哪一步错了你根本不知道是“网格没找到”还是“数字没认出”,也没法逐步调试。分步管线的好处是每一步都能输出中间结果图,出了问题看一眼就知道坏在哪一步。这个调试思路,在真实工程里比任何花哨算法都重要。

1.3 工具选型:Python 加 OpenCV 就够了

整个项目我用的是 Python 和 OpenCV,求解部分自己写了个回溯(大约 50 行),识别先用模板匹配跑通,最后换成了简单卷积网络。为什么不直接用 C++?因为前期大量工作是调参数、看中间结果,Python 的交互式环境效率高得多。等以后要做实时视频流或者部署到手机上,再换成 C++ 或者模型端侧推理,那是后话。

OpenCV 里我主要用到的模块就几个:cv2.findContours找轮廓、cv2.approxPolyDP做多边形逼近、cv2.getPerspectiveTransform算透视矩阵、cv2.warpPerspective做校正变换、cv2.matchTemplate做模板匹配。每个函数单独拿出来都不难,难的是把它们串起来的时候才知道参数怎么配合。

2. 拍照时网格是歪的:先做预处理和透视校正,而不是急着识别

2.1 灰度化、去噪和自适应阈值的选择逻辑

拿到一张手机照片,第一件事绝对不是识别数字,而是先把图像变干净、把网格找出来。我先用cv2.cvtColor转灰度,然后用 5x5 的高斯滤波去噪。高斯滤波的核大小是个经验值:太小去不掉传感器噪声,太大容易把数字边缘糊掉。

关键的一步是二值化。我最初用了全局阈值cv2.threshold,发现只要照片上有不均匀阴影,全局阈值就废了——阴影区的白底被当成黑,数字直接消失。后来换成了cv2.adaptiveThreshold,它的原理是对每个像素和它周围一个小邻域的平均亮度做比较,相当于每个局部区域自动选取阈值。这就是为什么它能在光照不均的情况下仍然把数字和背景分开。我用的参数是blockSize=15, C=2,意思是每个像素和周围 15x15 窗口的平均灰度比较,谁更暗超过 2 个灰度级就置为黑。

如果是在强光、带纹理的纸面上拍,单纯自适应阈值偶尔会把纸面纹路当成前景。这种情况我建议先试Canny边缘检测再做轮廓查找,效果往往更稳。

2.2 用轮廓查找定位数独外边框

二值化之后,数独网格的外边框会形成一个大的闭合轮廓。我使用cv2.findContours提取所有轮廓,然后筛选:

  • 先按面积过滤,只保留占整张图面积一定比例以上的轮廓;这一步能去掉桌面纹理、手指、纸屑。
  • 再用cv2.approxPolyDP对方形轮廓做多边形逼近,筛选出四边形。approxPolyDP的 epsilon 参数我取周长的 2%,这个值很重要,太大导致四边形失真,太小又把弯曲的边界拆成很多段。
  • 数独外框在图像中通常是面积最大的四边形,所以按面积排序,取最大那一个。

这里有个很容易翻车的点:如果照片里数独边框恰好和照片边缘重合了一部分,那么最大的“轮廓”可能把整张照片都包进去了,不收敛成一个四边形。我后来加了一个校验:四个点形成四边形之后,检查四条边的长度是否接近,四个角是否接近直角。如果校验不通过,就把这个候选丢弃,换下一个轮廓。

2.3 透视变换不是简单的裁剪,是平面单应

找到四个角点之后,它们对应的是数独网格在真实纸面上的一个正方形。我们要把照片里那个任意四边形“拉正”成正方形,这个操作叫透视变换,数学上用一个 3x3 的单应矩阵描述,OpenCV 里cv2.getPerspectiveTransform会根据四对对应点直接算出这个矩阵。

我用下面的代码完成校正:

import cv2 import numpy as np def order_points(pts): # 四个点按左上、右上、右下、左下排序 rect = np.zeros((4, 2), dtype="float32") s = pts.sum(axis=1) rect[0] = pts[np.argmin(s)] rect[2] = pts[np.argmax(s)] diff = np.diff(pts, axis=1) rect[1] = pts[np.argmin(diff)] rect[3] = pts[np.argmax(diff)] return rect src = order_points(approx.reshape(4, 2)) dst = np.array([[0, 0], [450, 0], [450, 450], [0, 450]], dtype="float32") M = cv2.getPerspectiveTransform(src, dst) warped = cv2.warpPerspective(img, M, (450, 450))

这段代码里最有信息量的是M。这个矩阵不只在这次校正中用到,后面把答案写回原图时,需要用它的逆矩阵做反向映射。我一开始没保存M,第五步往回画的时候还得重新算,后来学乖了,一开头就把M和M_inv = cv2.linalg.inv(M)都存好。

2.4 三个经典翻车场景:边框断裂、反光和阴影

  • 边框断裂:铅笔线断了一截,findContours找出来的轮廓是断开的,无法形成闭合四边形。解决办法是在二值化之后先做一次闭运算,用小核把断点连起来。核用 3x3 就够了,核太大会把数字和附近的格线黏在一起。
  • 反光:照片上有强反光时,反光区域会变成纯白,整个网格看起来缺了一个角。这种情况自适应阈值的局部窗口也会失效。我实测下来,先用cv2.medianBlur或者用Canny检测边缘,再补一次膨胀,比单纯调阈值管用。
  • 阴影边缘:纸面上有手指阴影,且阴影恰好压在边框线上。这时外轮廓面积可能变小。我给轮廓筛选加了一个“最小包围边长”的约束,同时把输入图像先等比缩放到固定宽度,保证不同距离拍摄的轮廓面积在一个可比尺度下。

3. 切开 9x9:网格分割里的坐标陷阱

3.1 为什么不能直接均分九等份

很多人透视校正完就认为大功告成,直接把 450x450 的图像切 9 块,每块 50x50。我一开始也这么干,结果发现:网格的粗线本身占了 2~4 个像素,直接按均分会导致某些格子切到了相邻数字,某些格子把边框线算进去了。更麻烦的是,校正之后如果仍有 1 度左右的旋转残余,越靠近右下角的格子误差越大。所以必须找到真正的格线位置,而不是假定它们均匀分布。

3.2 用投影法找到格线的精确位置

格线提取我用的方法是投影法。对校正过的二值图,分别按行和列做像素值求和:白线(格线)所在的行或列会有明显的高峰,非线区域数值很低。找到这些峰值的位置,就得到了所有横线和竖线的坐标。

def find_lines(binary_image, axis=0): proj = binary_image.sum(axis=axis) lines = [] in_line = False for i, v in enumerate(proj): if v > threshold and not in_line: start = i in_line = True elif v < threshold and in_line: end = i mid = (start + end) // 2 lines.append(mid) in_line = False return lines

注意我取的是每一条连续高亮区间的中点,而不是峰值点。因为格线可能有 2~3 个像素宽,取中点可以消除宽度带来的偏差。因为数独内有 10 条横线和 10 条竖线,检测到 10 个横坐标和 10 个纵坐标,就得到了 10x10 个交叉点。用这些交叉点的坐标作为切割边界,每个格子两侧各留 2 个像素的余量,再把格子小块裁剪出来。

3.3 切割后的格子校验与空白格判别

切出来的格子小图,我在送入识别前做三件事:

  • 尺寸归一化:把所有 48x48 的格子小图直接 resize 到统一尺寸,识别网络的输入固定。
  • 背景清理:检查格子小图边缘是否有非零像素,如果有,说明格线残留,做一次腐蚀边缘处理。
  • 空白判定:统计小图中黑色像素占比,如果低于某个阈值(比如 2%),判定为空格,不送识别器,直接标记为 0。这个步骤能大幅减少误识别,因为空格如果硬送进分类器,反而可能被莫名其妙分类成某个数字。

3.4 坐标陷阱:直线有斜率,交叉点需要矩心校正

用 HoughLines 提取格线时若直接求两线交点,由于照片歪斜矫正后仍有残余旋转,横线和竖线并不绝对垂直,直接相交得到的点可能偏离真实网格节点。我的做法是把检测到的所有交叉点收集起来,然后对每个真实节点周围的候选点求平均值,相当于做一次聚类的矩心。这一步对后面的答案回填非常重要,坐标偏几个像素,原图上数字位置看起来就歪了。

有一个小经验:校正后的图像尺寸我固定用 450x450,一方面保证格子约 50x50 大小适合识别,另一方面让交叉点坐标基本是整数,调试时肉眼看一下输出数组就能发现问题。

4. 数字识别是计算机视觉和机器学习的交接处

4.1 模板匹配:不需要训练数据也能跑的 MVP

先把识别这条线跑通,我用的是模板匹配。做法是准备 10 张标准打印数字模板(0~9,我直接用绘图软件生成),每张缩放到 32x32。然后对每个格子小图做同样的预处理,再用cv2.matchTemplate加TM_CCOEFF_NORMED计算相似度,取分数最高的作为结果。

模板匹配的优点是零训练成本、代码量小,打印体数字识别率很高。我实际测试了几张印刷清晰的数独照片,正确率大概在 90% 左右。缺点是极其死板,换一种字体、换一个笔迹,分数立刻掉下去;数字稍微旋转一点也会失效。刚开始调试 pipeline 时,用它当占位符是非常明智的,因为你需要先确认网格分割、透视校正这些环节是对的,再去优化识别。

4.2 简单卷积网络:更稳但要会做数据增强

流程稳定之后,我把识别模块换成了一个小型卷积网络:三层卷积加池化,接两个全连接层,输入 48x48 灰度图,输出 10 类。训练数据用的是公开手写数字数据集,训练集几万张,足够用了。

但直接拿公开数据集训练出来的模型放到数独照片上表现并不好。原因很简单:公开数据集里的数字是居中的、手写的、笔画集中的,而数独照片里的数字可能偏低、偏大、边缘残缺。我的解决办法是训练时做数据增强:随机平移最多 3 个像素、随机缩放 0.9~1.1 倍、随机旋转正负 5 度。这么一弄,真实照片上的识别率明显提升,误判主要集中在“3”和“8”、“1”和“7”这几组容易混淆的数字上。

4.3 识别前的归一化细节:保持宽高比而不是直接拉伸

把格子小图送进网络之前,我踩过一个细节坑:如果直接cv2.resize拉伸到 48x48,会把原本细长的“1”拉宽成粗胖的“1”,也会把横向较宽的“3”压扁,导致误识别。正确的做法是:先找数字的连通域,必要时用cv2.connectedComponentsWithStats找到数字包围盒,然后把包围盒按比例缩放到 40x40 左右,再居中放进 48x48 的白底画布。这样一来数字的原始宽高比保留住了,网络输入也不会因为白边太多而丢失特征。

4.4 误识别的常见来源和投票策略

总结下来,误识别基本来自四类情况:

  • 空格被识别成数字(所以空白阈值必须先判断)
  • 数字偏小、笔画太细,导致特征不足
  • 格线残边进入小图,干扰了分类
  • “6”和“8”、“9”和“3”这类结构相似的数字,在分辨率低的情况下确实容易混

我最后的方案是引入投票:对同一张格子图,分别用原始图、轻微膨胀图、轻微腐蚀图各识别一次,三个结果取多数。如果三个结果完全不一致,就标记为低置信度,人工或按概率最高的结果处理。这个投票策略简单有效,能把整体识别率达到 95% 以上。

5. 把答案写回原图:坐标逆变换的最后一公里

5.1 一开始就要保存单应矩阵,别返回去找

前面的步骤做完,识别出的 81 个数字(空位为 0)组成了一个棋盘矩阵。求解器我用的是回溯,纯 Python 跑一个数独题大概 30~50 毫秒,完全够用。问题是答案最后要显示在用户拍的那张歪斜照片上,这时候如果当初没保存透视矩阵,就得重新找一遍角点再算一次,非常麻烦。

所以再次强调:在第 2 步计算M = cv2.getPerspectiveTransform(src, dst)时,立刻保存M和M_inv。把答案从校正图坐标映射回原图坐标,用M_inv对校正图上的点做透视变换即可。

pts_corrected = np.array([[col * cell, row * cell] for col in range(9) for row in range(9)]) pts_original = cv2.perspectiveTransform(pts_corrected.reshape(-1, 1, 2).astype(np.float32), M_inv)

5.2 反向映射到原图写数字的细节

得到原图坐标后,我在每个格子内部用cv2.putText写答案。这里有一个显示上的问题:直接把答案覆盖到题目数字上,会遮住原有题目,用户看不出来哪个是题目哪个是答案。我的做法是:

  • 题目原有的数字保留黑色
  • 答案数字用深红色写在格子中心偏下的位置,避免和原有数字重叠
  • 如果格子里原本有数字,把答案写到右下角空白处

写字前最好先根据每个格子的实际四边形边长估算字体大小。校正图上格子是 50x50,但原图上距离不同、透视不同,远处格子看起来小,近处格子看起来大。直接用一个固定字体大小会让远处数字挤满格子、近处数字显得太小。我按照每个格子四边形的平均边长比例动态计算字体大小,效果会自然很多。

5.3 防止答案遮挡和视觉混乱的处理

还有一个不起眼但很重要的点:当答案数字和题目数字在同一个格子里时,要处理遮挡。我测试时发现直接把红色答案写在题目黑色数字正上方,不仅看不清,还容易被用户误认为印刷重叠。后来我把答案统一放在格子对角位置,并给答案加一圈白色描边,这样即使和题目交叠,也能清楚地分离出来。这个处理在实际演示中效果非常好,别人一眼就能分清印刷的题目和红色答案。如果你做的是视频流版本,还可以把答案区域做成半透明浮层,动态切换显示与隐藏。

6. 项目复盘:这些参数和思路值得存档

6.1 我最终固定下来的参数参考表

环节参数/操作取值说明
缩放等比缩放宽高宽 600~900太大影响速度,太小轮廓不稳定
高斯滤波核大小5x5去除传感器噪声
自适应阈值blockSize, C15, 2光照不均时明显优于全局阈值
形态学闭运算核3x3连接断裂网格线,一次即可
外轮廓筛选多边形逼近 epsilon周长 x 2%偏小容易多出顶点,偏大丢失直角
校正输出尺寸450x450每格约 50x50,识别器输入友好
格线提取投影阈值最大值 x 0.5峰值超过中位值一半才认作格线
数字模板模板尺寸32x32配合 matchTemplate 足够
识别输入归一化尺寸48x48保留宽高比后居中填充
空白判定黑像素占比< 2% 判为空避免空格被误识别

这些参数不是从哪本书抄来的,而是反复试出来的。你换一批照片很可能需要微调,但调整的方向和逻辑是一样的:先看中间结果,确定崩在哪一步,再顺势调参。比如线条断了就搞形态学,不要埋头加高斯核;数字模糊就加大模板尺寸或者换网络,不要盲目膨胀。

6.2 从失败案例中学会的调试习惯

这个项目我做了一半进度时,识别率一直在 60% 徘徊,每天改参数都像无头苍蝇。后来意识到一个问题:我从来没把每一步的中间结果保存下来过。于是我在每个模块后加了一行cv2.imwrite,把灰度图、二值图、轮廓图、校正图、格子切分图全部导出。导出之后,20 秒就能定位到问题是出在轮廓提取还是在数字分类。这个习惯帮我节省了至少两天的改参数时间。

强烈推荐你也这么做。不要省那几行代码,中间结果是你调试时唯一的眼睛。尤其是轮廓绘制那一步,把找到的四个角点点在原图上看看位置,如果角点偏了,后面一切都会跟着错。

6.3 这个项目还能往哪些方向延伸

  • 实时视频识别:手机或摄像头对准数独,画面里实时叠加答案,需要把单应矩阵每一帧重新计算或做平滑跟踪。
  • 手写数独:把模板匹配换成更鲁棒的字符识别模型,或者用手写数字增强数据重新训练。
  • 模糊/遮挡数独:加入超分辨率或去阴影模块,这是更接近真实场景的需求。
  • 边缘人像拍摄:倾斜角度特别大时,四边形的检测容易失效,可以研究更鲁棒的角点检测方法。

最后说点实践经验

做完这个项目,我最大的体会是:计算机视觉不是一个“调库”的领域,而是一个“理解像素如何流转”的领域。数独题目看起来简单,但它把图像的获取、增强、分割、识别、几何变换、结果合成全部串起来,每一步都对应一个经典问题。如果哪天有人问我入门 CV 做什么项目好,我还是会推荐做一遍数独识别,数据好获取、问题边界清晰、成就感来得快。

最后分享一个小技巧:先拿一张打印清晰、正对拍摄的“标准图”把整条流水线调通,再拿一张随手拍的“地狱图”来打磨每个环节。这样做的好处是,你永远知道问题出在哪个环节,而不是在两张照片之间胡乱改参。这个思路,也适用于很多其他视觉任务。

相关新闻

本科论文写作不卡壳:8个AI工具组合全流程拆解

本科论文写作不卡壳:8个AI工具组合全流程拆解

本科论文这事儿&#xff0c;最磨人的其实不是“写”&#xff0c;而是从起笔到交稿这一路上不停卡壳&#xff1a;选题没方向、几十篇文献读不完、初稿憋不出三千字、改完又觉得全是口水话……我前后帮不少同学看过论文&#xff0c;也琢磨过很多AI论文写作软件&#xff0c;最后留…

2026/10/20 21:25:33 阅读更多 →
S/4HANA部署方式选型指南:MTE、STE、HEC与本地部署对比

S/4HANA部署方式选型指南:MTE、STE、HEC与本地部署对比

简介&#xff1a;SAP S/4HANA部署方式梳理笔记&#xff0c;面向正在规划S/4HANA上云或本地落地路径的顾问、架构师及企业IT决策者&#xff0c;帮助快速厘清不同部署模式之间的差异和选型要点。资源包共1个docx文档&#xff0c;大小约62KB&#xff0c;内容紧凑&#xff0c;重点分…

2026/10/20 21:25:33 阅读更多 →
Matlab指纹识别全链路系统:从预处理到匹配打分的可调试实现

Matlab指纹识别全链路系统:从预处理到匹配打分的可调试实现

简介&#xff1a;这是一套面向本科生与初学者的Matlab指纹识别系统完整实现方案&#xff0c;适用于毕业设计、课程设计及期末大作业等实践场景&#xff0c;聚焦图像预处理、二值化、细化、特征点提取与匹配等核心算法环节。资源包含40个文件&#xff0c;以12个核心.m脚本&#…

2026/10/20 21:25:33 阅读更多 →

最新新闻

知识蒸馏进阶:变分信息蒸馏VID原理与实战

知识蒸馏进阶:变分信息蒸馏VID原理与实战

1. 从知识蒸馏的瓶颈说起如果你这两年一直在跟进模型压缩和知识蒸馏方向&#xff0c;大概率会有一种感觉&#xff1a;传统KD&#xff08;Knowledge Distillation&#xff09;那套“软标签KL散度”的玩法&#xff0c;在早期分类任务上确实好使&#xff0c;但一旦碰到特征维度高、…

2026/10/20 22:18:29 阅读更多 →
5秒进3秒出片:AI视频风格化与V2V技术实测解析

5秒进3秒出片:AI视频风格化与V2V技术实测解析

1. 这个标题背后的需求&#xff0c;其实没你想的那么简单先问一句&#xff1a;你说的“出片”&#xff0c;到底是哪种“出片”&#xff1f;我拿这个标题去问了一圈做短视频的朋友&#xff0c;得到的答案五花八门。有人说我要的是“我拍一段真人视频&#xff0c;AI直接给我变成动…

2026/10/20 22:18:29 阅读更多 →
Notepad++下载安装与配置全攻略:避坑指南与效率提升技巧

Notepad++下载安装与配置全攻略:避坑指南与效率提升技巧

我电脑里常年躺着好几个文本编辑器&#xff0c;但要说最顺手、打开最快、从大学写代码到现在写博客都离不开的那个&#xff0c;还得是Notepad。这软件太出名了&#xff0c;以至于很多人觉得“下载安装还有什么好说的&#xff0c;官网一搜不就有了吗”。但我在实际工作和帮朋友弄…

2026/10/20 22:18:29 阅读更多 →
零代码打造机械臂遥控器:智能体开发实录与硬件控制边界探索

零代码打造机械臂遥控器:智能体开发实录与硬件控制边界探索

1. 从"一行代码没写"说起&#xff1a;这个标题到底在讲什么第一次看到"我一行代码没写&#xff0c;机械臂遥控器做出来了"这个标题&#xff0c;我的反应是&#xff1a;要么是标题党&#xff0c;要么背后有一套相当成熟的智能体开发范式在支撑。仔细拆解之后…

2026/10/20 22:18:29 阅读更多 →
AMD收购Xilinx后Vivado工具链稳定性与迁移策略解析

AMD收购Xilinx后Vivado工具链稳定性与迁移策略解析

1. 从一句调侃说起&#xff1a;AMD与Vivado之间到底什么关系“AMD Ross没有介入Vivado的私生活”这句话第一次看到的时候&#xff0c;我正蹲在一个FPGA开发群里看人吐槽工具链。乍一看像八卦标题&#xff0c;实际上是个技术梗——它调侃的是AMD收购Xilinx之后&#xff0c;很多人…

2026/10/20 22:18:29 阅读更多 →
多Agent系统架构设计与工程实践:从单Agent瓶颈到Agent蜂群

多Agent系统架构设计与工程实践:从单Agent瓶颈到Agent蜂群

1. 多Agent系统到底在解决什么问题1.1 从单Agent的瓶颈说起做过Agent项目的人大概都有这种体会&#xff1a;单个Agent在简单任务上表现还行&#xff0c;一旦任务链路变长、涉及的工具变多、需要同时处理的信息源超过三四个&#xff0c;它就开始“犯糊涂”了。具体表现包括&…

2026/10/20 22:17:20 阅读更多 →

日新闻

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实现详解

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

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

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在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 阅读更多 →