news 2026/4/23 13:51:29

用 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/4/17 20:01:16

FinBERT:金融情感分析的终极解决方案

FinBERT:金融情感分析的终极解决方案 【免费下载链接】finbert 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/finbert 想要准确分析财经新闻、研报和社交媒体中的市场情绪吗?FinBERT为您提供简单快速的金融情感分析工具!…

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

Emotion2Vec+ Large镜像1.9GB模型加载优化技巧

Emotion2Vec Large镜像1.9GB模型加载优化技巧 1. 引言 1.1 技术背景 在语音情感识别领域,预训练大模型的应用正变得越来越广泛。Emotion2Vec Large作为一款基于大规模语音数据训练的深度学习模型,能够有效捕捉语音中的情感特征,在多个应用…

作者头像 李华
网站建设 2026/4/19 1:05:22

中三条以上 建议直接 “解绑” 啦

📌1. 吵架像开辩论会 赢你没商量 哄你不存在📌2. 礼物全靠“画大饼” 纪念日能忘到九霄云外📌3. 你说话他走神 反驳你倒比谁都积极📌4. 对陌生人彬彬有礼 对你只剩“随便”“都行”📌5. 微信聊天靠你主动 他回复像挤牙…

作者头像 李华
网站建设 2026/4/23 13:19:55

动态注意力剪枝是什么?Z-Image-Turbo效率提升关键

动态注意力剪枝是什么?Z-Image-Turbo效率提升关键 1. 引言:AI图像生成的效率瓶颈与突破方向 在当前AI图像生成技术快速发展的背景下,模型推理速度已成为决定其能否广泛落地的核心因素之一。尽管高保真度是生成质量的基础,但若无…

作者头像 李华
网站建设 2026/4/23 11:38:27

轻松掌握Windows文件元数据:FileMeta实用技巧大全

轻松掌握Windows文件元数据:FileMeta实用技巧大全 【免费下载链接】FileMeta Enable Explorer in Vista, Windows 7 and later to see, edit and search on tags and other metadata for any file type 项目地址: https://gitcode.com/gh_mirrors/fi/FileMeta …

作者头像 李华
网站建设 2026/4/23 11:34:25

ESP32蓝牙音频实战指南:从零构建无线音响系统

ESP32蓝牙音频实战指南:从零构建无线音响系统 【免费下载链接】ESP32-A2DP A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF 项目地址: https://gitcode.com/gh_mirrors/…

作者头像 李华