【机器学习】基于OpenCV和TensorFlow的MobileNetV2模型的物种识别与个体相似度分析
在计算机视觉领域,物种识别和图像相似度比较是两个重要的研究方向。本文通过结合深度学习和图像处理技术,基于OpenCV和TensorFlow的MobileNetV2的预训练模型模,实现物种识别和个体相似度分析。本文详细介绍该实验过程并提供相关代码。
一、名词介绍
1. OpenCV
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。OpenCV由英特尔公司在1999年发起,并在2000年以开源的方式发布。该库被设计为高效的计算机视觉应用程序开发工具,支持多种编程语言(如C++、Python、Java)和平台(如Windows、Linux、Mac OS、Android、iOS)。
使用OpenCV具有以下优势:
- 开源和免费:OpenCV是完全开源和免费的,这使得开发者可以自由地使用、修改和分发。
- 跨平台:OpenCV支持多个操作系统和平台,包括Windows、Linux、Mac OS、Android和iOS,使其在多种设备上具有广泛的适用性。
- 丰富的功能:OpenCV提供了广泛的功能,包括图像处理、视频分析、物体检测、机器学习、计算机视觉算法等,满足了大多数计算机视觉应用的需求。
- 大规模社区支持:OpenCV拥有一个活跃的社区,提供丰富的文档、教程和示例代码,开发者可以方便地获取支持和资源。
- 性能优化:OpenCV对性能进行了高度优化,支持硬件加速(如GPU),能够在实时应用中高效运行。
2. TensorFlow
TensorFlow是一个由Google Brain团队开发的开源深度学习框架。它提供了全面、灵活的工具,支持构建和训练各种深度学习模型。TensorFlow支持多种平台,包括Windows、Linux、Mac OS和移动设备,并且可以利用CPU和GPU进行高效计算。
使用TensorFlow具有以下优势:
- 灵活性和可扩展性:TensorFlow支持构建和训练各种类型的深度学习模型,从简单的线性模型到复杂的神经网络。
- 跨平台支持:TensorFlow支持在多个平台上运行,包括桌面系统、服务器和移动设备,并且可以利用GPU和TPU进行加速。
- 广泛的社区和生态系统:TensorFlow拥有一个庞大的社区,提供丰富的资源和支持。其生态系统包括TensorBoard(用于可视化)、TensorFlow Lite(用于移动设备)和TensorFlow Serving(用于部署)。
- 预训练模型和模型库:TensorFlow提供了大量的预训练模型和模型库,可以方便地进行迁移学习和模型优化。
3. OpenCV与同类视库对比
下表对比了OpenCV与其他几种常见的计算机视觉库(如Dlib、SimpleCV和Scikit-Image)的特点:
| 特性 | OpenCV | Dlib | SimpleCV | Scikit-Image |
|---|---|---|---|---|
| 开源和免费 | 是 | 是 | 是 | 是 |
| 跨平台支持 | Windows, Linux, Mac OS, Android, iOS | Windows, Linux, Mac OS | Windows, Linux, Mac OS | Windows, Linux, Mac OS |
| 编程语言支持 | C++, Python, Java, MATLAB | C++, Python | Python | Python |
| 图像处理 | 广泛支持 | 支持 | 基础支持 | 广泛支持 |
| 视频处理 | 广泛支持 | 不支持 | 基础支持 | 不支持 |
| 机器学习算法 | 支持(集成了OpenCV ML模块) | 支持(内置多种机器学习算法) | 基础支持 | 支持(依赖Scikit-Learn) |
| 面部检测 | 支持(Haar级联分类器、DNN) | 支持(HOG+SVM、CNN) | 支持 | 基础支持(依赖外部库) |
| 性能优化 | 高度优化,支持硬件加速 | 一定程度优化,部分支持硬件加速 | 未优化 | 一定程度优化 |
| 社区支持 | 活跃社区,大量资源 | 中等规模社区 | 小规模社区 | 中等规模社区 |
二、环境准备
1. 搭建python环境
为了避免和历史包版本的冲突,这里我先新建了一个新的conda环境,起名opencv。
python环境为3.8.19。

升级pip和setuptools,规避后面可能发生的包版本冲突等安装问题。

