ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

构建计算机视觉 WebApp — Flask、OpenCV 和 MongoDB

2022-09-02 09:00:45  阅读:376  来源: 互联网

标签:show Flask MongoDB OpenCV html 创建 上传 我们 模板


构建计算机视觉 WebApp — Flask、OpenCV 和 MongoDB

作为一名数据科学家,具备一些软件工程技能已成为就业市场中一项非常重要的技能。如果您可以构建模型,我建议您提高简单的应用程序开发和模型部署技能。

https://www.oreilly.com/library/view/python-advanced-guide

该项目

我最近收到了一个使用 Flask 创建对象检测应用程序的带回家的任务, 开放式CV 以及 1 周内的任何 NoSQL 数据库平台。我最后一次使用 Flask 是在 2 年前,当时我还是一名数据科学家,所以这是一个很好的更新项目。

该应用程序允许用户上传图像或视频,对上传的文件执行对象检测并将结果输出到 MongoDB 或者 AWS DynamoDB。

要查看完整的工作代码,请访问我的 ** GitHub 仓库** ** .**

*这里先睹为快

烧瓶

Flask 是一个允许使用 Python 无缝开发 Web 应用程序的框架。

与其他框架不同,Flask 非常 Pythonic。所以它没有很大的学习曲线,而且非常明确,增加了可读性。

要使用 Flask,我建议你过去 HTTPs 请求方法 这很容易理解。它们为您的应用程序(使用烧瓶)提供了一种与您创建的网页进行通信的方式。他们指定是否将数据发布到您的网站,从您的网站获取数据等等。

开放式CV

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。 OpenCV 旨在为计算机视觉应用程序提供通用基础架构。

通过我们将通过的代码,我们将看到 OpenCV 的实现,并带有注释以帮助理解。如果您已经熟悉深度学习和计算机视觉,您将能够更快地理解代码。

MongoDB

MongoDB 是一个面向文档的 NoSQL 数据库,用于大容量数据存储。 MongoDB 不像在传统关系数据库中那样使用表和行,而是使用类似 JSON 的文档。

常见的关系数据库具有具有固定模式(指定数据类型)的表,并使用 SQL(结构化查询语言)来管理数据。

使用 NoSQL,您可以将非结构化或半结构化数据存储在一起,而不是连接规范化数据的表;通常在键值对或 JSON 文档中。 NoSQL 在易用性、可扩展性、弹性和高效可用性方面表现出色。

连接到 MongoDB Atlas

这允许我们在云中使用 MongoDB。

  1. 创建一个免费帐户 这里 , 点击 “免费试用” .
  2. 点击 数据库 > , 并选择免费套餐。
  3. 通过选择所需的云服务提供商、集群层和集群名称来创建 Starter Cluster。
  4. 创建用户,选择使用本地环境并单击 添加我当前的 IP 地址 > 保持简单。
  5. 点击 数据库 > 在您刚刚创建的集群上单击 ** .**
  6. 点击 ** ** ,添加数据库名称和集合名称并创建。
  7. 返回您的集群,单击 ** ** ,会弹出一个窗口:
  8. 选择 ** ** 并选择您的驱动程序和版本——对我来说它的 Python 和版本 3.6 或更高版本。
  9. 创建一个空的python文件并命名 数据库.py 粘贴此代码,然后替换 <username> , <password> , <your_db_name> <your_collection_name> 使用您创建的值/名称。

看看我们如何使用它 数据库.py 文件,转到标题下的文章末尾> utils.py 中的辅助函数

项目结构

 ├── app.py  
 ├── utils.py  
 ├── db.py  
 └── 设置/  
 │ ├── requirements.txt  
 │ ├── setup.sh  
 └── 静态文件/  
 │ ├── 图片  
 │ ├── 影片  
 │ ├── 输出  
 │ ├── 上传  
 └── 模板文件/  
 │ ├── index.html  
 │ ├── show_image.html  
 │ ├── show_video.htl  
 │ ├── 成功.html  
 └── README.md

上面我们已经提到了HTTPS请求方法,现在让我们简单介绍一下html网站模板。

模板

烧瓶用途 神社2 ,这让我们可以使用 Python 来生成 html 网页(即模板)。

模板包含变量,这些变量是模板时传入的替换值 渲染 __ 通过我们在下面创建的函数 @app.routes() (我们在下一节中进一步解释路线) .

以下是如何创建模板的指南 → 点击这里 .

我们为我们的应用程序创建的模板是:

  • 索引.html: 我们将用于用户上传的登陆/主页。
  • show_image.html: 我们将用来显示用户上传的图片的页面。
  • show_video.html: 我们将用于显示用户上传的视频和
  • 成功.html: 与索引页面相同,但当用户成功上传文件时,它将加载“成功”消息。

要查看模板的完整代码,请访问我的 GitHub 仓库 在下面 模板文件/ 目录 → 这里 .在本教程中,我将只强调 html 页面的重要部分。要以交互方式了解有关 html 的更多信息,我建议使用 W3学校 .

应用程序代码

让我们从实际的 Flask 应用程序创建开始,之后我们将介绍对象检测代码。我们首先创建一个空的python文件并命名 应用程序.py ,导入 flask 及其库,然后创建一个 App 对象。

 从烧瓶导入烧瓶,渲染模板,请求,会话 app = Flask(__name__)

app = Flask(__name__) 创建一个 Flask 应用程序对象 在我们正在创建的当前 Python 文件中。这 应用程序 变量是一个 实例 我们在文件顶部导入了一个名为 Flask 的 Python 类。 应用程序 现在拥有 Flask 的所有函数、方法和属性。

我们还指定环境变量以显示我们的上传和输出数据应存储的路径。

 UPLOAD_FOLDER = os.path.join('staticFiles', 'uploads')  
 OUTPUT_FOLDER = os.path.join('staticFiles', 'output')

然后我们创建路线。

路线

路由将网站 URL 附加或映射到 Python 代码或函数,这些代码或函数决定在该特定路由 (URL) 上会发生什么。我们将创建这些功能。

对于每一个 @app.route('') 我们将创建,我们将加载特定路由将使用的 html 模板/页面。我们指定的任何路由名称都附加到我们网站 URL 的末尾。

我们将创建的示例路线最终将作为 https://ourwebapp.com/ , https://ourwebapp.com/show_image 或者 https://ourwebapp.com/detect-obect .请记住,在每条路线上,我们的应用程序都会执行与路线相关的代码。

  1. @app.route('/') 是我们将创建的第一条路线,它将把我们带到我们的主页。

我们可以看到这个主页路由只是一个空的 '/' 因为它的 URL 只是停留在着陆页上。

这里附加到这条路线的功能是 定义主(): ,它被命名为main,因为它是我们网站的主页,它真的可以命名任何你喜欢的名字。我们告诉函数返回 渲染模板(“index.html”) 这将加载 索引.html 模板/页面并使其显示在我们的网站上。

**索引.html** 模板

这是所有网站中主页的页面。在我们的网站上,我们将使用它从用户那里获取输入文件,因此我们需要使用 html 表单。

  • 动作=”/” 它调用了我们刚刚创建的@app.route('/')。
  • 方法="发布" 我们指定 POST 请求方法,因为用户会将数据发布到我们的网站上。
  • name = "文件上传" 指定上传文件的名称。这将在我们创建 Flask 应用程序时派上用场,因为我们将使用上传的文件来执行对象检测。
  • 动作="/show_image" 调用 @app.route('/show_image') 我们稍后会创建。它将用户带到 show_image.html .当用户单击“显示图像”提交按钮时会发生这种情况。

当。。。的时候 索引.html 渲染后,这将是我们的结果(使它看起来漂亮的代码在我的 GitHub 存储库中):

Our index.html page

2. 然后我们创建 @app.route('/', methods=[“POST”]) 允许用户上传文件的路由。

我们看到的一样 '/' 我们在主页路由中看到的意思是我们留在主页但这次我们指定 方法="发布" 因为我们将创建用户所在的部分 邮政 将他们的文件下载到我们的网站。

  • _img = request.files['文件上传'] 允许我们获取用户上传的图片或视频, 请求文件 是一个包含所有上传文件的字典对象。回想一下,在我们的 index.html 模板中,我们将用户上传的文件命名为 name = "文件上传" 因此,我们在这里称其为相同的名称。
  • 我们从 请求文件 上面的对象,然后将其传递给一个简短的帮助函数,该函数决定我们的应用程序中是否允许该文件类型。
  • 然后我们将图像保存到我们之前指定的上传文件夹路径中,然后
  • 会话['uploaded_img_file_path'] = … 一个 会议 (从上面的烧瓶中导入)用于在用户与 Web 应用程序交互时跨不同请求存储与用户相关的信息。在其中我们存储上传文件的路径。稍后我们将再次使用它。
  • 就像其他路线一样,我们返回 渲染模板() ——这次是 成功.html 显示文件是否上传成功的页面。

**成功.html** 模板:

它与 索引.html template ,除了这次我们添加这个 html 行:

 <p style="color:green;">文件上传成功</p>

这是渲染成功模板的部分:

3. 然后我们创建 @app.route('/show_image') 路线。

  • session.get('uploaded_img_file_path', 无) 允许我们获取/获取我们从 上传文件 我们在上面创建的路线。根据文件类型,无论是图像还是视频,我们返回 渲染模板() 为了 show_image.html 或者 show_video.html . 用户图像 是我们创建的一个变量,允许我们将图像插入到渲染的网页中。

**show_image/video.html** 模板

  • <video src=”{{ user_image }}” controls=”controls” ></video>: 使用 <video> </video> 我们周围的html标签 {{用户图像}} 变量让 html 知道期待来自我们上传文件路径的视频。如果它是一个图像,我们把 <img> </img> 标签。

