news 2026/2/6 4:49:20

用 OpenCV 的 DNN 模块玩转图像分类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 OpenCV 的 DNN 模块玩转图像分类

你是不是也想快速实现图像分类,却不想费劲搭建复杂的深度学习框架?今天就给大家分享一个超实用的技巧 —— 用 OpenCV 的 DNN 模块直接调用训练好的模型,不管是单张图片还是批量图片,都能轻松完成分类任务,小白也能快速上手!

一、核心原理:DNN 模块到底能干啥?

简单来说,OpenCV 的 DNN 模块就像一个 “模型中转站”。它支持加载 Caffe、TensorFlow、PyTorch 等主流框架训练好的模型,不用我们再去手写网络结构、调参训练。

我们只需要做两件事:

  1. 准备好模型配置文件权重文件
  2. 把输入图像处理成模型能 “看懂” 的样子
  3. 丢给模型就能直接出分类结果

这次我们用的是经典的 GoogLeNet 模型,它是基于 ImageNet 数据集训练的,可以识别 1000 种常见物体。

二、实战步骤:从单张图片到批量预测

话不多说,直接上代码和讲解,每一步都给你掰扯明白。

1. 前期准备

先把需要的工具包导入,再处理好标签文件。这个标签文件对应了 ImageNet 的 1000 个分类,能把模型输出的数字索引转换成我们能看懂的物体名称。

# 导入工具包 import utils_paths import numpy as np import cv2 # 标签文件处理:把每行的标签提取出来,方便后续对应结果 rows = open("synset_words.txt").read().strip().split("\n") classes = [r[r.find(" ") + 1:].split(",")[0] for r in rows]

2. 加载预训练模型

这里我们加载基于 Caffe 框架训练的 GoogLeNet 模型,需要两个文件:.prototxt是模型的配置文件,定义了网络结构;.caffemodel是训练好的权重文件,存着网络里的参数。

# Caffe所需配置文件:加载模型结构和权重 net = cv2.dnn.readNetFromCaffe("bvlc_googlenet.prototxt", "bvlc_googlenet.caffemodel")

3. 单张图片预测:一步一步来

这是最基础的操作,核心就是把图片转换成模型需要的blob格式,再传入模型得到结果。

# 获取图像路径 imagePaths = sorted(list(utils_paths.list_images("images/"))) # 读取并预处理单张图片 image = cv2.imread(imagePaths[0]) # 第一步:调整尺寸。模型训练时用的是224×224,测试也得统一尺寸 resized = cv2.resize(image, (224, 224)) # 第二步:转换成blob。1是缩放因子,(104,117,123)是ImageNet的三通道均值 blob = cv2.dnn.blobFromImage(resized, 1, (224, 224), (104, 117, 123)) print("First Blob: {}".format(blob.shape)) # 输出blob形状,方便检查 # 传入模型做预测 net.setInput(blob) preds = net.forward() # 前向传播,得到1000个分类的概率值 # 找出概率最大的分类 idx = np.argsort(preds[0])[::-1][0] # 排序后取第一个(概率最大) # 生成结果文本:分类名称 + 概率百分比 text = "Label: {}, {:.2f}%".format(classes[idx],preds[0][idx] * 100) # 把结果画到图片上 cv2.putText(image, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX,0.7, (0, 0, 255), 2) # 显示结果 cv2.imshow("Image", image) cv2.waitKey(0)

这里要注意两个关键点:

  • 图片尺寸必须和训练时一致,不然模型会 “看不懂”
  • 减均值是为了消除光照的影响,让分类更准确,这个均值是 ImageNet 数据集统计出来的,直接用就行

4. 批量图片预测:效率翻倍

如果有一堆图片要分类,一个个预测太麻烦,用blobFromImages函数(注意比单张多了个s)就能批量处理,速度更快。

# Batch数据制作:批量处理剩下的图片 images = [] for p in imagePaths[1:]: image = cv2.imread(p) image = cv2.resize(image, (224, 224)) images.append(image) # 转换成批量blob,参数和单张一样 blob = cv2.dnn.blobFromImages(images, 1, (224, 224), (104, 117, 123)) print("Second Blob: {}".format(blob.shape)) # 批量预测 net.setInput(blob) preds = net.forward() # 遍历每个预测结果,画到图片上并显示 for (i, p) in enumerate(imagePaths[1:]): image = cv2.imread(p) idx = np.argsort(preds[i])[::-1][0] text = "Label: {}, {:.2f}%".format(classes[idx],preds[i][idx] * 100) cv2.putText(image, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX,0.7, (0, 0, 255), 2) cv2.imshow("Image", image) cv2.waitKey(0)

三、小技巧和注意事项

  1. 预处理要一致:训练时对图片做了啥操作(缩放、减均值、裁剪等),测试时必须一模一样,不然结果会跑偏。
  2. 框架选择灵活:除了 Caffe,OpenCV 还支持readNetFromTensorflowreadNetFromTorch等,换个函数就能加载其他框架的模型。
  3. 批量预测更高效:处理大量图片时,批量预测比单张循环快很多,推荐优先使用。

完整代码

# 导入工具包 import utils_paths import numpy as np import cv2 # 标签文件处理 rows = open("synset_words.txt").read().strip().split("\n") classes = [r[r.find(" ") + 1:].split(",")[0] for r in rows] # Caffe所需配置文件 net = cv2.dnn.readNetFromCaffe("bvlc_googlenet.prototxt", "bvlc_googlenet.caffemodel") # 图像路径 imagePaths = sorted(list(utils_paths.list_images("images/"))) # 图像数据预处理 image = cv2.imread(imagePaths[0]) resized = cv2.resize(image, (224, 224)) # image scalefactor size mean swapRB blob = cv2.dnn.blobFromImage(resized, 1, (224, 224), (104, 117, 123)) print("First Blob: {}".format(blob.shape)) # 得到预测结果 net.setInput(blob) preds = net.forward() # 排序,取分类可能性最大的 idx = np.argsort(preds[0])[::-1][0] text = "Label: {}, {:.2f}%".format(classes[idx], preds[0][idx] * 100) cv2.putText(image, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) # 显示 cv2.imshow("Image", image) cv2.waitKey(0) # Batch数据制作 images = [] # 方法一样,数据是一个batch for p in imagePaths[1:]: image = cv2.imread(p) image = cv2.resize(image, (224, 224)) images.append(image) # blobFromImages函数,注意有s blob = cv2.dnn.blobFromImages(images, 1, (224, 224), (104, 117, 123)) print("Second Blob: {}".format(blob.shape)) # 获取预测结果 net.setInput(blob) preds = net.forward() for (i, p) in enumerate(imagePaths[1:]): image = cv2.imread(p) idx = np.argsort(preds[i])[::-1][0] text = "Label: {}, {:.2f}%".format(classes[idx], preds[i][idx] * 100) cv2.putText(image, text, (5, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.imshow("Image", image) cv2.waitKey(0)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/3 17:24:17

没GPU怎么跑BGE-M3?云端镜像1小时1块,5分钟部署

没GPU怎么跑BGE-M3?云端镜像1小时1块,5分钟部署 你是不是也遇到过这种情况:想试试最近火出圈的BGE-M3文本嵌入模型,结果一查发现——“推荐显存至少16GB”?家里的老笔记本连8GB都不到,直接被拒之门外。别急…

作者头像 李华
网站建设 2026/2/6 4:40:23

5个颠覆性技巧:用MacGesture重新定义macOS鼠标操作效率

5个颠覆性技巧:用MacGesture重新定义macOS鼠标操作效率 【免费下载链接】MacGesture Global mouse gestures for macOS 项目地址: https://gitcode.com/gh_mirrors/ma/MacGesture 还在为频繁切换应用标签页而烦恼吗?是否经常觉得macOS的操作效率还…

作者头像 李华
网站建设 2026/2/5 17:13:58

Windows运行安卓APP终极方案:告别模拟器的轻量级安装器

Windows运行安卓APP终极方案:告别模拟器的轻量级安装器 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经遇到过这样的情况:手机上有一…

作者头像 李华
网站建设 2026/2/3 13:01:11

5分钟实现Windows运行安卓APP:告别模拟器的终极方案

5分钟实现Windows运行安卓APP:告别模拟器的终极方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 还在为Windows无法直接安装手机应用而烦恼吗&#xff1…

作者头像 李华
网站建设 2026/2/3 20:25:37

免费Windows系统优化神器Dism++完整使用教程

免费Windows系统优化神器Dism完整使用教程 【免费下载链接】Dism-Multi-language Dism Multi-language Support & BUG Report 项目地址: https://gitcode.com/gh_mirrors/di/Dism-Multi-language 还在为电脑运行卡顿、磁盘空间不足而烦恼吗?今天我要向您…

作者头像 李华