gocv图像处理:水平投影与垂直投影实现文本行切分
做图像处理做得久了难免有个体会不少看着高级的活儿根基反而是特别朴素的小操作。比如把一张合同扫描件里的文字块自动拆成一行一行、再拆成一个一个字符很多人上来就考虑上模型可实际上真正第一步往往是先把图做成二值图再沿着横向、纵向各数一遍白色像素——这就是我要聊的水平投影和垂直投影。原理一句话就能讲清楚水平投影是统计图像每一行里白色像素的个数垂直投影是统计每一列里白色像素的个数。二维图像经过这一步直接被压成两条一维数组文本行切分、字符分割、车牌定位、表格线检测这些都从这两条数组上找到了突破口。我在几个实际项目里都是用这个方案先做预处理既稳又快。我目前主要用Go写机器视觉程序用的库是gocv也就是OpenCV在Go生态里最成熟的绑定。这篇文章从投影原理出发用gocv把水平投影和垂直投影从代码到调试完整过一遍。想快速在OCR、文档分析项目里落地行切分的人或者刚碰gocv想搞明白图像基础操作怎么写的人都可以拿这篇当作一个能直接抄作业的参考。整体流程大概是这样读图 - 灰度化 - 二值化 - 水平投影 - 垂直投影 - 区间切分 - 可视化验证。下面一步一步来。1. 为什么投影能解决切分问题1.1 用行和列的“密度”理解投影先举一个生活化的例子。想象一下雪地上走过一排人站在二楼往下看每个人在雪地上踩出的脚印位置是不同的。如果沿着水平方向把雪地划成很多条细长的“横条”数一数每条横条里有多少脚印得到的就是水平投影如果沿着垂直方向划“竖条”数每条竖条里有多少脚印得到的就是垂直投影。换成图像来说一张二值图里白色像素就是“脚印”。水平投影相当于把图像按行切开每一行数一下白色像素的数量最后得到一个长度为图像行数的一维数组垂直投影则是按列统计得到一个长度为图像列数的一维数组。这一步的本质是降维把一张几千乘几千的二维矩阵压缩成两条一维曲线后续的分析和切分直接在这两条曲线上做计算量小很多。这也是为什么投影算法在机器视觉预处理里地位很高——它不依赖训练数据不需要GPU纯粹靠像素分布规律就能解决一大批版面分析问题。很多看似玄乎的OCR前置工作其实都是从这一对简单的统计操作开始的。1.2 文本行切分是怎么用投影的投影最经典的用法就是文本行切分。假设现在有一张扫描的文字段落做二值化之后字符是白色背景是黑色。先对整张图做水平投影文字所在的行白色像素数量很大行与行之间的空白区域白色像素数量接近0。于是水平投影曲线上会出现一个个“凸起”和“凹陷”凹陷就是行间距凸起就是文字行。拿到这些凸起对应的行号区间之后再把每一行单独抠出来对该行做垂直投影一样的方式字符所在的列白色像素多字符间隙的列白色像素少垂直投影的谷底就是字符切分点。整段文字就这样被一层一层拆开先拆行再拆字整个过程不需要人工参与。有个点需要提前说一下这套方法对规整的印刷体非常有效对倾斜或者有严重透视变形的图片会打折扣。原因也很直观文字一旦倾斜水平投影里行与行之间原本干净的空白会被倾斜的笔画“穿破”谷底抬起来切分就不干净了。后面我会讲一些应对倾斜和噪声的思路。1.3 除了OCR投影还能用在哪些场景投影可干的事不止是文字切分。我这些年遇到过的场景大概有这几类车牌字符分割车牌区域定位成功之后水平投影先确定字符占用的上下边界垂直投影再确定每一个字符的左右边界这套流程比用连通域分析更稳定。表格线检测网格线的特征是横平竖直对表格图做水平投影和垂直投影会得到非常尖锐的峰值根据峰值位置可以还原出表格横线与竖线的坐标后续做单元格拆分就很方便。文档版面分析一页报纸或者论文标题、正文、图片区块的投影特征差异很大用水平投影可以先粗分出段落块再用垂直投影判断这个块是单栏还是双栏。简单目标定位如果目标在图像里是一个明显的高密度区域比如一行LED灯珠、一排试剂孔投影找峰值的思路完全可以用。可以说投影是机器视觉里一个万金油级的前置算子。很多更复杂的算法比如基于连通域的分割、基于形态学的分块本质上也在间接利用这些分布特征。2. gocv环境与二值化前置处理2.1 把gocv跑起来gocv是OpenCV C库的Go绑定安装本身不难但是因为要编译C/C代码第一次装的时候需要一点耐心。用Go Modules的方式在项目里执行go get -u gocv.io/x/gocv执行完还不算完gocv依赖系统里的OpenCV库Linux环境下一般要先装好基础依赖包。我记得Ubuntu系可以这样装sudo apt install libopencv-dev如果是Windows或者macOSgocv官方文档里也提供了对应的安装脚本。这里不多展开因为不同系统的差异比较大装好之后先跑一个最小的demo验证环境能输出OpenCV版本号就说明OK了package main import ( fmt gocv.io/x/gocv ) func main() { ver : gocv.OpenCVVersion() fmt.Println(OpenCV Version:, ver) }我第一次装的时候卡在链接阶段后来发现是系统里同时存在多个OpenCV版本把多余的版本清理掉就好了。遇到编译报错先别慌绝大多数问题都出在依赖库版本不匹配上。2.2 读图与灰度化投影统计的是像素分布不需要颜色信息。所以第一步就是把图像转成灰度图。用gocv读图时可以顺便指定灰度模式img : gocv.IMRead(text.png, gocv.IMReadGrayScale) if img.Empty() { log.Fatal(read image failed) } defer img.Close()如果你的图片已经用彩色模式读进来了也可以手动转灰度gray : gocv.NewMat() defer gray.Close() gocv.CvtColor(img, gray, gocv.ColorBGRToGray)这两种写法效果一样看实际场景选择。需要注意的一点是IMRead的第二个参数决定了读入通道数如果后面还要显示原图或者做颜色相关的处理就别在读取时降成灰度如果只是做投影这种纯几何统计直接灰度读入能省一次转换和一部分内存。2.3 二值化让投影变得干净投影之前必须做二值化。你可能会想灰度图不是也能统计吗理论上是可以但灰度图里有渐变、噪声、阴影投影曲线上会有很多不规则的毛刺切分阈值很难定。二值化之后像素只有0和255两种统计结果干净利落前后景分明。gocv里最省事的做法是用Otsu自动阈值它根据灰度直方图的分布自动计算分割阈值不用你手动去试bin : gocv.NewMat() defer bin.Close() gocv.Threshold(gray, bin, 0, 255, gocv.ThresholdBinarygocv.ThresholdOtsu)第三个参数0在Otsu模式下会被忽略因为阈值由Otsu算法自己算出来。这里我强烈建议凡是做投影的场景能上Otsu就上Otsu除非你测试过固定阈值的效果更好。手动试出来的阈值换一张图可能就不灵了Otsu至少能保持一定程度的自适应性。二值图里有一个特别容易踩的坑前景和背景的颜色方向。我们通常约定投影统计的是白色像素也就是255那一类。如果你的图片是白底黑字用ThresholdBinary得到的二值图背景是白色、字符是黑色投影统计的“白色像素”实际是背景表现就是整张图的投影几乎都非零行与行之间根本没有谷底。这种情况通常有两个解决办法// 方案一用反向二值化让字符变白、背景变黑 gocv.Threshold(gray, bin, 0, 255, gocv.ThresholdBinaryInvgocv.ThresholdOtsu) // 方案二先正常二值化再做一次位取反 gocv.BitwiseNot(bin, bin)我只用方案一的情形比较多一步到位代码也干净。至于哪种方向正确判断标准很朴素字符区域应该是白色。拿到二值图之后看两眼白字黑底就是对的黑字白底就要反转。3. 核心实现水平投影和垂直投影3.1 第一版用GetUCharAt逐像素统计最直观的写法是遍历每一个像素逐个判断是不是白色。gocv的Mat提供了GetUCharAt方法可以读取指定位置的像素值func HorizontalProjection(src gocv.Mat) []int { proj : make([]int, src.Rows()) for y : 0; y src.Rows(); y { count : 0 for x : 0; x src.Cols(); x { if src.GetUCharAt(y, x) 0 { count } } proj[y] count } return proj }对应的垂直投影func VerticalProjection(src gocv.Mat) []int { proj : make([]int, src.Cols()) for x : 0; x src.Cols(); x { for y : 0; y src.Rows(); y { if src.GetUCharAt(y, x) 0 { proj[x] } } } return proj }这个版本的优点是非常容易读懂适合第一次接触投影算法的人做验证。缺点也很明显GetUCharAt内部要做类型检查和越界断言在大图上循环调用开销不小。我拿一张大约1200×800的二值图做过对比这个版本跑一次水平投影大概要十几毫秒垂直投影因为内存访问顺序不连续还要更慢一些。如果你只是做一次离线预处理这个速度倒也不是不能用。但如果要在高分辨率视频帧或者批量处理大量图片时用就得考虑更高效的办法了。3.2 用RowPtr直接访问行内存gocv的Mat在内存布局上每一行是连续存储的。RowPtr方法可以直接拿到某一行数据的字节切片省掉GetUCharAt的函数调用和类型断言性能提升非常明显func HorizontalProjectionFast(src gocv.Mat) []int { proj : make([]int, src.Rows()) for y : 0; y src.Rows(); y { row : src.RowPtr(y) count : 0 for x : 0; x src.Cols(); x { if row[x] 0 { count } } proj[y] count } return proj }注意RowPtr返回的切片长度是行数 x 通道数对于我们处理单通道二值图来说通道数就是1所以下标x对应第x列像素值。如果传入的是三通道彩色图内存布局完全不同直接按字节统计就会得到奇怪的结果。所以用RowPtr之前务必确认Mat的类型确实是CV_8UC1。垂直投影也可以用RowPtr优化只是列的访问天然跨行没法做到连续访问但至少省掉了GetUCharAt的开销func VerticalProjectionFast(src gocv.Mat) []int { proj : make([]int, src.Cols()) for y : 0; y src.Rows(); y { row : src.RowPtr(y) for x : 0; x src.Cols(); x { if row[x] 0 { proj[x] } } } return proj }我在自己的机器上测试RowPtr版本大约比GetUCharAt版本快3到5倍。不同机器、不同图像尺寸会有差异但量级感受就是这样。对于生产环境里的批量图像处理这个小优化往往就能省下不少时间。3.3 投影结果可视化投影算出来之后是一堆int数组光看数字不够直观尤其是调试过程中很难一眼看出曲线哪里是峰、哪里是谷。我习惯把投影画成一张柱状图直接在屏幕上或者保存成文件看。用gocv画图很简单思路是创建一张白色的单通道图然后在每个坐标位置画一条竖直的黑线线的长度按投影值归一化到图片高度func DrawProjection(proj []int, height int) gocv.Mat { img : gocv.NewMatWithSize(height, len(proj), gocv.MatTypeCV8U) img.SetTo(gocv.NewScalar(255, 255, 255, 255)) maxVal : 0 for _, v : range proj { if v maxVal { maxVal v } } if maxVal 0 { maxVal 1 } for i, v : range proj { barHeight : int(float64(v) / float64(maxVal) * float64(height-2)) pt1 : image.Pt(i, height-1) pt2 : image.Pt(i, height-1-barHeight) gocv.Line(img, pt1, pt2, gocv.NewScalar(0, 0, 0, 0), 1) } return img }保存或者显示projImg : DrawProjection(hProj, 200) gocv.IMWrite(h_proj.png, projImg) projImg.Close()有了这张图二值化方向对不对、噪声重不重、行间谷底是否干净一眼就能判断。我后面排查问题几乎全靠它。4. 实战文本行切分与字符切分4.1 从投影数组找连续区间有了投影数组下一步就是从里面找出哪些连续区间属于文字区域。核心逻辑是遍历数组当值大于阈值时认为进入了前景区域当值小于等于阈值时认为离开了前景区域type Span struct { Start int End int } func FindSpans(proj []int, threshold int) []Span { var spans []Span inSpan : false start : 0 for i, v : range proj { if v threshold { if !inSpan { inSpan true start i } } else { if inSpan { inSpan false spans append(spans, Span{Start: start, End: i}) } } } if inSpan { spans append(spans, Span{Start: start, End: len(proj)}) } return spans }threshold在多数干净图像上可以直接取0也就是只有完全没有白色像素的行才算空白行。但总有些图带着噪声或者笔画延伸到了行间空白地带这时候阈值可以调成2或者3把像素数极少、不算有效前景的杂质行过滤掉。这里有个经验阈值太小过滤不了噪声阈值太大又会吃掉笔画稀疏的字符导致一些左右结构的字被切裂。所以一般先画投影图观察一下谷底的高度再决定阈值。我通常从0开始碰到毛刺再往上加到2、3极少超过5。4.2 完整流程按行再按列切开下面把这几个函数串起来实现一个完整的文本行和字符切分流程。package main import ( fmt image log gocv.io/x/gocv ) func main() { // 读图并二值化假设是白底黑字所以用 BinaryInv 让字符变白 img : gocv.IMRead(text.png, gocv.IMReadGrayScale) if img.Empty() { log.Fatal(read image failed) } defer img.Close() bin : gocv.NewMat() defer bin.Close() gocv.Threshold(img, bin, 0, 255, gocv.ThresholdBinaryInvgocv.ThresholdOtsu) // 第一步水平投影找出每一行的上下边界 hProj : HorizontalProjectionFast(bin) lines : FindSpans(hProj, 0) fmt.Printf(共检测到 %d 行文字\n, len(lines)) // 第二步对每一行做垂直投影切出字符 for i, line : range lines { region : bin.Region(image.Rect(0, line.Start, bin.Cols(), line.End)) vProj : VerticalProjectionFast(region) chars : FindSpans(vProj, 0) fmt.Printf(第 %d 行字符数量 %d\n, i, len(chars)) // 这里可以基于 chars 的左右坐标在原图或者原图上框出每个字符 for _, ch : range chars { // ch.Start, ch.End 就是当前字符的左右列范围 _ ch } region.Close() } }Region返回的是原二值图的一个“视图”本质上是共享内存区域用完一定要Close避免引用计数一直不减导致内存释放不掉。这个我在早期版本里经常漏掉后来已经变成肌肉记忆了。实际跑一遍你会发现只要输入图像质量还可以这个流程对不同字号、不同行距的文字块都适应得不错不需要针对单张图单独调参数。这就是投影方法的性价比所在。4.3 边界情况和参数细节这套流程看着简单碰到现实里的图片还是有几个需要处理的地方。一是行距非常小的情况。有些扫描件行距压得很低水平投影的谷底虽然存在但可能只有一行像素是0甚至连续几行都是几十个像素。这时候可以先用形态学方法拉大行距特征比如对二值图做一个水平方向的开运算或者干脆用一个小尺寸的矩形核对二值图做膨胀让字符的上下笔画产生更多重叠投影的峰就会更“胖”谷底也就更干净。二是字符间距非常密的情况。印刷体的字距通常都不会太小但有些艺术字体笔画会延伸到相邻字符之间垂直投影的谷底会抬起来。处理办法是用一个小的矩形核对二值图做腐蚀先把细的粘连点断掉再做垂直投影。注意腐蚀会同时把笔画变细可能导致字符投影高度下降但只要不影响切分就行。三是文字倾斜。如果图片里的文字不是水平的水平投影的曲线干净程度会直线下降。常见解决办法是先做倾斜校正用最小外接矩形找到文字整体倾斜角度然后用仿射变换把图片转正再来做投影。gocv里旋转变换的API可以直接实现rotated : gocv.NewMat() defer rotated.Close() rotated gocv.WarpAffine(src, gocv.NewMat(), ...)具体参数这里不展开了核心思路是先算角度后校正校正干净了投影才能发挥威力。5. 踩坑记录与调试技巧5.1 常见问题速查表现象可能原因排查与解决办法投影全是0或者近乎0二值化方向反了白色像素变成背景改用ThresholdBinaryInv或对二值图做BitwiseNot投影曲线毛刺特别多图像噪声重、二值化后有很多散点投影前先做一次开运算或者高斯模糊再二值化一行文字被切成多段行间有笔画穿越、谷底没有归零调大FindSpans的threshold对二值图做适度的膨胀相邻字符粘在一起分不开字距太小或字体笔画粘连对二值图做轻微腐蚀先缩小图像再做垂直投影截出来的字符区域参差不齐文字本身有修约、笔画长短不一属于正常现象可以按最大宽度统一裁剪或者用连通域再做一次校正运行时报Mat类型断言错误传入的不是CV_8UC1单通道图确认先用IMReadGrayScale读图或者用CvtColor转灰度5.2 让代码自动判断前背景方向之前提到的反转问题手动看虽然不算麻烦但如果在批处理流程里几百张图不可能每张都人工确认。我自己写过一个小技巧统计二值图中白色像素的占比如果超过一半说明背景是白色需要反转否则保持不动。func ensureForegroundWhite(bin gocv.Mat) { total : bin.Rows() * bin.Cols() whiteCount : 0 for y : 0; y bin.Rows(); y { row : bin.RowPtr(y) for x : 0; x bin.Cols(); x { if row[x] 0 { whiteCount } } } if whiteCount total/2 { gocv.BitwiseNot(bin, bin) } }这个规则适合大多数常规扫描件和文档截图前提是文字区域面积不能大于背景面积。如果整张图都是黑底白字的代码截图或者反色艺术海报这个比例判断就可能失效但那种情况通常看一眼投影图就能发现问题不大。5.3 大图性能优化思路投影本身复杂度是O(width x height)对大图来说还是有一定开销。如果图片是几千万像素级别的工程图有几个思路可以组合使用缩小图像后再做投影。投影关注的是分布特征对分辨率不敏感。把长边缩到2000像素以内速度和内存占用都会大幅下降。提前用Region限定ROI。如果已经知道文字区域的大致范围比如车牌在图片中间区域就没必要全图投影先Region切出目标区域再统计。做投影前先做一次粗略的下采样。和缩图思路类似但只影响投影统计不影响后续基于切分坐标在原图上做精细处理。我之前处理一批工程扫描件原图都是4000×3000以上直接投影虽然也能跑但批处理总时间比较感人。后来把长边统一缩到2000像素处理速度提升了近3倍切分精度没受多大影响。再分享一个我自己的排查习惯写投影代码的时候先别急着做后续切分拿到投影数组之后一定先把投影图画出来看一眼。曲线长什么样、谷底干不干净、前景方向对不对一眼就能判断。这个习惯帮我省下了大量排查时间比对着数字猜快太多了。投影这个方法虽然“老”但在很多版面分析和字符分割场景里依然是最划算的起点。很多时候你不需要复杂模型把基础算子用到极致效果就已经足够稳。等你把投影调稳了后面的切分基本就是水到渠成的事。

