项目开源地址:
opencv-vision-lab:OpenCV Vision Lab —— 在线图像处理实验室 - AtomGit华为云码道:
AtomGit - 全球开发者的开源社区,开源代码托管平台
前言
前两篇里,我已经用华为云码道 Agent 把一个基础 OpenCV 项目逐步扩展成了完整的计算机视觉算法实验室。
目前项目已经支持:
- 灰度化
- 均值滤波
- 高斯滤波
- 中值滤波
- 二值化
- 腐蚀
- 膨胀
- 开运算
- 闭运算
- Sobel
- Canny
- 轮廓检测
- Harris
- SIFT
一共 14 种 OpenCV 算法。
但做到这里以后,我发现还有一个问题:
很多算法虽然能调参数,但每次只能看一组结果。
比如 Canny:
threshold1 = 50 threshold2 = 100和:
threshold1 = 150 threshold2 = 250到底差多少?
如果只能一次改一组参数,再重新执行、重新观察,其实并不直观。
所以这一篇我不准备继续加新算法,而是做另一件事:
让同一个算法使用多组参数同时运行,并把结果并排展示。
也就是把 OpenCV Vision Lab 从“算法调用工具”,继续升级成一个:
参数可视化实验平台。
一、这次不加算法,只改“实验方式”
这次我给码道 Agent 的需求核心很简单:
不要再增加新的 OpenCV 算法,而是增加“参数对比模式”。
目标是:
同一张图片,同一个算法,多组不同参数,同时运行,同时展示结果。
这一轮重点支持 5 个最适合做参数实验的算法:
- Gaussian Blur
- Canny
- Harris
- SIFT
- 轮廓检测
例如 Canny 可以一次设置三组参数:
50 / 100 100 / 200 150 / 250然后在同一个页面中并排查看三组边缘检测结果。
这次和前两篇最大的区别是:
第一篇解决的是:
能不能从 0 到 1 搭一个项目。
第二篇解决的是:
能不能在旧项目上继续增量开发。
第三篇关注的是:
能不能把已有算法进一步做成真正适合实验和学习的工具。
二、Agent 先做的还是“复用”,而不是推翻重写
这一轮,码道先分析了现有项目结构。
当前项目里已经有:
app.py processing.py main.js index.html style.css smoke_test.py README.md而且processing.py里已经有统一的:
process_image(image, alg_id, params)因此它并没有重新写一套算法逻辑,而是直接复用已有接口。
它给出的方案大致是:
后端
新增:
POST /api/compare请求格式类似:
{ "alg": "canny", "groups": [ {"threshold1": 50, "threshold2": 100}, {"threshold1": 100, "threshold2": 200}, {"threshold1": 150, "threshold2": 250} ] }然后对每一组参数重复调用原来的process_image。
返回的数据则包含:
- 处理结果图片
- 参数
- 统计信息
- 执行状态
前端
新增:
单次处理 / 参数对比
两种模式切换。
参数对比模式下:
- 同一个算法可以建立多组参数
- 每组参数独立控制
- 同时生成多张结果卡片
- 每张结果显示对应参数和统计结果
这一点我觉得很重要。
因为这次不是:
“给我重新做一个对比页面。”
而是:
“尽量复用现有项目结构,把一个新的实验模式接进去。”
三、项目正式加入“参数对比模式”
升级后,OpenCV Vision Lab 不再只有原来的单次处理。
现在可以直接在页面中切换:
单次处理模式和参数对比模式
单次模式仍然保持原来的逻辑:
上传图片 ↓ 选择算法 ↓ 调整参数 ↓ 查看处理结果而参数对比模式变成:
上传图片 ↓ 选择算法 ↓ 设置第 1 组参数 ↓ 设置第 2 组参数 ↓ 设置第 3 组参数 ↓ 同时运行 ↓ 并排查看结果而且原来的 14 种算法没有被破坏。
对比模式只开放给更适合实验的 5 种算法:
- Gaussian Blur
- Canny
- Harris
- SIFT
- 轮廓检测
其余算法在参数对比模式下会被禁用或提示暂不支持。
这样比把所有功能强行塞进去更合理。
四、实际案例一:Canny 三组参数同时比较
参数对比模式最适合演示的,我觉得还是 Canny。
Canny 本身就是一个对参数比较敏感的算法。
这次我使用同一张测试图片,同时设置三组参数。
例如:
第 1 组: threshold1 = 50 threshold2 = 100 第 2 组: threshold1 = 100 threshold2 = 200 第 3 组: threshold1 = 150 threshold2 = 250运行以后,三组结果直接并排展示。
这样一看,差别就非常直观。
参数比较低时,图像中会检测出更多边缘。
比如:
- 草地纹理
- 毛发
- 树叶
- 背景细节
都会被检测出来。
但随着阈值逐渐提高,一些比较弱的边缘会被过滤掉。
最终保留下来的往往是:
- 主体轮廓
- 强结构边缘
- 比较明显的局部变化
以前如果只是写代码:
cv2.Canny(img, 50, 100)再修改参数:
cv2.Canny(img, 150, 250)实际上很难快速形成整体印象。
而现在三组结果就在同一个页面里。
参数到底怎么影响结果,一眼就能看到。
五、参数对比不只是“多放三张图片”
这一轮我还要求每一组结果都带上对应信息。
比如:
- 当前参数
- 结果图
- 统计数据
- 执行结果
以 Canny 为例,可以进一步统计:
边缘像素数量
这样就不仅仅是:
“看起来好像边缘少了一点。”
而是可以进一步比较:
参数变化以后,检测到的边缘数量到底减少了多少。
这就从纯视觉观察进一步变成了:
视觉结果 + 数值结果。
对做算法实验来说更有意义。
六、实际案例二:SIFT 多组参数对比
第二个我测试的是 SIFT。
SIFT 的结果和 Canny 又完全不一样。
Canny 更适合看:
边缘变化。
而 SIFT 更适合观察:
关键点数量和分布变化。
这次我设置多组不同参数,对同一张图片进行 SIFT 特征点检测。
从结果中可以看到,参数变化以后:
- 关键点总数量会变化
- 特征点密集程度会变化
- 一些弱特征是否被保留也会变化
例如在这张图片里:
- 草地
- 树叶
- 毛发
- 狗的面部
- 建筑物
这些纹理丰富的位置,本身就比较容易产生大量 SIFT 特征点。
当参数更宽松时,通常能够保留更多关键点。
参数收紧以后,一些不够稳定的局部特征则会被过滤掉。
这类实验如果靠反复改代码其实挺麻烦。
但放进参数对比模式以后,就更像一个真正的:
SIFT 参数实验台。
七、另外几个算法为什么也适合做参数对比?
除了 Canny 和 SIFT,这次还支持:
Gaussian Blur
可以直接对比不同 Kernel Size:
3 7 15卷积核越大,通常平滑效果越明显。
同时细节也会逐渐损失。
Harris
可以比较:
blockSize ksize k quality不同参数组合会影响角点数量和响应程度。
轮廓检测
可以设置不同的:
min_area例如:
0 500 2000就能观察最小轮廓面积阈值变化以后,最终保留的轮廓数量有多大变化。
这些算法其实都有一个共同特点:
参数本身不难理解,难的是建立“参数变化”和“输出变化”之间的直觉。
所以我觉得这种对比模式比单纯继续增加算法更有价值。
八、这一轮开发过程中也不是完全顺利
这次前端改动比前两篇明显更大。
因为原来的页面只需要处理一套参数和一个结果。
而参数对比模式需要处理:
- 多组参数控件
- 多组 ID
- 多张结果图
- 多组统计信息
- 单次 / 对比两种模式状态
- 多组参数动态增加和删除
所以前端main.js改动比较大。
开发过程中,一度在重写main.js时出现了部分异常字符和语法问题。
Agent 随后重新检查文件内容,并继续修复。
最后再次验证时:
main.js 语法检查通过,没有发现字符损坏。
这一点其实也比较真实。
Agent 开发并不是意味着“代码永远一次生成成功”。
更关键的是:
出错以后,它能不能重新检查当前工程状态并继续修复。
九、最终测试:从 62 项增加到 100 项
第二篇结束时,整个项目的测试数量是:
62 / 62这一轮加入参数对比模式以后,测试数量进一步增加。
最终后端:
100 / 100 全部通过其中参数对比相关测试:
38 项覆盖内容包括:
- 5 种算法默认参数对比
- stats 统计结果
- 参数合法性校验
- 部分参数组失败处理
- 单组处理
- 多组处理
- 原有算法回归
前端还进行了 Playwright 测试。
最终:
6 / 6 全部通过 0 JavaScript 错误测试流程覆盖:
上传图片 ↓ 切换参数对比模式 ↓ 生成 3 张结果卡片 ↓ 新增参数组 ↓ 生成 4 张结果卡片 ↓ 切回单次模式最终提交:
73006eb 新增参数对比模式:同算法多组参数并排对比结果并且已经推送到远程main分支。
十、做到第三篇以后,这个项目已经变成什么了?
最开始,我只是想做一个:
OpenCV 在线图像处理实验室。
第一篇完成了:
基础图像处理。
第二篇加入:
边缘、轮廓、角点和局部特征。
第三篇进一步加入:
参数对比实验。
现在这个项目已经不只是简单地:
上传图片,然后调用一个 OpenCV API。
而是逐渐形成了一个比较完整的计算机视觉学习工具。
目前可以做到:
| 功能 | 状态 |
|---|---|
| 14 种 OpenCV 算法 | ✅ |
| 单次处理模式 | ✅ |
| 参数对比模式 | ✅ |
| Gaussian 多参数对比 | ✅ |
| Canny 多参数对比 | ✅ |
| Harris 多参数对比 | ✅ |
| SIFT 多参数对比 | ✅ |
| 轮廓参数对比 | ✅ |
| 多组结果并排显示 | ✅ |
| 参数统计 | ✅ |
| 原有功能回归测试 | ✅ |
| 后端测试 100/100 | ✅ |
| 前端测试 6/6 | ✅ |
| 0 JS 错误 | ✅ |
| README 更新 | ✅ |
| Git 推送 | ✅ |
项目地址:
opencv-vision-lab:OpenCV Vision Lab —— 在线图像处理实验室 - AtomGit
十一、这一轮我觉得最有价值的地方
如果只是从“代码量”来看,这一篇其实未必比第二篇新增 5 个算法更复杂。
但从学习体验来说,我觉得这一轮反而更有意义。
因为真正学习计算机视觉时,我们最终还是会遇到:
为什么我的效果和别人不一样?
很多时候,问题并不在算法名字。
而在:
参数。
所以相比继续往项目里塞更多 OpenCV API,我更希望让这个工具开始帮助理解:
参数为什么会改变结果。
这也是这次“参数对比模式”的核心价值。
十二、OpenCV 系列先告一段落
做到这里以后,我暂时不准备继续往 OpenCV Vision Lab 里增加更多算法。
因为目前已经完成了:
基础图像处理 → 高级视觉算法 → 参数实验
这一整条路线。
继续一直增加传统视觉算法,项目反而容易变成单纯的功能堆叠。
所以下一个项目,我准备从传统计算机视觉进一步进入:
深度学习。
下一篇准备尝试:
只给码道一句需求,它能不能从零开发一个 CNN 手写数字识别平台?
计划加入:
- MNIST
- CNN
- PyTorch
- 手写数字输入
- 模型预测
- 类别概率
- 特征图可视化
也就是从:
OpenCV
正式进入:
神经网络 + PyTorch。
看看这次 Agent 面对一个真正包含深度学习模型的项目,还能不能像前面一样完成从需求到完整工程的开发。