Python调用MMDetection实现AI抠图去背景

2023-11-16

这篇文章的内容是以 《使用MMDetection进行目标检测、实例和全景分割》 为基础,需要安装好 MMDetection 的运行环境,同时完成目标检测、实例分割和全景分割的功能实践,之后再看下面的内容。

想要实现AI抠图去背景的需求,我们需要利用 OpenMMLab 项目 MMDetection 模型库中的实例分割(Instance Segmentation)模型,来帮我们完成最核心的分类、分割图片物体任务。

接下来的主要操作是在 demo.py 编写和调试代码,首先编写下面的代码:

import cv2
import mmcv
from copy import deepcopy
from mmdet.apis import init_detector, inference_detector

config_file = 'configs/scnet/scnet_r50_fpn_1x_coco.py'  # 配置文件路径
checkpoint_file = 'checkpoints/scnet/scnet_r50_fpn_1x_coco-c3f09857.pth'  # 预训练模型加载路径
device = 'cpu'  # cpu|gpu
model = init_detector(config_file, checkpoint_file, device=device)  # 构建模型
img_raw = mmcv.imread('demo/demo.jpg')  # 待推理图像的原始 numpy.ndarray 对象

img_h = img_raw.shape[0]  # 图像高度像素值
img_w = img_raw.shape[1]  # 图像宽度像素值

result = inference_detector(model, img_raw)  # 推理的结果
img_result = model.show_result(img_raw, result)  # 结果图像的 numpy.ndarray 对象
model.show_result(img_raw, result, out_file='demo/demo_result.jpg')  # 将结果图像另存为文件

执行 demo.py 文件后,项目下面会生成 demo/demo_result.jpg 文件:

demo_result_1676859284

之前,我们是通过另存为文件的方式,来可视化推理的结果,现在,我们要进一步的解析推理结果。由模型文件名称 scnet_r50_fpn_1x_coco-c3f09857.pth 可知,这是个使用 coco 数据集训练出来的预训练模型,所以我们需要用 coco 数据集的定义方式去解析推理结果。

demo.py 文件里继续编写,提前定义一个存储和解析推理结果的 coco_80_dict 字典:

