平常用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可视化的更多相关文章

  1. 训练自己数据-xml文件转voc格式

    首先我们有一堆xml文件 笔者是将mask-rcnn得到的json标注文件转为xml的 批量json转xml方法:https://www.cnblogs.com/bob-jianfeng/p/1112 ...

  2. COCO数据集深入理解

    TensorExpand/TensorExpand/Object detection/Data_interface/MSCOCO/ 深度学习数据集介绍及相互转换 Object segmentation ...

  3. [PocketFlow]解决TensorFLow在COCO数据集上训练挂起无输出的bug

    1. 引言 因项目要求,需要在PocketFlow中添加一套PeleeNet-SSD和COCO的API,具体为在datasets文件夹下添加coco_dataset.py, 在nets下添加pelee ...

  4. Microsoft COCO 数据集

    本篇博客主要以介绍MS COCO数据集为目标,分为3个部分:COCO介绍,数据集分类和COCO展示. 本人主要下载了其2014年版本的数据,一共有20G左右的图片和500M左右的标签文件.标签文件标记 ...

  5. COCO 数据集的使用

    Windows 10 编译 Pycocotools 踩坑记 COCO数据库简介 微软发布的COCO数据库, 除了图片以外还提供物体检测, 分割(segmentation)和对图像的语义文本描述信息. ...

  6. 自制 COCO api 直接读取类 COCO 的标注数据的压缩文件

    第6章 COCO API 的使用 COCO 数据库是由微软发布的一个大型图像数据集,该数据集专为对象检测.分割.人体关键点检测.语义分割和字幕生成而设计.如果你要了解 COCO 数据库的一些细节,你可 ...

  7. COCO 数据集使用说明书

    下面的代码改写自 COCO 官方 API,改写后的代码 cocoz.py 被我放置在 Xinering/cocoapi.我的主要改进有: 增加对 Windows 系统的支持: 替换 defaultdi ...

  8. 《Microsoft COCO Captions Data Collection and Evaluation Server》论文笔记

    出处:CVPR2015 Motivation 本文描述了MSCoco标题数据集及评估服务器(Microsoft COCO Caption dataset and evaluation server), ...

  9. coco标注信息与labelme标注信息的详解、相互转换及可视化

    引言 在做实例分割或语义分割的时候,我们通常要用labelme进行标注,labelme标注的json文件与coco数据集已经标注好的json文件的格式和内容有差异.如果要用coco数据集的信息,就要对 ...

  10. 解决 Jumpserver coco 使用登录用户(ldap)进行SSH连接目标主机,忽略系统用户

    前言 Jumpserver 作为国内流行的开源堡垒机,很多公司都在尝试使用,同时 Jumpserver 为了契合众多公司的用户认证,也提供了 LDAP 的用户认证方式,作为 Jumpserver 的用 ...

随机推荐

  1. BeanShell 如何加密加签?

    一 首先我们要搞清楚接口签名步骤: **第一步:初步实现接口****第二步:找开发拿到算法和key** * key:sAHDRNJg0ZevmEn7HwBfbw== * 算法:HmacMD5 咱们就找 ...

  2. Android学习之文件存储

    •前言 任何一个应用程序,其实说白了就是在不停地和数据打交道,我们聊QQ.看新闻.刷微博,所关心的都是里面的数据, 没有数据的应用程序就变成了一个空壳子,对用户来说没有任何实际用途. 那么这些数据都是 ...

  3. Spring事务(六)-只读事务

    @Transactional(readOnly=true)就可以把事务方法设置成只读事务.设置了只读事务,事务从开始到结束,将看不见其他事务所提交的数据.这在某种程度上解决了事务并发的问题.一个方法内 ...

  4. import.meta.globEager('./src/components/**/*.vue'); 遍历文件

    main.js const importAll = (modules) => { Object.keys(modules).forEach((key) => { const compone ...

  5. Client请求外部接口标准处理方式

    简单记录下client外部请求代码的我认为比较标准的书写格式 public List<GdtDailyBalanceReportAO> getGdtDailyReportList2(Lon ...

  6. 初探修模的三维模型OBJ格式轻量化压缩的遇到常见问题与处理方法

    初探修模的三维模型OBJ格式轻量化压缩的遇到常见问题与处理方法 在对经过修模的三维模型进行OBJ格式轻量化压缩处理的过程中,可能会遇到一些常见问题.以下是一些常见问题以及相应的处理方法: 1.顶点丢失 ...

  7. 记录--npm, npx, cnpm, yarn, pnpm梭哈

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 依赖管理解决了在软件开发过程中管理和协调各种依赖项的问题,简化了开发流程,提高了项目的可靠性.可维护性和可重复性.它们帮助开发人员更高效地 ...

  8. base64格式上传图片后台写入

    前台 var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function(e){//回调 } 后台 ...

  9. Linux基础操作一

    开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 开启虚拟机→Username:root→Password:"(注册时所创建的密码,比如"123 ...

  10. KingbaseES V8R6集群部署案例之---脚本部署节点环境检查故障

    KingbaseES V8R6集群部署案例之---脚本部署节点环境检查故障 案例说明: KingbaseES V8R6集群在部署前会对集群节点系统环境进行检测,检测失败后,将中断部署:其中一个检测项, ...