相关新闻

智能问数核心实践:多策略召回与精排的工程方案

智能问数核心实践:多策略召回与精排的工程方案

1. 智能问数为什么难:核心不是"写SQL",而是"找对表和找对列"1.1 从传统BI到自然语言问数的需求变化做自然语言问数这几年,我最大的体感是:大家一开始都以为难点在"让大模型写SQL",真正上…

2026/10/18 6:46:54 阅读更多 →
PHP代码审计实战:六类致命反模式与漏洞挖掘指南

PHP代码审计实战:六类致命反模式与漏洞挖掘指南

前阵子给一套老系统做例行排查,翻到一个导出模块的时候,我看到了那行再熟悉不过的代码:一段从GET参数拿来的字符串,被直接拼进了一条SQL查询,然后mysqli_query一把梭。看到它的瞬间,我的脑子里冒出了两句话…

2026/10/18 6:46:54 阅读更多 →
从零开始写第一篇博客:选题、结构、可读性与发布心态全攻略

从零开始写第一篇博客:选题、结构、可读性与发布心态全攻略

说起第一篇博客,我到现在还记得当时的窘迫。打开编辑器,盯着空白页发呆,光标一闪一闪的,像在嘲笑我。脑子里明明有七八个想写的话题,可真要落笔,又觉得哪个都不够分量,哪个都怕写砸了。那篇&quo…