coco_80_dict = {
    'person': {'index': 0, 'id': 1, 'describe': '人'},
    'bicycle': {'index': 1, 'id': 2, 'describe': '自行车'},
    'car': {'index': 2, 'id': 3, 'describe': '车'},
    'motorcycle': {'index': 3, 'id': 4, 'describe': '摩托车'},
    'airplane': {'index': 4, 'id': 5, 'describe': '飞机'},
    'bus': {'index': 5, 'id': 6, 'describe': '公交车'},
    'train': {'index': 6, 'id': 7, 'describe': '火车'},
    'truck': {'index': 7, 'id': 8, 'describe': '卡车'},
    'boat': {'index': 8, 'id': 9, 'describe': '船'},
    'traffic light': {'index': 9, 'id': 10, 'describe': '红绿灯'},
    'fire hydrant': {'index': 10, 'id': 11, 'describe': '消防栓'},
    'stop sign': {'index': 11, 'id': 13, 'describe': '停车标志'},
    'parking meter': {'index': 12, 'id': 14, 'describe': '停车收费表'},
    'bench': {'index': 13, 'id': 15, 'describe': '板凳'},
    'bird': {'index': 14, 'id': 16, 'describe': '鸟'},
    'cat': {'index': 15, 'id': 17, 'describe': '猫'},
    'dog': {'index': 16, 'id': 18, 'describe': '狗'},
    'horse': {'index': 17, 'id': 19, 'describe': '马'},
    'sheep': {'index': 18, 'id': 20, 'describe': '羊'},
    'cow': {'index': 19, 'id': 21, 'describe': '牛'},
    'elephant': {'index': 20, 'id': 22, 'describe': '大象'},
    'bear': {'index': 21, 'id': 23, 'describe': '熊'},
    'zebra': {'index': 22, 'id': 24, 'describe': '斑马'},
    'giraffe': {'index': 23, 'id': 25, 'describe': '长颈鹿'},
    'backpack': {'index': 24, 'id': 27, 'describe': '背包'},
    'umbrella': {'index': 25, 'id': 28, 'describe': '雨伞'},
    'handbag': {'index': 26, 'id': 31, 'describe': '手提包'},
    'tie': {'index': 27, 'id': 32, 'describe': '领带'},
    'suitcase': {'index': 28, 'id': 33, 'describe': '手提箱'},
    'frisbee': {'index': 29, 'id': 34, 'describe': '飞盘'},
    'skis': {'index': 30, 'id': 35, 'describe': '雪橇'},
    'snowboard': {'index': 31, 'id': 36, 'describe': '滑雪板'},
    'sports ball': {'index': 32, 'id': 37, 'describe': '运动球'},
    'kite': {'index': 33, 'id': 38, 'describe': '风筝'},
    'baseball bat': {'index': 34, 'id': 39, 'describe': '棒球棒'},
    'baseball glove': {'index': 35, 'id': 40, 'describe': '棒球手套'},
    'skateboard': {'index': 36, 'id': 41, 'describe': '滑板'},
    'surfboard': {'index': 37, 'id': 42, 'describe': '冲浪板'},
    'tennis racket': {'index': 38, 'id': 43, 'describe': '网球拍'},
    'bottle': {'index': 39, 'id': 44, 'describe': '瓶'},
    'wine glass': {'index': 40, 'id': 46, 'describe': '酒杯'},
    'cup': {'index': 41, 'id': 47, 'describe': '杯'},
    'fork': {'index': 42, 'id': 48, 'describe': '叉子'},
    'knife': {'index': 43, 'id': 49, 'describe': '刀'},
    'spoon': {'index': 44, 'id': 50, 'describe': '汤匙'},
    'bowl': {'index': 45, 'id': 51, 'describe': '碗'},
    'banana': {'index': 46, 'id': 52, 'describe': '香蕉'},
    'apple': {'index': 47, 'id': 53, 'describe': '苹果'},
    'sandwich': {'index': 48, 'id': 54, 'describe': '三明治'},
    'orange': {'index': 49, 'id': 55, 'describe': '橙'},
    'broccoli': {'index': 50, 'id': 56, 'describe': '西兰花'},
    'carrot': {'index': 51, 'id': 57, 'describe': '胡萝卜'},
    'hot dog': {'index': 52, 'id': 58, 'describe': '热狗'},
    'pizza': {'index': 53, 'id': 59, 'describe': '披萨'},
    'donut': {'index': 54, 'id': 60, 'describe': '甜甜圈'},
    'cake': {'index': 55, 'id': 61, 'describe': '蛋糕'},
    'chair': {'index': 56, 'id': 62, 'describe': '椅子'},
    'couch': {'index': 57, 'id': 63, 'describe': '沙发'},
    'potted plant': {'index': 58, 'id': 64, 'describe': '盆栽植物'},
    'bed': {'index': 59, 'id': 65, 'describe': '床'},
    'dining table': {'index': 60, 'id': 67, 'describe': '餐桌'},
    'toilet': {'index': 61, 'id': 70, 'describe': '厕所'},
    'tv': {'index': 62, 'id': 72, 'describe': '电视'},
    'laptop': {'index': 63, 'id': 73, 'describe': '笔记本电脑'},
    'mouse': {'index': 64, 'id': 74, 'describe': '鼠标'},
    'remote': {'index': 65, 'id': 75, 'describe': '遥控器'},
    'keyboard': {'index': 66, 'id': 76, 'describe': '键盘'},
    'cell phone': {'index': 67, 'id': 77, 'describe': '手机'},
    'microwave': {'index': 68, 'id': 78, 'describe': '微波炉'},
    'oven': {'index': 69, 'id': 79, 'describe': '烤箱'},
    'toaster': {'index': 70, 'id': 80, 'describe': '烤面包机'},
    'sink': {'index': 71, 'id': 81, 'describe': '水槽'},
    'refrigerator': {'index': 72, 'id': 82, 'describe': '冰箱'},
    'book': {'index': 73, 'id': 84, 'describe': '书'},
    'clock': {'index': 74, 'id': 85, 'describe': '时钟'},
    'vase': {'index': 75, 'id': 86, 'describe': '花瓶'},
    'scissors': {'index': 76, 'id': 87, 'describe': '剪刀'},
    'teddy bear': {'index': 77, 'id': 88, 'describe': '泰迪熊'},
    'hair drier': {'index': 78, 'id': 89, 'describe': '吹风机'},
    'toothbrush': {'index': 79, 'id': 90, 'describe': '牙刷'},
}

