xml转voc,voc转coco,coco转yolo,coco划分,coco检查,yolo检查,coco可视化
平常用coco格式的数据集比较多,所有这里整合一下数据集相关的常用的脚本。
pycocotools安装
这个非常重要,因为处理coco数据集时,用pycocotools包非常方便。
自行搜索一下怎么安装吧,windows安装比较麻烦。网上有很多方法,但是都有时效性,不定时就失效了。如果有好的安装pycocotools的文章,可以把链接评论在评论区。
xml转voc
xml2voc.py
# 命令行执行: python xml2voc2007.py --input_dir data --output_dir VOCdevkit
# 输出文件夹必须为空文件夹
import argparse
import glob
import os
import random
import sys
import shutil
# 主程序执行
def xml2voc():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("--input_dir", default="data", help="input annotated directory")
parser.add_argument("--output_dir", default="VOCdevkit", help="output dataset directory")
args = parser.parse_args()
if os.path.exists(args.output_dir):
print("Output directory already exists:", args.output_dir)
sys.exit(1)
os.makedirs(args.output_dir)
print("| Creating dataset dir:", os.path.join(args.output_dir, "VOC2007"))
# 创建保存的文件夹
if not os.path.exists(os.path.join(args.output_dir, "VOC2007", "Annotations")):
os.makedirs(os.path.join(args.output_dir, "VOC2007", "Annotations"))
if not os.path.exists(os.path.join(args.output_dir, "VOC2007", "ImageSets")):
os.makedirs(os.path.join(args.output_dir, "VOC2007", "ImageSets"))
if not os.path.exists(os.path.join(args.output_dir, "VOC2007", "ImageSets", "Main")):
os.makedirs(os.path.join(args.output_dir, "VOC2007", "ImageSets", "Main"))
if not os.path.exists(os.path.join(args.output_dir, "VOC2007", "JPEGImages")):
os.makedirs(os.path.join(args.output_dir, "VOC2007", "JPEGImages"))
# 获取目录下所有的.jpg文件列表
total_img = glob.glob(os.path.join(args.input_dir, "*.jpg"))
print('| Image number: ', len(total_img))
# 获取目录下所有的joson文件列表
total_xml = glob.glob(os.path.join(args.input_dir, "*.xml"))
print('| Xml number: ', len(total_xml))
percent_trainval = 0.8
percent_train = 0.75
num_total = len(total_xml)
data_list = range(num_total)
num_tv = int(num_total * percent_trainval)
num_tr = int(num_tv * percent_train)
num_trainval = random.sample(data_list, num_tv)
num_train = random.sample(num_trainval, num_tr)
print('| Train number: ', num_tr)
print('| Val number: ', num_tv - num_tr)
print('| Test number: ', num_total - num_tv)
file_trainval = open(
os.path.join(args.output_dir, "VOC2007", "ImageSets", "Main", "trainval.txt"), 'w')
file_test = open(
os.path.join(args.output_dir, "VOC2007", "ImageSets", "Main", "test.txt"), 'w')
file_train = open(
os.path.join(args.output_dir, "VOC2007", "ImageSets", "Main", "train.txt"), 'w')
file_val = open(
os.path.join(args.output_dir, "VOC2007", "ImageSets", "Main", "val.txt"), 'w')
for i in data_list:
name = os.path.basename(total_xml[i])[:-4] + '\n' # 去掉.xml后缀以及父级目录,只保留文件名
if i in num_trainval:
file_trainval.write(name)
if i in num_train:
file_train.write(name)
else:
file_val.write(name)
else:
file_test.write(name)
file_trainval.close()
file_train.close()
file_val.close()
file_test.close()
if os.path.exists(args.input_dir):
# root 所指的是当前正在遍历的这个文件夹的本身的地址
# dirs 是一个 list,内容是该文件夹中所有的目录的名字(不包括子目录)
# files 同样是 list, 内容是该文件夹中所有的文件(不包括子目录)
for root, dirs, files in os.walk(args.input_dir):
for file in files:
src_file = os.path.join(root, file)
if src_file.endswith(".jpg"):
shutil.copy(src_file, os.path.join(args.output_dir, "VOC2007", "JPEGImages"))
else:
shutil.copy(src_file, os.path.join(args.output_dir, "VOC2007", "Annotations"))
print('| Done!')
if __name__ == "__main__":
print("—" * 50)
xml2voc()
print("—" * 50)
voc转coco
voc2coco.py
import json
import os
import shutil
import datetime
from PIL import Image
from tqdm import trange
root_dir = os.getcwd()
def voc2coco():
# 处理coco数据集中category字段。
# 创建一个 {类名 : id} 的字典,并保存到 总标签data 字典中。
class_name_to_id = {'class1': 1, 'class2': 2, 'class3': 3, 'class4': 4, 'class5': 5, 'class6': 6, 'class7': 7, 'class8': 8} # 改为自己的类别名称,以及对应的类别id
# 创建coco的文件夹
if not os.path.exists(os.path.join(root_dir, "coco")):
os.makedirs(os.path.join(root_dir, "coco"))
os.makedirs(os.path.join(root_dir, "coco", "annotations"))
os.makedirs(os.path.join(root_dir, "coco", "train"))
os.makedirs(os.path.join(root_dir, "coco", "val"))
# 创建 总标签data
now = datetime.datetime.now()
data = dict(
info=dict(
description=None,
url=None,
version=None,
year=now.year,
contributor=None,
date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"),
),
licenses=[dict(url=None, id=0, name=None, )],
images=[
# license, file_name,url, height, width, date_captured, id
],
type="instances",
annotations=[
# segmentation, area, iscrowd, image_id, bbox, category_id, id
],
categories=[
# supercategory, id, name
],
)
for name, id in class_name_to_id.items():
data["categories"].append(
dict(supercategory=None, id=id, name=name, )
)
# 处理coco数据集train中images字段。
images_dir = os.path.join(root_dir, 'VOCdevkit', 'VOC2012', 'JPEGImages')
images = os.listdir(images_dir)
# 生成每个图片对应的image_id
images_id = {}
for idx, image_name in enumerate(images):
images_id.update({image_name[:-4]: idx})
# 获取训练图片
train_img = []
fp = open(os.path.join(root_dir, 'VOCdevkit', 'VOC2012', 'ImageSets', 'Main', 'train.txt'))
for i in fp.readlines():
train_img.append(i[:-1] + ".jpg")
# 获取训练图片的数据
for image in train_img:
img = Image.open(os.path.join(images_dir, image))
data["images"].append(
dict(
license=0,
url=None,
file_name=image, # 图片的文件名带后缀
height=img.height,
width=img.width,
date_captured=None,
# id=image[:-4],
id=images_id[image[:-4]],
)
)
# 获取coco数据集train中annotations字段。
train_xml = [i[:-4] + '.xml' for i in train_img]
bbox_id = 0
for xml in train_xml:
category = []
xmin = []
ymin = []
xmax = []
ymax = []
import xml.etree.ElementTree as ET
tree = ET.parse(os.path.join(root_dir, 'VOCdevkit', 'VOC2012', 'Annotations', xml))
root = tree.getroot()
object = root.findall('object')
for i in object:
category.append(class_name_to_id[i.findall('name')[0].text])
bndbox = i.findall('bndbox')
for j in bndbox:
xmin.append(float(j.findall('xmin')[0].text))
ymin.append(float(j.findall('ymin')[0].text))
xmax.append(float(j.findall('xmax')[0].text))
ymax.append(float(j.findall('ymax')[0].text))
for i in range(len(category)):
data["annotations"].append(
dict(
id=bbox_id,
image_id=images_id[xml[:-4]],
category_id=category[i],
area=(xmax[i] - xmin[i]) * (ymax[i] - ymin[i]),
bbox=[xmin[i], ymin[i], xmax[i] - xmin[i], ymax[i] - ymin[i]],
iscrowd=0,
)
)
bbox_id += 1
# 生成训练集的json
json.dump(data, open(os.path.join(root_dir, 'coco', 'annotations', 'train.json'), 'w'))
# 获取验证图片
val_img = []
fp = open(os.path.join(root_dir, 'VOCdevkit', 'VOC2012', 'ImageSets', 'Main', 'val.txt'))
for i in fp.readlines():
val_img.append(i[:-1] + ".jpg")
# 将训练的images和annotations清空,
del data['images']
data['images'] = []
del data['annotations']
data['annotations'] = []
# 获取验证集图片的数据
for image in val_img:
img = Image.open(os.path.join(images_dir, image))
data["images"].append(
dict(
license=0,
url=None,
file_name=image, # 图片的文件名带后缀
height=img.height,
width=img.width,
date_captured=None,
id=images_id[image[:-4]], # 图片名作为id
)
)
# 处理coco数据集验证集中annotations字段。
val_xml = [i[:-4] + '.xml' for i in val_img]
for xml in val_xml:
category = []
xmin = []
ymin = []
xmax = []
ymax = []
import xml.etree.ElementTree as ET
tree = ET.parse(os.path.join(root_dir, 'VOCdevkit', 'VOC2012', 'Annotations', xml))
root = tree.getroot()
object = root.findall('object')
for i in object:
category.append(class_name_to_id[i.findall('name')[0].text])
bndbox = i.findall('bndbox')
for j in bndbox:
xmin.append(float(j.findall('xmin')[0].text))
ymin.append(float(j.findall('ymin')[0].text))
xmax.append(float(j.findall('xmax')[0].text))
ymax.append(float(j.findall('ymax')[0].text))
for i in range(len(category)):
data["annotations"].append(
dict(
id=bbox_id,
image_id=images_id[xml[:-4]],
category_id=category[i],
area=(xmax[i] - xmin[i]) * (ymax[i] - ymin[i]),
bbox=[xmin[i], ymin[i], xmax[i] - xmin[i], ymax[i] - ymin[i]],
iscrowd=0,
)
)
bbox_id += 1
# 生成验证集的json
json.dump(data, open(os.path.join(root_dir, 'coco', 'annotations', 'val.json'), 'w'))
print('| VOC -> COCO annotations transform finish.')
print('Start copy images...')
# 复制图片
m = len(train_img)
for i in trange(m):
shutil.copy(os.path.join(images_dir, train_img[i]), os.path.join(root_dir, 'coco', 'train', train_img[i]))
print('| Train images copy finish.')
m = len(val_img)
for i in trange(m):
shutil.copy(os.path.join(images_dir, val_img[i]), os.path.join(root_dir, 'coco', 'val', val_img[i]))
print('| Val images copy finish.')
if __name__ == '__main__':
voc2coco()
coco转yolo
coco数据集目录结构:
coco_small
├── train
│ ├── 001.jpg
│ ├── 002.jpg
│ ├── 003.jpg
│ └── ...
│
├── val
│ ├── 004.jpg
│ ├── 005.jpg
│ ├── 006.jpg
│ └── ...
├── test
│ ├── 007.jpg
│ ├── 008.jpg
│ ├── 009.jpg
│ └── ...
│
└── annotatoins
├── train.json
├── val.json
└── test.json
生成的yolo数据集目录:
yolo_dataset
├── images
│ ├── 001.jpg
│ ├── 002.jpg
│ ├── 003.jpg
│ └── ...
│
├── labels
│ ├── 001.txt
│ ├── 002.txt
│ ├── 003.txt
│ └── ...
│
└── ImageSets
├── train.txt
├── val.txt
└── test.txt
将coco的train,val,test分别转换为yolo的train,val,test
coco2yolo.py
# coco是x1,y1,w,h,yolo是x,y,w,h。 x1,y1是左上角坐标,x,y是中心坐标
import os
import shutil
from pycocotools.coco import COCO
from tqdm import trange
root_dir = os.getcwd()
# 将coco的bbox转换为yolo的bbox
def cocobbox2yolobbox(coco_box):
x1, y1, w, h = coco_box
x = x1 + w / 2
y = y1 + h / 2
return [x, y, w, h]
def coco2yolo(dataset_type, json_fp, origin_imgs_dir, save_dir):
imgs_dir = os.path.join(save_dir, 'images')
labels_dir = os.path.join(save_dir, 'labels')
ImageSets_dir = os.path.join(save_dir, 'ImageSets')
if not os.path.exists(save_dir):
os.mkdir(save_dir)
os.mkdir(imgs_dir)
os.mkdir(labels_dir)
os.mkdir(ImageSets_dir)
text_data_fp = os.path.join(ImageSets_dir, dataset_type + '.txt')
text_data = []
coco = COCO(json_fp)
imgs = coco.imgs
img_ids = coco.getImgIds()
m = len(img_ids)
for i in trange(m):
img_id = img_ids[i]
filename = imgs[img_id]['file_name']
text_data.append(os.path.join(imgs_dir, filename))
txt_name = filename.split('.')[0] + ".txt" # 对应的txt名字,与jpg一致
f_txt = open(os.path.join(labels_dir, txt_name), 'w')
ann_ids = coco.getAnnIds(imgIds=img_id)
anns = coco.loadAnns(ann_ids)
for ann in anns:
bbox = cocobbox2yolobbox(ann["bbox"])
f_txt.write("%s %s %s %s %s\n" % (ann['category_id'], bbox[0], bbox[1], bbox[2], bbox[3]))
f_txt.close()
# 将数据集写入文件
with open(text_data_fp, 'w') as f:
for line in text_data:
f.write(line + '\n')
print('labels create done.')
for i in trange(m):
img_id = img_ids[i]
filename = imgs[img_id]['file_name']
shutil.copy(os.path.join(origin_imgs_dir, filename), os.path.join(imgs_dir, filename))
print('images copy done.')
def coco2yolo_type(dataset_type):
save_dir = os.path.join(root_dir, 'yolo_dataset')
if dataset_type == 'train':
json_fp = os.path.join(root_dir, 'coco_small', 'annotations', 'train.json')
imgs_dir = os.path.join(root_dir, 'coco_small', 'train')
coco2yolo(dataset_type, json_fp, imgs_dir, save_dir)
elif dataset_type == 'val':
json_fp = os.path.join(root_dir, 'coco_small', 'annotations', 'val.json')
imgs_dir = os.path.join(root_dir, 'coco_small', 'val')
coco2yolo(dataset_type, json_fp, imgs_dir, save_dir)
elif dataset_type == 'test':
json_fp = os.path.join(root_dir, 'coco_small', 'annotations', 'test.json')
imgs_dir = os.path.join(root_dir, 'coco_small', 'test')
coco2yolo(dataset_type, json_fp, imgs_dir, save_dir)
if __name__ == '__main__':
coco2yolo_type('train')
coco2yolo_type('val')
coco2yolo_type('test')
coco数据集划分为train,val,test
划分前目录结构:
coco
+annotations
+val2017
+split_coco.py
划分后目录结构:
coco_small
+annotations
+train.json
+val.json
+test.json
+train
+val
+test
split_coco.py
# 划分coco数据集
# 将coco数据集分为train和val两个子集
import json
import os
import random
import shutil
from pycocotools.coco import COCO
from tqdm import trange
train_percentage = 0.7
val_percentage = 0.2
root_dir = os.getcwd()
json_fp = os.path.join(root_dir, 'coco', 'annotations', 'instances_val2017.json')
img_dir = os.path.join(root_dir, 'coco', 'val2017')
save_dir = os.path.join(root_dir, 'coco_small')
def split_coco(json_fp, img_dir, save_dir):
json_data = json.load(open(json_fp, 'r'))
coco = COCO(json_fp)
train_dir = os.path.join(save_dir, 'train')
val_dir = os.path.join(save_dir, 'val')
test_dir = os.path.join(save_dir, 'test')
train_json = {'info': json_data['info'], 'licenses': json_data['licenses'], 'images': [], 'annotations': [],
'categories': json_data['categories']}
val_json = {'info': json_data['info'], 'licenses': json_data['licenses'], 'images': [], 'annotations': [],
'categories': json_data['categories']}
test_json = {'info': json_data['info'], 'licenses': json_data['licenses'], 'images': [], 'annotations': [],
'categories': json_data['categories']}
# 创建coco目录结构
if os.path.exists(save_dir):
shutil.rmtree(save_dir)
os.makedirs(save_dir)
os.mkdir(train_dir)
os.mkdir(val_dir)
os.mkdir(test_dir)
os.mkdir(os.path.join(save_dir, 'annotations'))
imgs = coco.imgs
img_ids = coco.getImgIds()
train_ids = random.sample(img_ids, int(len(img_ids) * train_percentage))
val_ids = random.sample(list(set(img_ids) - set(train_ids)), int(len(img_ids) * val_percentage))
m = len(img_ids)
for i in trange(m):
ann_ids = coco.getAnnIds(imgIds=img_ids[i])
if img_ids[i] in train_ids:
train_json['images'].append(imgs[img_ids[i]])
shutil.copy(os.path.join(img_dir, imgs[img_ids[i]]['file_name']),
os.path.join(train_dir, imgs[img_ids[i]]['file_name']))
for ann_id in ann_ids:
train_json['annotations'].append(coco.anns[ann_id])
elif img_ids[i] in val_ids:
val_json['images'].append(imgs[img_ids[i]])
shutil.copy(os.path.join(img_dir, imgs[img_ids[i]]['file_name']),
os.path.join(val_dir, imgs[img_ids[i]]['file_name']))
for ann_id in ann_ids:
val_json['annotations'].append(coco.anns[ann_id])
else:
test_json['images'].append(imgs[img_ids[i]])
shutil.copy(os.path.join(img_dir, imgs[img_ids[i]]['file_name']),
os.path.join(test_dir, imgs[img_ids[i]]['file_name']))
for ann_id in ann_ids:
test_json['annotations'].append(coco.anns[ann_id])
with open(os.path.join(save_dir, 'annotations', 'train.json'), 'x') as f:
json.dump(train_json, f)
with open(os.path.join(save_dir, 'annotations', 'val.json'), 'x') as f:
json.dump(val_json, f)
with open(os.path.join(save_dir, 'annotations', 'test.json'), 'x') as f:
json.dump(test_json, f)
if __name__ == '__main__':
split_coco(json_fp, img_dir, save_dir)
print('done')
coco数据集图片检查
check_coco.py
# 检查coco数据集每张图片能否打开
import os
import cv2
from pycocotools.coco import COCO
from tqdm import trange
root_dir = os.getcwd()
def check_coco(json_fp, img_dir):
coco = COCO(json_fp)
imgs = coco.imgs
img_ids = coco.getImgIds()
for i in trange(len(img_ids)):
img_fp = os.path.join(img_dir, imgs[img_ids[i]]['file_name'])
img = cv2.imread(img_fp)
try:
img.shape
except:
print(img_fp)
if __name__ == '__main__':
json_fp = os.path.join(root_dir, 'coco', 'annotations', 'instances_val2017.json')
img_dir = os.path.join(root_dir, 'coco', 'val2017')
check_coco(json_fp, img_dir)
print('done')
yolo数据集图片检查
check_yolo.py
# 检查yolo数据集每张图片能否打开
import os
import cv2
from tqdm import trange
root_dir = os.getcwd()
def check_coco(txt_fp):
imgs = []
with open(txt_fp, 'r') as f:
for line in f:
imgs.append(line.strip())
for i in trange(len(imgs)):
img = cv2.imread(imgs[i])
try:
s = img.shape
except:
print(imgs[i])
if __name__ == '__main__':
txt_fp = os.path.join(root_dir, 'yolo_dataset', 'annotations', 'train.txt')
check_coco(txt_fp)
print('done')
coco数据集bbox可视化
visiual_coco.py
import os
import random
import cv2
from pycocotools.coco import COCO
from tqdm import trange
root_dir = os.getcwd()
# 检查转变后coco的json文件,坐标是否正确。
def visiual_coco(json_fp, images_dir):
coco = COCO(json_fp)
imgs = coco.imgs
img_ids = coco.getImgIds()
cats = coco.cats
random.shuffle(img_ids)
for i in trange(len(img_ids)):
img_fp = os.path.join(images_dir, imgs[img_ids[i]]['file_name'])
img = cv2.imread(img_fp)
ann_ids = coco.getAnnIds(imgIds=img_ids[i])
anns_ = coco.loadAnns(ann_ids)
for ann in anns_:
bbox = ann['bbox']
left_top = (int(bbox[0]), int(bbox[1])) # coco数据集中bbox的含义是x1,y1,w,h
right_bottom = (int(bbox[0]) + int(bbox[2]), int(bbox[1]) + int(bbox[3]))
cv2.rectangle(img, left_top, right_bottom, (0, 255, 0), 2) # 图像,左上角,右下坐标,颜色,粗细
cv2.putText(img, cats[ann['category_id']]['name'], left_top, cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
json_fp = os.path.join(root_dir, 'coco', 'annotations', 'instances_val2017.json')
images_dir = os.path.join(root_dir, 'coco', 'val2017')
visiual_coco(json_fp, images_dir)
xml转voc,voc转coco,coco转yolo,coco划分,coco检查,yolo检查,coco可视化的更多相关文章
- 训练自己数据-xml文件转voc格式
首先我们有一堆xml文件 笔者是将mask-rcnn得到的json标注文件转为xml的 批量json转xml方法:https://www.cnblogs.com/bob-jianfeng/p/1112 ...
- COCO数据集深入理解
TensorExpand/TensorExpand/Object detection/Data_interface/MSCOCO/ 深度学习数据集介绍及相互转换 Object segmentation ...
- [PocketFlow]解决TensorFLow在COCO数据集上训练挂起无输出的bug
1. 引言 因项目要求,需要在PocketFlow中添加一套PeleeNet-SSD和COCO的API,具体为在datasets文件夹下添加coco_dataset.py, 在nets下添加pelee ...
- Microsoft COCO 数据集
本篇博客主要以介绍MS COCO数据集为目标,分为3个部分:COCO介绍,数据集分类和COCO展示. 本人主要下载了其2014年版本的数据,一共有20G左右的图片和500M左右的标签文件.标签文件标记 ...
- COCO 数据集的使用
Windows 10 编译 Pycocotools 踩坑记 COCO数据库简介 微软发布的COCO数据库, 除了图片以外还提供物体检测, 分割(segmentation)和对图像的语义文本描述信息. ...
- 自制 COCO api 直接读取类 COCO 的标注数据的压缩文件
第6章 COCO API 的使用 COCO 数据库是由微软发布的一个大型图像数据集,该数据集专为对象检测.分割.人体关键点检测.语义分割和字幕生成而设计.如果你要了解 COCO 数据库的一些细节,你可 ...
- COCO 数据集使用说明书
下面的代码改写自 COCO 官方 API,改写后的代码 cocoz.py 被我放置在 Xinering/cocoapi.我的主要改进有: 增加对 Windows 系统的支持: 替换 defaultdi ...
- 《Microsoft COCO Captions Data Collection and Evaluation Server》论文笔记
出处:CVPR2015 Motivation 本文描述了MSCoco标题数据集及评估服务器(Microsoft COCO Caption dataset and evaluation server), ...
- coco标注信息与labelme标注信息的详解、相互转换及可视化
引言 在做实例分割或语义分割的时候,我们通常要用labelme进行标注,labelme标注的json文件与coco数据集已经标注好的json文件的格式和内容有差异.如果要用coco数据集的信息,就要对 ...
- 解决 Jumpserver coco 使用登录用户(ldap)进行SSH连接目标主机,忽略系统用户
前言 Jumpserver 作为国内流行的开源堡垒机,很多公司都在尝试使用,同时 Jumpserver 为了契合众多公司的用户认证,也提供了 LDAP 的用户认证方式,作为 Jumpserver 的用 ...
随机推荐
- Python列表转换成字典、嵌套列表转字典、多个列表转为字典嵌套列表
目录 两列表转为字典 多列表转为字典嵌套列表 嵌套列表转字典 方法一:直接内置dict 方法二: for循环 一个列表转字典 两列表转为字典 list1=["key1"," ...
- CPNtools协议建模-----门卫过滤两种帧存储方式
1.门卫过滤作用 两种帧格式定义方式的过滤 ,第一种方式 数据存储定义格什为 colset frame=product MAC *MAC*DATA 第二种数据帧存储格式定义为 colse ...
- .Net下的简易Http请求调用(Post与Get)
http请求调用是开发中经常会用到的功能.在内,调用自有项目的Web Api等形式接口时会用到:在外,调用一些第三方功能接口时,也会用到,因为,这些第三方功能往往是通过http地址的形式提供的,比如: ...
- Zabbix6.0使用教程 (三)—zabbix6.0的安装要求
接上篇,我们继续为大家详细介绍zabbix6.0的使用教程之zabbix6.0的安装部署.接下来我们将从zabbix部署要求到四种不同的安装方式逐一详细的为大家介绍.本篇讲的是部署zabbix6.0的 ...
- sign 单词学习 - 本质:去分开
sign 英[saɪn],美[saɪn] n. 符号; 指示牌; 手势; 征兆; 正负号; 星座 v. 签名; 签约; 打手语 词源说明(童理民) sign : 来自拉丁语signum,符号,标志,图 ...
- vscode sftp 代码同步到服务器
然后执行 ctrl+shift+p ,搜索 SFTP:Config 回车后,会生成一个".vscode/sftp.json",这个就是配置文件 参考:VsCode SFTP插件详细 ...
- python学习笔记(4):面向对象
面向对象 定义 class Student(被继承类): def __init__(self, xx, xxx): #构造函数 类方法的第一个参数一定是self.除此之外和普通函数并没有区别.同样可以 ...
- Mysql存储引擎MyIsAM和InnoDB区别
Mysql 数据库中,最常用的两种引擎是innordb 和myisam.InnoDB 是Mysql 的默认存储引擎. 两者的区别: 1.事务处理上方面MyISAM:强调的是性能,查询的速度比InnoD ...
- 三维模型3DTile格式轻量化压缩处理重难点分析
三维模型3DTile格式轻量化压缩处理重难点分析 在对三维模型3DTile格式进行轻量化压缩处理的过程中,存在一些重要而又困难的问题需要解决.以下是几个主要的重难点: 1.压缩率和模型质量之间的平衡: ...
- 记录-关于console你不知道的那些事
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 了解 console ● 什么是 console ? console 其实是 JavaScript 内的一个原生对象 内部存储的方法大部分 ...