2026/10/18 6:46:54 阅读更多 →

最新新闻

AI Agent Harness 多终端同步管控:把 Codex auth.json 改到 TaoToken 的实操大纲

AI Agent Harness 多终端同步管控:把 Codex auth.json 改到 TaoToken 的实操大纲

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

2026/10/18 22:45:50 阅读更多 →
C 语言与 Python 语言分别代表了系统级编程与高级通用编程两种截然不同的设计哲学

C 语言与 Python 语言分别代表了系统级编程与高级通用编程两种截然不同的设计哲学

C 语言与 Python 语言分别代表了系统级编程与高级通用编程两种截然不同的设计哲学。C 语言诞生于 1970 年代的贝尔实验室,以接近硬件、执行高效、可移植性强著称,长期是操作系统、嵌入式系统、驱动程序和高性能计算领域的首选语言。 Python 则是一种解释…

2026/10/18 22:45:50 阅读更多 →
PHP 仍然驱动着全球约 77% 的网站,在 CMS 和传统 Web 开发领域保有巨大存量

PHP 仍然驱动着全球约 77% 的网站,在 CMS 和传统 Web 开发领域保有巨大存量

在 2026 年的编程语言格局中,Python 与 PHP 代表了两种截然不同的技术路线。根据 TIOBE 2026 年 10 月排行榜,Python 以 19.23% 的占比位居第一,而 PHP 以 1.26% 排在第十二位。然而,PHP 仍然驱动着全球约 77% 的网站,…