2. 安装必要的库
下面,我安装了程序依赖的必要库。因为我是边摸索边安装,所以没有一次性全部安装这些库,你可以全部浏览完本节内容后一口气安装。
用到的库及介绍:
| 库名称 | 介绍 |
|---|---|
| Flask | 一个轻量级的Web框架,用于构建Web应用程序和API。 |
| Flask-CORS | 一个Flask扩展,用于处理跨域资源共享(CORS)问题,使得前端可以访问后端API。 |
| NumPy | 一个用于科学计算的库,提供支持大型多维数组和矩阵的操作,以及大量的数学函数库。 |
| OpenCV | 一个开源计算机视觉库,提供丰富的图像和视频处理功能。 |
| TensorFlow | 一个开源的机器学习框架,用于构建和训练各种机器学习模型。 |
| Keras | 高级神经网络API,运行在TensorFlow之上,用于快速构建和训练深度学习模型。 |
| Scikit-learn | 一个用于机器学习的Python库,提供简单高效的数据挖掘和数据分析工具,包括各种分类、回归和聚类算法。 |
下面是逐步安装的步骤:
① 安装flask、numpy、opencv-python库
pip install flask numpy opencv-python

② 安装flask-cors库
安装这个库主要原因是解决请求flask时的跨域问题。
pip install flask-cors

③ 安装tensorflow、keras库
tensorflow 是常用的深度学习框架。Keras 是一个高级神经网络 API,它能够以 TensorFlow, CNTK 或者 Theano 作为后端运行。
pip install tensorflow keras

④ 安装scikit-learn库
scikit-learn是一个用于机器学习的Python库,提供简单高效的数据挖掘和数据分析工具,包括各种分类、回归和聚类算法。
pip install scikit-learn

⑤ 安装cosine_similarity库
该库用于个体相似度比较。
pip install cosine_similarity

三、搭建Flask服务器
1. 编写图像识别python代码
创建一个名为app.py的文件,编写如下代码:
from flask import Flask, request, jsonify
from flask_cors import CORS
import numpy as np
import cv2
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2, preprocess_input, decode_predictions
from tensorflow.keras.preprocessing import image
from sklearn.metrics.pairwise import cosine_similarityapp = Flask(__name__)
CORS(app)# 加载预训练的MobileNetV2模型
model = MobileNetV2(weights='imagenet', include_top=True)def classify_image(img):img = cv2.resize(img, (224, 224)) # MobileNetV2的输入尺寸为224x224x = image.img_to_array(img)x = np.expand_dims(x, axis=0)x = preprocess_input(x)preds = model.predict(x)return decode_predictions(preds, top=1)[0][0][1], model.predict(x) # 返回类别名称和特征向量def calculate_similarity(feature1, feature2):return cosine_similarity(feature1, feature2)[0][0]@app.route('/compare', methods=['POST'])
def compare_images():file1 = request.files['image1']file2 = request.files['image2']npimg1 = np.frombuffer(file1.read(), np.uint8)npimg2 = np.frombuffer(file2.read(), np.uint8)img1 = cv2.imdecode(npimg1, cv2.IMREAD_COLOR)img2 = cv2.imdecode(npimg2, cv2.IMREAD_COLOR)# 分类和特征提取class1, feature1 = classify_image(img1)class2, feature2 = classify_image(img2)if class1 != class2:similarity = 0.0risk_level = "低"intervention = "否"else:similarity = calculate_similarity(feature1, feature2)risk_level = "高" if similarity > 0.8 else "中" if similarity > 0.5 else "低"intervention = "是" if similarity > 0.8 else "否"return jsonify({'similarity': f'{similarity * 100:.2f}%','risk_level': risk_level,'intervention': intervention,'class1': class1,'class2': class2})if __name__ == '__main__':app.run(debug=True)
2. 运行Flask服务器
再Anaconda中启动opencv环境的终端,运行以下命令启动Flask服务器:
python app.py

