news 2026/4/16 15:51:53

用 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/15 23:14:36

RAG技术全解析:从基础概念到三大形态的实战指南

RAG(检索增强生成)是给AI模型装上"专属知识库精准搜索引擎"的技术,避免AI瞎编并提高回答准确性。文章详解了三种核心形态:传统RAG实现"检索-总结"流程,Graph RAG通过知识图谱理解信息逻辑&#xf…

作者头像 李华
网站建设 2026/3/15 6:22:33

Fillinger:Illustrator智能填充的革命性工具

Fillinger:Illustrator智能填充的革命性工具 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 还在为复杂的图形填充而苦恼吗?Fillinger脚本彻底改变了Adobe I…

作者头像 李华
网站建设 2026/4/16 14:32:16

零基础入门大模型微调:用Qwen2.5-7B打造专属AI助手

零基础入门大模型微调:用Qwen2.5-7B打造专属AI助手 1. 引言 1.1 背景与学习目标 随着大语言模型(LLM)技术的快速发展,个性化定制AI助手已成为提升用户体验和品牌识别度的重要手段。Qwen2.5-7B 是阿里云推出的高性能开源大模型&…

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

避坑指南:用Qwen All-in-One轻松解决多模型部署内存冲突

避坑指南:用Qwen All-in-One轻松解决多模型部署内存冲突 1. 背景与挑战:多模型部署的“隐性成本” 在实际AI工程落地过程中,开发者常常面临一个看似简单却极具挑战的问题:如何在资源受限的环境中高效部署多个AI功能?…

作者头像 李华
网站建设 2026/4/16 12:24:11

chainlit+HY-MT1.5-1.8B插件开发

chainlitHY-MT1.5-1.8B插件开发 1. 技术背景与应用场景 随着多语言交流需求的快速增长,高质量、低延迟的翻译服务成为智能应用的核心能力之一。特别是在边缘计算和实时交互场景中,对轻量级高性能翻译模型的需求尤为迫切。混元翻译模型(Huny…

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

移动虚拟化终极指南:安卓虚拟机技术深度解析与实践技巧

移动虚拟化终极指南:安卓虚拟机技术深度解析与实践技巧 【免费下载链接】Vectras-VM-Android Its a Virtual Machine App for Android Which is Based on QEMU 项目地址: https://gitcode.com/gh_mirrors/ve/Vectras-VM-Android 你是否曾经想过,一…

作者头像 李华