2026/10/18 22:45:50 阅读更多 →
工业相机SDK适配实战:一套架构兼容Basler、海康、堡盟

工业相机SDK适配实战:一套架构兼容Basler、海康、堡盟

很多搞机器视觉的朋友都经历过这种场景:项目做到一半,甲方说“现场临时变更,相机换成海康的”,或者“第二套设备要用堡盟的,因为供货周期短”。乍一听只是换个硬件,实际上等于把图像采集这块代码推倒重来。…

2026/10/18 22:45:50 阅读更多 →
Spring Boot + MyBatis-Plus 实战:从 CRUD 到分页、乐观锁与代码生成器

Spring Boot + MyBatis-Plus 实战:从 CRUD 到分页、乐观锁与代码生成器

简介:一份面向Java后端开发者的Spring Boot与MyBatis-Plus整合实践资源。资源围绕企业级应用快速开发场景,展示如何利用Spring Boot的自动配置与起步依赖,以及MyBatis-Plus的CRUD接口、代码生成、分页与逻辑删除等特性,帮助读者摆…

2026/10/18 22:45:50 阅读更多 →
AI重塑编程行业:从LLM代码生成到可视化数据,附可复用代码案例与TaoToken统一API接入实践

AI重塑编程行业:从LLM代码生成到可视化数据,附可复用代码案例与TaoToken统一API接入实践

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

2026/10/18 22:44:48 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →