当前位置:   article > 正文

构建一个计算机视觉项目

构建一个计算机视觉项目

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达ab982bbac9b3331539c646d6860fd6e4.jpeg

你想创建一个应用程序来检测一些东西吗?猫和狗,检测水果的成熟程度,在图片中找到品牌?

如果你的答案是需要,那么这篇文章就是为你准备的!

将向你展示如何为你的探测器创建一个应用程序,并把它放到互联网上,让每个人都能看到。

最后,你将有类似这样的东西向你的同事和朋友展示:https://huggingface.co/spaces/Kili/plastic_in_river

你将能够上传一个测试图像,模型将返回预测框和标签。

免责声明:你需要在你的电脑中安装git才能将文件上传到HuggingFace Spaces。如果你没有,不要担心!安装起来很容易。遵循这个教程:https://git-scm.com/downloads

这将是项目的工作流程:

261c3589ac9a87486e5b997d21535d24.png
  1. 首先,你必须为你的项目收集图像。你想从长颈鹿中发现斑马吗?首先需要获取这两种动物的图像。无论你想检测什么,你都需要它的图像。这个点在工作流程中是白色的,这意味着你必须在你的计算机中完成工作。

  2. 标签图像在工作流中显示为蓝色,这是因为你将使用Datature的标签工具。Datature是一家专门为数据标签和模型训练构建用户友好工具的公司。

  3. 你还将使用Datature来训练模型。

  4. 一旦模型训练好了,你就把它下载到你的电脑上,把所有的文件放在一起(这些文件我会提供给你)

  5. 当所有文件放在一起时,你将把它们上传到HuggingFace Spaces,你的模型就可以使用了!


1.找到图片

在计算机视觉项目中,我们需要做的第一件事是收集图像。如果我们想要训练一个深度神经网络,我们需要成千上万张图像。

幸运的是,Datature使用非常先进的模型,而且可能是预训练的,这意味着如果我们从头开始训练模型,我们只需要需要的一小部分图像。

每个类大约有100个图像就足够了。例如,如果你想要检测t恤和裤子,你将需要100个t恤和100个裤子的图像。当然,这个例子也适用于其他情况。例如,你可以有100张猫和狗的图片,所以你可以有100张猫的例子,也可以有100张狗的例子。

如果有类不平衡是可以的,例如如果你的项目检测晴天和阴天,你可以有120张晴天的图片和100张阴天的图片。大约100张就足够了。

收集所有的图像并存储在你的计算机的一个文件夹中。

2.标记图像

在Datature中创建一个帐户,并为你的用例创建一个项目。这个来自Datature团队的教程解释了如何创建项目和标记图像。

https://datature.io/blog/train-and-visualize-face-mask-detection-model

这篇博文详细介绍了如何:

  • 创建Datature Nexus账户(免费试用)

  • 创建一个项目

  • 上传图片

  • 创建类

  • 注释图片

  • 在图像中创建矩形框

  • 为每个框分配一个类

对于每个图像,你将注释一个框(对象在哪里?)和一个类(对象是什么?)

只阅读标签部分,之后,在项目概述中,你应该看到你的图像统计,标签分布等。例如,项目概述应该是这样的:

a388939b0b21d27ad257d9d8bc8ba0b9.png

在这个例子中,我有一个名为香蕉的项目,我标记了16张图片,我有3类:成熟的、可食用的和无效的。这只是一个示例,所以请确保每个类至少有100个示例!


3.训练模型

一旦我们有了图像,我们就可以训练我们的模型了!我们将不得不在Nexus中创建一个“工作流”。尝试使用博客文章:https://datature.io/blog/train-and-visualize-face-mask-detection-model来完成以下步骤:

  • 构建训练工作流程:选择训练-测试分割比,选择增强,选择模型设置

  • 训练模型

  • 监控模型:损失、精度、召回

  • 导出模型

模型将需要大约1小时来训练,之后你应该看到这个

6d21746af365ecaf2114a030140d6c8a.png

进入Artifacts并下载TensorFlow模型

f8e14739ba6d648e1f7b72d40c925437.png

当计算机中导出了一个.zip文件时,这一部分就完成了。

4.创建一个HuggingFace帐户

模型是经过训练的,我们把它以.zip的形式下载到我们的电脑上。但我们如何与它交互呢?

我们可以通过上传照片到HuggingFace Spaces与它交互。我们还需要一些网站前端的代码。

Huggingface Spaces是Huggingface旗下的一个网站,人们可以在这里展示自己的模型,并与他们交互。

这些是创建步骤

  1. 创建Huggingface帐户

  2. 创建一个Space

  3. 为Space写一个名字。记住,这个网站将是公开的,所以选择一个与应用程序相匹配的名字!例如:香蕉分析或类似的东西

  4. 选择Streamlit作为空间SDK

  5. 选择public

  6. Space使用完成后,将存储库克隆到本地计算机中的一个文件夹中

  7. 可选的README.md