推理结果 result 的长度为 len(result) == 2,其中:

  • 检测框 result[0] 的长度固定为 len(result[0]) == 80,因为 coco 数据集用于检测、分割的部分共有 80 个类别
    • 检测框的解析方式
      • 长度为 5 的列表,内容分别代表的是 [x1, y1, x2, y2, 置信度]
    • 检测框的数据示例
      [
          array([
              [2.54207230e+02, 1.04094536e+02, 2.62954681e+02, 1.12405502e+02, 7.87650794e-02],
              [3.75357147e+02, 1.20013657e+02, 3.81758453e+02, 1.33114960e+02, 6.91782460e-02],
              [5.32841248e+02, 1.09704865e+02, 5.40237061e+02, 1.24966133e+02, 1.59687027e-02],
              [6.22804871e+02, 1.05815277e+02, 6.35152161e+02, 1.15566162e+02, 5.09093935e-03]
          ], dtype=float32),
          array([], shape=(0, 5), dtype=float32),
          array([
              [4.81168701e+02, 1.10373505e+02, 5.23180786e+02, 1.30380783e+02, 9.89862204e-01],
              [4.32057190e+02, 1.04940285e+02, 4.83949829e+02, 1.32065140e+02, 9.75807786e-01],
              [8.68552148e-01, 1.12007828e+02, 6.18107605e+01, 1.44267593e+02, 9.75750148e-01],
              [6.08653687e+02, 1.11829590e+02, 6.35857971e+02, 1.37511154e+02, 9.74755704e-01],
              [2.66471069e+02, 1.05501320e+02, 3.26720917e+02, 1.27970596e+02, 9.69615817e-01],
              [1.91124908e+02, 1.08998817e+02, 2.99086731e+02, 1.55649002e+02, 9.68829334e-01],
              [3.98783081e+02, 1.11128929e+02, 4.33258514e+02, 1.33113083e+02, 9.66077983e-01],
              ......
              [2.54207230e+02, 1.04094536e+02, 2.62954681e+02, 1.12405502e+02, 5.26814163e-03]
          ], dtype=float32),
          ......
          array([
              [3.7397647e+02, 1.3353706e+02, 4.3298822e+02, 1.8852022e+02, 2.0611383e-01],
              [2.1776900e+02, 1.7274181e+02, 4.5755392e+02, 3.8911337e+02, 6.3707083e-03]
          ], dtype=float32),
          array([], shape=(0, 5), dtype=float32)
      ]
      
  • 分割对象 result[1] 的长度固定为 len(result[1]) == 80,同样代表 coco 数据集里的 80 个类别
    • 分割对象的解析方式,是一个 2 维数组
      • 1 个维度代表图像的高度
      • 2 个维度代表图像的框度
      • 具体的 bool 值用于判断下标 [h][w] 的像素点是否为识别目标的分割像素点,以抠图需求为例
        • True 表示下标 [h][w] 的像素点应该被保留
        • False 表示下标 [h][w] 的像素点应该被去掉
    • 分割对象的数据示例
      [
          [
              array([
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  ...,
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False]
              ]),
              array([
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  ...,
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False]
              ]),
              array([[False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  ...,
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False],
                  [False, False, False, ..., False, False, False]
              ])
          ],
          ...,
          [],
          []
      ]
      

因为推理结果 result 的组织结构是 result [0=检测框,1=分割对象] [coco 80 个类别的顺序下标],这种组织结构不方便我们提取抠图的数据,所以需要将推理结果 result 拆解后存储到前面定义好 coco_80_dict 字典中。

demo.py 文件里继续编写,拆解推理结果 result 数据,以方便我们提取抠图的结构存储到 coco_80_dict 字典:

for cc_key, cc_value in coco_80_dict.items():
    coco_80_dict[cc_key]['number'] = len(result[0][cc_value['index']])
    coco_80_dict[cc_key]['detection'] = result[0][cc_value['index']]
    coco_80_dict[cc_key]['segmentation'] = result[1][cc_value['index']]

此时 coco_80_dict 字典的数据结构如下所示:

{
    'person': {
        'index': 0,
        'id': 1,
        'describe': '人',
        'number': 4,
        'detection': 检测框 list[[x1, y1, x2, y2, 置信度]],
        'segmentation': 分割对象 list[[h][w]=是否为识别目标的分割像素点]
    },
    ......
    'toothbrush': {
        'index': 79,
        'id': 90,
        'describe': '牙刷',
        'number': 0,
        'detection': array([], shape=(0, 5), dtype=float32),
        'segmentation': []
    }
}

接下来以位于图像中心位置的板凳为例,把板凳的检测框和分割对象可视化成图像文件,我们开始解析,首先可视化板凳的检测框。

demo.py 文件里继续编写,读取第 1 个板凳的检测框( coco_80_dict['bench']['detection'][0] ),并将其可视化:

img_detection = deepcopy(img_raw)  # 深拷贝原始 numpy.ndarray 对象
img_detection_data = coco_80_dict['bench']['detection'][0]  # 第1个板凳的检测框
img_detection_data_x1 = int(img_detection_data[0])
img_detection_data_y1 = int(img_detection_data[1])
img_detection_data_x2 = int(img_detection_data[2])
img_detection_data_y2 = int(img_detection_data[3])
print(f'目标置信度 = {img_detection_data[4]*100}%')  # 绘制比较麻烦,就直接打印

for x_i in range(img_detection_data_x1, img_detection_data_x2):
    img_detection[img_detection_data_y1, x_i] = [0,0,255]  # 重置为 [0,0,255] 即红色像素点
    img_detection[img_detection_data_y2, x_i] = [0,0,255]

for y_i in range(img_detection_data_y1, img_detection_data_y2):
    img_detection[y_i, img_detection_data_x1] = [0,0,255]
    img_detection[y_i, img_detection_data_x2] = [0,0,255]

cv2.imwrite(f'demo/demo_result_detection.jpg', img_detection)

执行 demo.py 文件后,控制台会打印 目标置信度 = 99.38850998878479%,然后项目下面会生成 demo/demo_result_detection.jpg 文件:

demo_result_detection_1676874870

demo.py 文件里继续编写,读取第 1 个板凳的分割对象( coco_80_dict['bench']['segmentation'][0] ),并将其可视化:

img_segmentation = deepcopy(img_raw)  # 深拷贝原始 numpy.ndarray 对象
img_segmentation_data = coco_80_dict['bench']['segmentation'][0]  # 第1个板凳的分割对象
for h_i in range(img_h):
    for w_i in range(img_w):
        # 通过分割对象的 bool 值来判断像素点是否需要去除(重置为 [255,255,255] 即纯白背景)
        if not img_segmentation_data[h_i, w_i]:
            img_segmentation[h_i, w_i] = [255,255,255]

cv2.imwrite(f'demo/demo_result_segmentation.jpg', img_segmentation)

执行 demo.py 文件后,项目下面会生成 demo/demo_result_segmentation.jpg 文件:

demo_result_segmentation_1676875708

最后,就是抠图最后一步,把现在的 3 通道图像数据改成 4 通道(添加透明度的通道),输出透明背景的图像文件。

demo.py 文件里继续编写,读取第 1 个板凳的分割对象( coco_80_dict['bench']['segmentation'][0] ),先添加透明度通道再并将其可视化:

img_segmentation_png_raw = deepcopy(img_raw)  # 深拷贝原始numpy.ndarray对象
img_segmentation_png = np.full((img_h, img_w, 4), 0, dtype='uint8')  # 创建(图像高,图像宽,4通道)大小的numpy.ndarray对象
img_segmentation_png_data = coco_80_dict['bench']['segmentation'][0]
for h_i in range(img_h):
    for w_i in range(img_w):
        if img_segmentation_png_data[h_i, w_i]:
            img_segmentation_png[h_i, w_i] = np.append(img_segmentation_png_raw[h_i, w_i], 255)

