news 2026/4/18 7:31:30

用 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/3/25 2:27:55

DDColor商业接单指南:如何用10块钱启动AI修复副业

DDColor商业接单指南:如何用10块钱启动AI修复副业 你是不是也经常刷到那些“老照片一键上色”的短视频?泛黄的黑白影像在几秒钟内变得色彩鲜活,仿佛时光倒流。其实,这背后的技术并不神秘,也不需要花大几千去报班学习。…

作者头像 李华
网站建设 2026/4/18 5:22:41

Vectras VM:5分钟在手机上部署跨平台系统的完整指南

Vectras VM:5分钟在手机上部署跨平台系统的完整指南 【免费下载链接】Vectras-VM-Android Its a Virtual Machine App for Android Which is Based on QEMU 项目地址: https://gitcode.com/gh_mirrors/ve/Vectras-VM-Android 移动虚拟化技术正彻底改变我们使…

作者头像 李华
网站建设 2026/4/6 14:44:10

DANN领域自适应终极完整指南:5分钟快速上手PyTorch实现

DANN领域自适应终极完整指南:5分钟快速上手PyTorch实现 【免费下载链接】DANN pytorch implementation of Domain-Adversarial Training of Neural Networks 项目地址: https://gitcode.com/gh_mirrors/da/DANN 领域自适应是迁移学习中的重要分支&#xff0c…

作者头像 李华
网站建设 2026/4/17 17:14:47

Fillinger脚本:Illustrator智能填充的终极完整指南

Fillinger脚本:Illustrator智能填充的终极完整指南 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 还在为Illustrator中复杂的图形填充而烦恼吗?想要快速在任…

作者头像 李华
网站建设 2026/4/16 15:55:44

GLM-TTS开箱即用镜像:1小时1元,比装虚拟机更简单

GLM-TTS开箱即用镜像:1小时1元,比装虚拟机更简单 你是不是也遇到过这样的情况?作为IT运维人员,测试一个新工具时,光是搭建环境就花了大半天——安装依赖、配置Python版本、调试CUDA驱动、解决包冲突……结果本地虚拟机…

作者头像 李华
网站建设 2026/4/6 8:58:25

中文文本分类案例:bert-base-chinese应用

中文文本分类案例:bert-base-chinese应用 1. 技术背景与问题提出 在自然语言处理(NLP)领域,中文文本分类是一项基础且关键的任务,广泛应用于舆情分析、智能客服、新闻聚类和内容审核等场景。传统方法依赖于词袋模型&…

作者头像 李华