5.收集所有文件并上传至HuggingFace空间

现在,我们的计算机中有了属于Space的文件夹。我们必须复制所有文件,并使用git将所有文件上传到Space。

首先,复制模型文件(saved_model/ folder, label_map.pbtxt)到文件夹

然后,在这个https://gist.github.com/anebz/2f62caeab1f24aabb9f5d1a60a4c2d25文件夹中创建3个文件

app.py

此文件包含用于上传图像、加载模型、进行预处理和从模型获得预测的代码。

注意那些带有#TODO的行,你必须修改它们!

特别是color_map,它们是每个类的方框的颜色。打开文件label_map.pbtxt查看给每个类分配了什么label_id,并使用这个label_id为颜色分配RGB值。

在这个例子中,我只有2个类,因此只有2种颜色。如果你有更多的类,按照示例的格式添加更多行:

1: [255, 0, 0],

记住,除了最后一行以外,每一行的末尾都应该有一个逗号!

  1. import cv2
  2. import numpy as np
  3. from PIL import Image
  4. import streamlit as st
  5. import tensorflow as tf
  6. from tensorflow.keras.models import load_model
  7. # most of this code has been obtained from Datature's prediction script
  8. # https://github.com/datature/resources/blob/main/scripts/bounding_box/prediction.py
  9. st.set_option('deprecation.showfileUploaderEncoding', False)
  10. @st.cache(allow_output_mutation=True)
  11. def load_model():
  12.  return tf.saved_model.load('./saved_model')
  13. def load_label_map(label_map_path):
  14.     """
  15.     Reads label map in the format of .pbtxt and parse into dictionary
  16.     Args:
  17.       label_map_path: the file path to the label_map
  18.     Returns:
  19.       dictionary with the format of {label_index: {'id': label_index, 'name': label_name}}
  20.     """
  21.     label_map = {}
  22.     with open(label_map_path, "r") as label_file:
  23.         for line in label_file:
  24.             if "id" in line:
  25.                 label_index = int(line.split(":")[-1])
  26.                 
  27.                 label_name = next(label_file).split(":")[-1].strip().strip('"')
  28.                 
  29.                 label_map[label_index] = {"id": label_index, "name": label_name}
  30.     return label_map
  31.  
  32. def predict_class(image, model):
  33.  image = tf.cast(image, tf.float32)
  34.     
  35.  image = tf.image.resize(image, [150, 150])
  36.     
  37.  image = np.expand_dims(image, axis = 0)
  38.     
  39.  return model.predict(image)
  40. def plot_boxes_on_img(color_map, classes, bboxes, image_origi, origi_shape):
  41.  for idx, each_bbox in enumerate(bboxes):
  42.   color = color_map[classes[idx]]
  43.   ## Draw bounding box
  44.   cv2.rectangle(
  45.    image_origi,
  46.    (int(each_bbox[1] * origi_shape[1]),
  47.     int(each_bbox[0] * origi_shape[0]),),
  48.    (int(each_bbox[3] * origi_shape[1]),
  49.     int(each_bbox[2] * origi_shape[0]),),
  50.    color,
  51.    2,
  52.   )
  53.         
  54.   ## Draw label background
  55.   cv2.rectangle(
  56.    image_origi,
  57.    (int(each_bbox[1] * origi_shape[1]),
  58.     int(each_bbox[2] * origi_shape[0]),),
  59.    (int(each_bbox[3] * origi_shape[1]),
  60.     int(each_bbox[2] * origi_shape[0] + 15),),
  61.    color,
  62.    -1,
  63.   )
  64.         
  65.   ## Insert label class & score
  66.   cv2.putText(
  67.    image_origi,
  68.    "Class: {}, Score: {}".format(
  69.     str(category_index[classes[idx]]["name"]),
  70.     str(round(scores[idx], 2)),
  71.    ),
  72.    (int(each_bbox[1] * origi_shape[1]),
  73.     int(each_bbox[2] * origi_shape[0] + 10),),
  74.    cv2.FONT_HERSHEY_SIMPLEX,
  75.    0.3,
  76.    (0, 0, 0),
  77.    1,
  78.    cv2.LINE_AA,
  79.   )
  80.  return image_origi
  81. # Webpage code starts here
  82. #TODO change this
  83. st.title('YOUR PROJECT NAME')
  84. st.text('made by XXX')
  85. st.markdown('## Description about your project')
  86. with st.spinner('Model is being loaded...'):
  87.  model = load_model()
  88. # ask user to upload an image
  89. file = st.file_uploader("Upload image", type=["jpg", "png"])
  90. if file is None:
  91.  st.text('Waiting for upload...')
  92.     
  93. else:
  94.  st.text('Running inference...')
  95.     
  96.  # open image
  97.     
  98.  test_image = Image.open(file).convert("RGB")
  99.     
  100.  origi_shape = np.asarray(test_image).shape
  101.     
  102.  # resize image to default shape
  103.     
  104.  default_shape = 320
  105.     
  106.  image_resized = np.array(test_image.resize((default_shape, default_shape)))
  107.  ## Load color map
  108.     
  109.  category_index = load_label_map("./label_map.pbtxt")
  110.  # TODO Add more colors if there are more classes
  111.   # color of each label. check label_map.pbtxt to check the index for each class
  112.  color_map = {
  113.   1: [255, 0, 0], # bad -> red
  114.   2: [0, 255, 0] # good -> green
  115.  }
  116.  ## The model input needs to be a tensor
  117.     
  118.  input_tensor = tf.convert_to_tensor(image_resized)
  119.     
  120.  ## The model expects a batch of images, so add an axis with `tf.newaxis`.
  121.     
  122.  input_tensor = input_tensor[tf.newaxis, ...]
  123.  ## Feed image into model and obtain output
  124.     
  125.  detections_output = model(input_tensor)
  126.     
  127.  num_detections = int(detections_output.pop("num_detections"))
  128.     
  129.  detections = {key: value[0, :num_detections].numpy() for key, value in detections_output.items()}
  130.     
  131.  detections["num_detections"] = num_detections
  132.  ## Filter out predictions below threshold
  133.  # if threshold is higher, there will be fewer predictions
  134.  # TODO change this number to see how the predictions change
  135.  confidence_threshold = 0.8
  136.     
  137.  indexes = np.where(detections["detection_scores"] > confidence_threshold)
  138.  ## Extract predicted bounding boxes
  139.     
  140.  bboxes = detections["detection_boxes"][indexes]
  141.     
  142.  # there are no predicted boxes
  143.  if len(bboxes) == 0:
  144.   st.error('No boxes predicted')
  145.         
  146.  # there are predicted boxes
  147.  else:
  148.   st.success('Boxes predicted')
  149.         
  150.   classes = detections["detection_classes"][indexes].astype(np.int64)
  151.         
  152.   scores = detections["detection_scores"][indexes]
  153.   # plot boxes and labels on image
  154.   image_origi = np.array(Image.fromarray(image_resized).resize((origi_shape[1], origi_shape[0])))
  155.         
  156.   image_origi = plot_boxes_on_img(color_map, classes, bboxes, image_origi, origi_shape)
  157.   # show image in web page
  158.   st.image(Image.fromarray(image_origi), caption="Image with predictions", width=400)
  159.         
  160.   st.markdown("### Predicted boxes")
  161.         
  162.   for idx in range(len((bboxes))):
  163.    st.markdown(f"* Class: {str(category_index[classes[idx]]['name'])}, confidence score: {str(round(scores[idx], 2))}")