在 Jinja 双卷曲 {{ }} 大括号允许我们评估 Python 表达式、变量或函数调用并将结果打印到模板中

  • 动作="/detect_object" 调用 @app.route('/detect_object') 这将是我们将创建的最终路线。

上传视频并渲染后 show_video.html 或者 show_image.html 模板,这是我们得到的结果:

4. 最后我们创建 @app.route('/detect_object') 路线。这条路线运行对象检测并将结果呈现给我们的 show_image/video.html 模板。

我们再次得到 上传图片路径 从会话中,然后我们运行我们的对象检测功能 def detect_and_draw_box() : 我们很快就会过去。

从中,我们得到 输出图像路径 保存图像结果的位置和 文件类型 这让我们的路由函数知道文件输出是“图像”还是“视频”,以便可以渲染相应的模板。

我们将从之前的上传中获得此输出。迷人的!!

现在让我们编码吧!

物体检测代码

我们创建一个名为 实用程序.py .这是代码的核心,我们编写的实际对象检测和辅助函数将在其中。

导入我们需要的所有库:

 进口我们  
 导入简历2  
 将 cvlib 导入为 cv  
 从 cvlib.object_detection 导入 draw_bbox

图像检测功能:

它需要 img_filepath 从保存的 应用程序.py 路线。我们使用“yolov3”模型并设置 信心 值,通常为 0.5(使用 50%)。

置信度是模型对检测到的对象分配正确标签的“信心”程度。编码器设置其阈值或截止点,以决定何时应为预测对象提供正标签。

  • img = cv2.imread(img_filepath) :OpenCv 将图像读入一个 numpy 数组以供我们的模型理解。
  • bbox,标签,conf = cv.detect_common_objects(img,信心,模型) 检测通用对象 使用预训练来检测 80 个常见对象。
  • 它返回图像中检测到的对象的边界框坐标(检测到的对象周围的框)、相应的标签和置信度分数。
  • output_image = draw_bbox(img, bbox, 标签, conf) :然后我们将框和标签绘制到图像上以获得输出图像。
  • output_image_path = os.path.join(OUTPUT_FOLDER, 'output_image.jpg') :我们指定图像输出名称和应保存的路径。
  • cv2.imwrite(输出图像路径,输出图像) 用于将图像保存到任何存储设备或路径。

其余代码使用我们创建的辅助函数将模型输出保存为本地 JSON(我们将其称为“响应”),并以这种格式将其推送到 MongoDB:

视频检测 功能:

cap = cv2.VideoCapture(video_filepath): 创建一个视频捕获对象,这将允许我们读取上传或流式传输的视频。

fourcc = cv2.VideoWriter_fourcc(*'MJPG'): 以 MJPG 格式保存输出视频。

四CC (“四字符代码”)是一个由四个组成的序列 字节 (通常 ASCII ) 用于唯一标识 数据格式 .

而 cap.isOpened() : 拍完视频后,可以用这个方法来检查你的视频是否打开成功。否则,您将收到一条错误消息。

ret, frame = cap.read(): 用于通过创建循环并一次读取一帧来捕获视频的每一帧。它返回一个元组 bool 和 frame,如果 ret 是 真的 然后有一个视频帧要读取。

如果 ret 返回 错误的 然后 print(“无法接收帧(流结束?)。正在退出……”) 并打破循环。

然后我们翻转图像,因为它可能会颠倒过来。

类似于 图片 检测代码,我们使用 检测通用对象 模型和 draw_bbox 函数显示每个检测到的对象的边界框和预测标签。

out = cv2.VideoWriter(out_path,fourcc, fps=10, (width, height)): 声明如何保存视频。指定输出文件夹,以指定的fourcc格式保存,将帧率(每秒帧数)设置为10.0,我们设置所需的大小。

out.write(输出帧): 将帧写入输出文件。

我们可以使用 显示() 在窗口中显示框架的方法。我们保存图像检测函数中指定的响应 JSON。

等待键() 指定在视频之间暂停多长时间并监视用户输入的键盘。当用户按下 q 键(当窗口在屏幕上打开时)我们退出循环并结束流式传输。

我们使用我们的辅助函数 添加数据() 将数据推送到 MongoDB Atlas 。 帽释放() 一旦视频流被完全处理或用户过早退出循环,就会释放视频捕获,在 out.release() 我们释放视频写入对象和 cv2.destroyAllWindows() 关闭窗口。最后我们保存模型输出 回复 本地。

utils.py 中的辅助函数:

其余的可以在 GitHub 仓库 *

 import db # 导入我们之前创建的 MongoDB db.py 文件

谢谢阅读!!

参考书目:

https://pythonbasics.org/what-is-flask-python/

https://python-adv-web-apps.readthedocs.io/en/latest/flask.html

https://tedboy.github.io/flask/

https://www.python-engineer.com/posts/opencv-videos/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/10962/54150208

标签:show,Flask,MongoDB,OpenCV,html,创建,上传,我们,模板
来源: https://www.cnblogs.com/amboke/p/16648569.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有