cv2.imwrite(f'demo/demo_result_segmentation_png.png', img_segmentation_png)

执行 demo.py 文件后,项目下面会生成 demo/demo_result_segmentation_png.png 文件:

demo_result_segmentation__1676881555

至此,就完成了Python调用MMDetection实现AI抠图去背景的功能!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python调用MMDetection实现AI抠图去背景 的相关文章

  • for 循环在 Python 中生成/导出输出所需的时间太长

    这个问题是上一个问题的延续for 循环花费太长时间才能产生输出 https stackoverflow com questions 41339200 for loop taking too long to produce output no
  • 从一个数组中删除另一个数组中的元素

    假设我有这些二维数组A and B 我怎样才能从中删除元素A那些在B 集合论中的补集 A B A np asarray 1 1 1 1 1 2 1 1 3 1 1 4 B np asarray 0 0 0 1 0 2 1 0 3 1 0 4
  • goJS 下拉菜单删除项目

    我有简单的 python Flask goJS 图形应用程序 如下所示 节点和链接文本的源是从应用程序的后端加载的 我将它们设置为model modelData像这样的部分 var graphDataString JSON parse di
  • 如何在Python中找到低精度浮点值的原始文本表示?

    我遇到了显示问题floatPython 中的值 从外部数据源加载 它们是 32 位浮点数 但这也适用于较低精度的浮点数 以防万一 这些值是由人类在 C C 中输入的 因此与任意计算值不同 与round数字很 可能not预期的 但不能被忽略
  • Python 如果 kwargs 中的 key 并且 key 为 true

    if force in kwargs and kwargs force is True 感觉应该有更好的方法来编写这个条件 因为我重复了键和变量 假设您确实想检查返回的关键字参数是否is True 这是另一种稍微不同的方式 if kwarg
  • python类型中的__flags__有什么用

    我最近阅读了pickle源代码 以下代码在copy reg让我很困惑 HEAPTYPE 1 lt lt 9 def reduce ex self proto assert proto lt 2 for base in self class
  • Django 和 AWS 简单电子邮件服务 [重复]

    这个问题在这里已经有答案了 我正在尝试启动并运行 django 站点 并且正在尝试启用 django 的标准密码重置服务 我的网站由 AWS EC2 托管 因此我想将 AWS SES 用于我的电子邮件服务 但是 我无法使 smtp 连接正常
  • PRAW 出现 SSLError?

    我正在尝试开始使用 PRAW 但在使用 login 时遇到问题 我有以下代码 import praw r praw Reddit This is a test bot r login myRedditUsername password 我收
  • Python textwrap.wrap 导致 \n 问题

    所以我只是重新格式化了一堆代码以合并textwrap wrap 却发现我所有的 n都消失了 这是一个例子 from textwrap import wrap def wrapAndPrint msg width 25 wrap msg to
  • Python 的二进制字符串列表

    我有一个像这样的二进制字符串 1100011101 我想将其解析为一个列表 其中每个 1 或 0 块都是列表中的单独值 例如 1100011101 变成 11 000 111 0 1 您可以通过使用正则表达式而不是从中获得一点 次要 性能g
  • Web 应用程序框架:C++ 与 Python

    作为一名程序员 我熟悉 Python 和 C 我正在考虑编写自己的简单 Web 应用程序 并且想知道哪种语言更适合服务器端 Web 开发 我正在寻找一些东西 它必须是直观的 我认识到 Wt 存在并且它遵循 Qt 的模型 我讨厌 Qt 的一件
  • 并行磁盘 I/O

    我有几个想要阅读的日志文件 不失一般性 假设日志文件处理如下 def process infilepath answer 0 with open infilepath as infile for line in infile if line
  • Python 日志记录 - 如何检查记录器是否为空

    我刚刚在我的应用程序中实现了日志记录 我想知道是否有一种方法可以检查记录器是否为空 我的想法是在我的脚本中设置两个处理程序 一个用于带水平仪的控制台WARNING 一个用于带级别的文件DEBUG 在脚本的最后 我需要检查是否CONSOLE记
  • 无法从源 pylance 解析导入烧瓶

    我正在学习 Python 课程的一部分是使用 Flask 设置网络服务器 我按照 Flask 安装文档执行了步骤 由于某种原因 flask 模块带有下划线 如下所示 当我将鼠标悬停时 我会得到如下附加信息 无法从源 pylance 解析导入
  • 打包布尔数组需要通过 int (numpy 1.8.2)

    我正在寻找更紧凑的方式来存储布尔值 numpy 内部需要 8 位来存储一个布尔值 但是np packbits允许打包 他们 这真是太酷了 问题是要打包在4e6字节数组a32e6字节我们需要首先使用的布尔值数组256e6字节将布尔数组转换为
  • 编写 CherryPy 装饰器以进行授权

    我有一个cherrypy应用程序 在某些视图上我想开始只允许某些用户查看它们 并将其他任何人发送到需要授权的页面 有没有办法使用自定义装饰器来做到这一点 我认为这将是最优雅的选择 这是我想做的一个基本示例 class MyApp autho
  • 添加条件计数器:基于其他列的值的计数器列

    我有一张这样的桌子 id id2 val a red apple a red orange b blue fish c violet beef a yellow banana a black pork 我想根据 id 和 id2 的值创建一
  • 如何找到 JAR:/home/hadoop/contrib/streaming/hadoop-streaming.jar

    我正在练习有关 Amazon EMR 的复数视角视频教程 我被困住了 因为我收到此错误而无法继续 Not a valid JAR home hadoop contrib streaming hadoop streaming jar 请注意
  • Django 表单中的只读字段

    如何在 Django 表单中将字段设置为只读 我知道如何禁用某个字段 但这不是我想要的 任何帮助 将不胜感激 您可以使用可选的attrs定义时的参数Field 以机智 somefield forms CharField widget for
  • 我收到错误:rest_framework.request.WrappedAttributeError:'CSRFCheck'对象没有属性'process_request'

    urls py from django conf urls import url from django contrib import admin from django conf import settings from django c

随机推荐

  • ABAP 向上取整和向下取整 CEIL & FLOOR

    ls taba 2 zjybs floor lv zlssl ls taba 2 bstrf 向上取整 CEIL 改为向下取整 FLOOR DATA a TYPE mseg menge b TYPE mseg menge c TYPE ms
  • shell 与用户交互

    bash shell如何获取命令行参数 添加到命令后的数据 命令行选项 确定命令行为的英文字母 键盘输入数据 操作命令行参数 1 读取参数 bash shell用位置参数变量 positional parameter 存储命令行输入的所有参
  • 第一次考CCF有感

    DWT来查寝时告诉我ccf能查分了 突然间就很紧张 很忐忑 我不知道我将面临的分数会是多少 说实话我幻想过400分 因为我感觉这次题目相比以前还是要简单一些的 毕竟图论都没考 表面上 2018 12 17 登上网址 查询成绩 这短短的几秒仿
  • 分库分表之拆分键设计

    众所周知 在现实世界中 每一个资源都有其提供能力的最大上限 当单一资源达到最大上限后就得让多个资源同时提供其能力来满足使用方的需求 同理 在计算机世界中 单一数据库资源不能满足使用需求时 我们也会考虑使用多个数据库同时提供服务来满足需求 当
  • spring-boot返回数据为null时返回空字符串

    在项目开发中 我们会遇到一些null值 如果不想让返回数据有null值 而是返回空字符串该怎么办捏 So Easy 我们做一下配置就好了 1 Jackson null值处理 spring boot是对Jackson默认支持的 所以有了web
  • (十一) 编译工具cmake

    文章目录 1 简单例子 2 管理工程 3 生成和使用共享库 3 1生成动态共享库 3 2引用库文件 4 其他 4 1环境变量 4 2系统信息 4 3 主要的开关选项 5 常用指令 5 1ADD DEFINITIONS 5 2 ADD DEP
  • k8s Unable to connect to the server: EOF 问题解决

    原因是K8s 没有启动成功 如下状态方位 启动成功 启动失败的原因多数是镜像下载失败 找到 Docker 的设置页面 在 Docker Engine 页面 将镜像网站的地址加入到右侧配置文件的 registry mirrors 节点下面 这
  • java毕业设计——基于java+Eclipse+jsp的网上手机销售系统设计与实现(毕业论文+程序源码)——网上手机销售系统

    基于java Eclipse jsp的网上手机销售系统设计与实现 毕业论文 程序源码 大家好 今天给大家介绍基于java Eclipse jsp的网上手机销售系统设计与实现 文章末尾附有本毕业设计的论文和源码下载地址哦 需要下载开题报告PP
  • 攻防世界Web题 - unseping 总结

    攻防世界Web题 unseping 总结 1 审题 进入题目 可以看出来是典型的php反序列化题目 2 源代码分析
  • 论文查找路径 查找IEEE、ScienceDirect论文 免费查看的方法

    IEEE ScienceDirect转免费查看网站网址 IEEE和ScienceDirect上的论文不少质量不错的 但是不少都是要收费才能下载查看的 怎么办呢 有国外大神提供的工具来帮忙 打开上面的网址 里面提供了三个网址 随便打开一个 仅
  • RabbitMQ--扩展--2.2--性能测试--linux.md

    RabbitMQ 扩展 2 2 性能测试 linux md 1 下载 https github com rabbitmq rabbitmq perf test releases tag v2 18 0 rabbitmq perf test
  • python发邮件--中文附件报错问题

    coding utf 8 Created on Thu Apr 11 14 01 30 2019 author zhang peng coding utf 8 import os import sys import smtplib from
  • 擎创技术流

    上期跟大家聊了下eBPF的发展历史还有特性 点击这里 擎创技术流 深入浅出运维可观测工具 一 聊聊eBPF的前世今生 一键回看上期精彩内容 这期主要跟大家分享下eBPF在应用过程中可能出现的问题 希望能帮到遇到类似问题的朋友 话不多说 我们
  • GIOU:Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression

    废话不多说 先看motivation There is a gap between optimizing the commonly used distance losses and maximizing this metric value
  • 高并发应用实践——缓存简介

    简介 随着互联网的普及 内容越来越复杂 用户和数据量越来越大 所以我们的应用应该支持更高的并发数 但是由于我们的服务器和数据库服务器资源量是有限的 所以如何更加高效的利用这有限的资源 并提供尽可能大的数据吞吐量 一个有效可行的办法就是引入缓
  • shell调用php脚本,并传递参数

    命令行执行带参数的php脚本 并取得参数 张映 发表于 2011 07 15 分类目录 php 一 为什么我们要在命令行下运行php脚本呢 个人理解 主要有二个原因 1 利用crontab去跑php 可以给服务器减压 当然在这里有一个条件
  • 如何导出mysql数据库

    mysql数据库是非常常用的一种数据库 属于中小型数据库 常用于网站业务和一些WEB系统业务 这个数据库非常简单 体积比较小 使用起来比较方便简洁 今天重点来介绍一下该数据的三种导出方法 1 使用工具软件导出数据库文件 这里推荐使用navi
  • ElementUI浅尝辄止30:PageHeader 页头

    如果页面的路径比较简单 推荐使用页头组件而非面包屑组件 1 如何使用
  • 信号处理之FFT(如何求幅度、相位、画频谱图)

    信号处理 可以理解为对信号进行某种加工或变换来达到削弱信号中的多余内容 滤除混杂的噪声和干扰 将信号变换成容易分析与识别的形式 便于估计和选择它的特征参量等目的 快速傅里叶变换 FFT 是信号处理的重要组成部分 是离散傅里叶变换 DFT 的
  • Python调用MMDetection实现AI抠图去背景

    这篇文章的内容是以 使用MMDetection进行目标检测 实例和全景分割 为基础 需要安装好 MMDetection 的运行环境 同时完成目标检测 实例分割和全景分割的功能实践 之后再看下面的内容 想要实现AI抠图去背景的需求 我们需要利