packages.txt:

  1. ffmpeg
  2. libsm6
  3. libxext6

requirements.txt:

  1. numpy==1.18.5
  2. opencv-python-headless
  3. Pillow==7.2.0
  4. streamlit
  5. tensorflow==2.3.0

packages.txt和requirements.txt是将安装在Space中的库。这些文件非常重要,没有它们,代码将无法运行。

最后,文件夹应该像这样

841ae2a145bf27afc52391af69d8e7fd.png
  • saved_model/是你先前从Datature下载的.zip文件中的文件夹

  • label_map.pbtxt存在于.zip文件

  • .gitattributes

  • README.md

  • app.py是用我在本文前面编写的代码创建的文件

  • requirements.txt在前面的代码中提供

  • packages.txt在前面的代码中提供

一旦我们需要的所有文件都在文件夹中,我们可以将其推送到Space。打开Git Bash,依次粘贴以下命令:

  • git add .

  • git commit -m “Added files”

  • git push

app上传文件需要一些时间,尤其是模型文件。git推送完成后,Space将花费几分钟来构建应用程序,并在Space中显示我们的应用程序。

如果git显示模型文件太大的错误,请查看这些帖子:https://discuss.huggingface.co/t/uploading-large-files-5gb-to-hf-spaces/12001/4和https://discuss.huggingface.co/t/uploading-files-larger-than-5gb-to-model-hub/4081/6

最后,你的应用会显示如下:https://huggingface.co/spaces/anebz/test

c39cf8f3af887731b321bdf1cb7b5dba.png

你可以上传一张图片,模型需要几秒钟来加载,然后你就可以看到预测结果了。项目完成了!

结论

你的项目完成了,祝贺你!!你可以从零开始快速创建一个应用程序。你只需要在你的电脑上安装Git,不需要Python或者不需要编写任何代码。

  1. 下载1:OpenCV-Contrib扩展模块中文版教程
  2. 在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
  3. 下载2:Python视觉实战项目52
  4. 在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
  5. 下载3:OpenCV实战项目20
  6. 在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
  7. 交流群
  8. 欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/472592
推荐阅读
相关标签
  

闽ICP备14008679号