服务器启动后,将会监听在本地的5000端口。
四、浏览器客户端调用
1. 页面前端代码实现
创建一个HTML文件(test.html),实现图片上传和结果展示功能,全部代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>图片对比</title><style>body {font-family: Arial, sans-serif;display: flex;flex-direction: column;align-items: center;margin: 0;padding: 20px;}.container {display: flex;justify-content: space-between;width: 80%;margin-bottom: 20px;}.image-box {width: 45%;border: 2px dashed #ccc;padding: 10px;text-align: center;position: relative;}.image-box img {max-width: 100%;max-height: 200px;display: none;}.image-box input {display: none;}.upload-btn {cursor: pointer;color: #007BFF;text-decoration: underline;}.loading-bar {width: 80%;height: 20px;background-color: #f3f3f3;border: 1px solid #ccc;margin-top: 10px;display: none;position: relative;}.loading-bar div {width: 0;height: 100%;background-color: #4caf50;position: absolute;animation: loading 5s linear forwards;}@keyframes loading {to {width: 100%;}}.result {display: none;margin-top: 20px;}</style>
</head>
<body><h1>图片对比</h1><div class="container"><div class="image-box" id="box1"><label for="upload1" class="upload-btn">上传图片</label><input type="file" id="upload1" accept="image/*"><img id="image1" alt="左边文本抓取图片"></div><div class="image-box" id="box2"><label for="upload2" class="upload-btn">上传图片</label><input type="file" id="upload2" accept="image/*"><img id="image2" alt="右边文本数据库图片"></div></div><button id="compare-btn">人工智能对比</button><div class="loading-bar" id="loading-bar"><div></div></div><div class="result" id="result"><p>相似百分比: <span id="similarity">0%</span></p><p>相似度: <span id="risk-level">低</span></p><p>相同个体推测: <span id="intervention">否</span></p><p>图1种类: <span id="class1">-</span></p><p>图2种类: <span id="class2">-</span></p></div><script>document.getElementById('upload1').addEventListener('change', function(event) {loadImage(event.target.files[0], 'image1', 'box1');});document.getElementById('upload2').addEventListener('change', function(event) {loadImage(event.target.files[0], 'image2', 'box2');});function loadImage(file, imgId, boxId) {const reader = new FileReader();reader.onload = function(e) {const img = document.getElementById(imgId);img.src = e.target.result;img.style.display = 'block';document.querySelector(`#${boxId} .upload-btn`).style.display = 'none';}reader.readAsDataURL(file);}document.getElementById('compare-btn').addEventListener('click', function() {const loadingBar = document.getElementById('loading-bar');const result = document.getElementById('result');const image1 = document.getElementById('upload1').files[0];const image2 = document.getElementById('upload2').files[0];if (!image1 || !image2) {alert('请上传两张图片进行对比');return;}const formData = new FormData();formData.append('image1', image1);formData.append('image2', image2);loadingBar.style.display = 'block';result.style.display = 'none';fetch('http://localhost:5000/compare', {method: 'POST',body: formData}).then(response => response.json()).then(data => {loadingBar.style.display = 'none';result.style.display = 'block';document.getElementById('similarity').innerText = data.similarity;document.getElementById('risk-level').innerText = data.risk_level;document.getElementById('intervention').innerText = data.intervention;document.getElementById('class1').innerText = data.class1;document.getElementById('class2').innerText = data.class2;}).catch(error => {loadingBar.style.display = 'none';alert('对比过程中发生错误,请重试');console.error('Error:', error);});});</script>
</body>
</html>
2. 运行网页
双击运行,刚刚创建的test.html文件,效果如图:

上传左右图片,点击对比:

可以看到两只品种明显不同的狗相似度为0。
再比较两只相同品种的狗的相似度:

可以看到系统识别出了两只狗的种类相同,相似比也高达75.2%,但因为没有达到我们设置的80%的阈值,所以判断非同一个体。当然,这里的80%非常牵强,实际操作中难免误差较大。由于本文算法使用的是MobileNetV2预训练模型,并没有根据实际应用场景大量训练和调参,所以如果投入应用,仍需重新训练并根据实际效果定义阈值。
同一物种的识别结果:

五、实验总结
本文介绍了基于OpenCV和深度学习的物种识别和个体相似度比较方法。通过使用预训练的MobileNetV2模型进行特征提取和分类,并结合余弦相似度计算,实现了物种识别和相似度比较。此方法在计算机视觉领域具有广泛的应用前景,可以用于各种图像识别和比较任务。
通过本文的示例代码,你可以快速搭建一个图像识别和比较系统,并根据需要进行进一步的优化和扩展。如果在实现过程中遇到问题,请随时联系我获取更多帮助。
相关文章:
【机器学习】基于OpenCV和TensorFlow的MobileNetV2模型的物种识别与个体相似度分析
在计算机视觉领域,物种识别和图像相似度比较是两个重要的研究方向。本文通过结合深度学习和图像处理技术,基于OpenCV和TensorFlow的MobileNetV2的预训练模型模,实现物种识别和个体相似度分析。本文详细介绍该实验过程并提供相关代码。 一、名…...
建模杂谈系列244 TimeTraveller
说明 所有的基于时间处理和运行的程序将以同样的节奏同步和执行 TT(TimeTraveller)是一个新的设计,它最初会服务与量化过程的大量任务管理:分散开发、协同运行。但是很显然,TT的功能将远不止于此,它将服务大量的,基于时…...
基于MingGW64 GCC编译Windows平台上的 libuvc
安装cmake 打开cmake官网 https://cmake.org/download/,下载安装包: 安装时选择将cmake加到系统环境变量里。安装完成后在新的CMD命令窗口执行cmake --version可看到输出: D:\>cmake --version cmake version 3.29.3 CMake suite mainta…...
【Linux】网络高级IO
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:Linux 目录 👉🏻五种IO模型👉🏻消息通信的同步异步与进程线程的同步异步有什么不同?👉…...
【C++ ——— 继承】
文章目录 继承的概念即定义继承概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类对象和派生类对象的赋值转换继承中的作用域派生类中的默认成员函数继承与友元继承与静态成员菱形继承虚继承解决数据冗余和二义性的原理继承的总结继承常见笔试面试题 继…...
kafka-守护启动
文章目录 1、kafka守护启动1.1、先启动zookeeper1.1.1、查看 zookeeper-server-start.sh 的地址1.1.2、查看 zookeeper.properties 的地址 1.2、查看 jps -l1.3、再启动kafka1.3.1、查看 kafka-server-start.sh 地址1.3.2、查看 server.properties 地址 1.4、再次查看 jps -l 1…...
TypeScript 中的命名空间和模块化
1. 命名空间(Namespace) 命名空间提供了一种逻辑上的代码分组机制,用于避免命名冲突和将相关代码组织在一起。它使用 namespace 关键字来定义命名空间,并通过点运算符来访问其中的成员。例如: // 定义命名空间 names…...
9 html综合案例-注册界面
9 综合案例-注册界面 一个只有html骨架的注册页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…...
Xilinx RFSOC 47DR 8收8发 信号处理板卡
系统资源如图所示: FPGA采用XCZU47DR 1156芯片,PS端搭载一组64Bit DDR4,容量为4GB,最高支持速率:2400MT/s; PS端挂载两片QSPI X4 FLASH; PS支持一路NVME存储; PS端挂载SD接口,用于存储程序&…...
ros2 launch 用法以及一些基础功能函数的示例
文章目录 launch启动一个节点的launch示例launch文件中添加节点的namespacelaunch文件中的话题名称映射launch文件中向节点内传入命令行参数launch文件中向节点内传入rosparam使用方法多节点启动命令行参数配置资源重映射ROS参数设置加载参数文件在launch文件中使用条件变量act…...
如何使用Python获取图片中的文字信息
如下有三中方法: 方法1. 使用Tesseract OCR(pytesseract) 安装依赖 首先,确保你已经安装了Tesseract OCR引擎(例如,通过你的操作系统的包管理器)。然后,你可以通过pip安装pytesse…...
C++知识点
1. 构造函数:当没有写任何构造函数(含拷贝构造),系统会生成默认的无参构造,并且访问属性是共有。 默认拷贝构造:当没有写任何的拷贝构造,系统会生成默认的拷贝构造->是一个浅拷贝 写了拷贝构造函数,这…...
反转字符串中的单词-力扣
此题将问题分为三步进行解决: 第一步,删除字符串中多余的空格,removeSpaces函数中删除所有的空格,并手动在每个单词后添加一个空格,最后重构字符串s第二步,将整个字符串反转第三步,对反转后的字…...
Kotlin 重写与重载
文章目录 重写(Override)重载(Overload) 重写(Override) 重写通常是指子类覆盖父类的属性或方法,通常会标记为override: open class Base {open val name "Base"open f…...
关于高版本 Plant Simulation 每次保存是 提示提交comm对话框的处理方法
关于高版本 Plant Simulation 每次保存是 提示提交comm对话框的处理方法 如下图 将model saving history 修改为None即可 关于AutoCAD 2022 丢失模板库的问题 从新从以下地址打开即可: D:\Program Files\Autodesk\AutoCAD 2022\UserDataCache\zh-cn\Template...
C语言之旅:探索单链表
目录 一、前言 二、实现链表的功能: 打印 创建节点 尾插 尾删 头插 头删 查找 在指定位置之前插入数据 指定位置删除 在指定位置之后插入数据 打印 销毁 三、全部源码: 四、结语 一、前言 链表是一个强大且基础的数据结构。对于很多初…...
【安卓基础】-- 消息机制 Handler
目录 消息机制 Handler面试问题 消息机制 Handler 对handler机制的基本作用、用法、时序流程进行介绍,针对handler机制中的内存泄漏问题讲解:一篇读懂Android Handler机制 Android-Handler机制详解 全面解析 | Android之Handler机制 需要掌握的&#x…...
Optional 类
概述 到目前为止,臭名昭著的空指针异常是导致 Java 应用程序失败的最常见原因。以前,为了解决空指针异常,Google 公司著名的 Guava 项目引入了 Optional 类, Guava 通过使用检查空值的方式来防止代码污染,它鼓励程序员…...
自动微分技术在 AI for science 中的应用
本文简记我在学习自动微分相关技术时遇到的知识点。 反向传播和自动微分 以 NN 为代表的深度学习技术展现出了强大的参数拟合能力,人们通过堆叠固定的 layer 就能轻松设计出满足要求的参数拟合器。 例如,大部分图神经网络均基于消息传递的架构。在推理…...
ASM OMF single-file creation form 重命名
OMF下不能自动命名,需要重新命名的话:1 1. spfile 可以 create pfile from spfile 后再create spfile from pfile 2 redo? 3 datafile? Here are some details of the copy problem: a) You are not allowed to set the numbe…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
