痤疮分类-yolov5 学习过程

实验思路:

实验任务是实现痤疮分类任务,并嵌入在PyQT上。

在目标检测、语义分割、实例分割面前我们选择了目标检测的yolov5.但是我们json文件的标注框全是多边形的,通过脚本文件将json文件转化为yolo模型能够识别的标注框为矩形的txt文件。实验结果的mAPI只有不到20%。所以还需要研究。

在PyQt方面,本来想把实验产生的结果图片显示在PyQt上的,但是目标是痤疮,检测出来的标注信息实在太小看不清楚,所以只是在PyQt上显示了文本信息,并且给出结果图片的生成路径。

实验过程

1、在github上下载yolov5-5.0的源码。

GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite

2、制作数据集

借鉴:

Yolov5 多边形标签转换,所有json文件自动转成txt格式[详细过程]_json格式转txt格式_Pandas_007的博客-CSDN博客

yolov5的数据集要求:

数据集文件夹结构

mydata:

接受的文件:

类型:txt文件,

检测框类型:四边形

原始数据集格式

文件夹内:

 json文件内:
{
  "version": "4.5.6",
  "flags": {},
  "shapes": [
    {
      "label": "papule",
      "points": [
        [
          1345.0132018448694,
          2377.567482115941
        ],
        [
          1324.995411499284,
          2388.9108966451063
        ],
        [
          1324.995411499284,
          2390.2454160014786
        ],
        [
          1324.995411499284,
          2392.2471950360373
        ],
        [
          1324.995411499284,
          2393.5817143924096
        ],
        [
          1324.995411499284,
          2394.916233748782
        ],
        [
          1328.3317098902148,
          2416.9358031289257
        ],
        [
          1328.998969568401,
          2420.2721015198567
        ],
        [
          1330.3334889247735,
          2422.2738805544154
        ],
        [
          1330.3334889247735,
          2423.6083999107877
        ],
        [
          1331.0007486029597,
          2425.6101789453464
        ],
        [
          1357.691135730407,
          2437.6208531526977
        ],
        [
          1359.0256550867794,
          2437.6208531526977
        ],
        [
          1361.0274341213378,
          2437.6208531526977
        ],
        [
          1361.694693799524,
          2436.2863337963254
        ],
        [
          1363.0292131558963,
          2434.951814439953
        ],
        [
          1381.7124841451096,
          2412.932245059809
        ],
        [
          1381.7124841451096,
          2411.5977257034365
        ],
        [
          1381.7124841451096,
          2410.263206347064
        ],
        [
          1381.7124841451096,
          2408.928686990692
        ],
        [
          1379.7107051105509,
          2406.926907956133
        ],
        [
          1379.0434454323647,
          2404.9251289215745
        ],
        [
          1366.3655115468273,
          2391.579935357851
        ],
        [
          1365.030992190455,
          2390.912675679665
        ],
        [
          1363.6964728340827,
          2390.2454160014786
        ],
        [
          1362.3619534777101,
          2389.5781563232927
        ]
      ],
      "group_id": null,
      "shape_type": "polygon",
      "flags": {}
    },
检测框类型:

标注的检测框为多边形

json文件标注信息:

Labelme是一种常用的开源工具,用于图像标注和语义分割任务。它的标注数据以JSON格式存储,下面是对Labelme标注的JSON格式的解释:

Labelme的JSON文件包含了图像的标注信息,通常包括以下主要字段:

1、"version": 标注数据的版本号。
2、"flags": 可选字段,用于存储标注的一些标志或注释。
3、"shapes": 包含一个数组,每个元素表示一个标注的形状。

"label": 标注的类别或标签名称。
"points": 形状的顶点坐标列表。对于矩形,可以使用四个顶点坐标来表示。
"group_id": 可选字段,用于标识形状所属的组。
"shape_type": 形状的类型,如"rectangle"表示矩形,"polygon"表示多边形等。
"flags": 可选字段,用于存储形状的一些标志或注释。
"imagePath": 图像文件的路径或名称。
4、"imageData": 图像的原始数据,可以是Base64编码的图像数据。

5、"imageHeight": 图像的高度。

6、"imageWidth": 图像的宽度。

7、"imageDepth": 图像的通道数,通常为3(RGB图像)或1(灰度图像)。

这些是Labelme标注的JSON格式的主要字段和解释。通过解析JSON文件,可以提取出图像的标注信息,以便进行后续的处理和分析。

每个points是有很多歌列表组成,其中每个列表由两个数组成,怎么解释:

在Labelme的JSON格式中,"points"字段表示标注形状的顶点坐标列表。每个"points"列表由两个数组组成,其中每个数组表示一个点的坐标。

具体而言,每个"points"列表由一系列的点组成,每个点由两个值构成,通常是(x, y)坐标。这些点按照顺序连接起来,形成一个封闭的多边形或者一个线段。

例如,对于一个矩形的标注,可以使用四个点的坐标来表示。在"points"字段中,会有一个包含四个列表的数组,每个列表由两个值组成,表示一个点的坐标。这些点按照顺序连接起来,形成一个矩形的边界。

对于多边形的标注,"points"字段中的数组会包含多个列表,每个列表由两个值表示一个点的坐标。这些点按照顺序连接起来,形成一个封闭的多边形。

总之,"points"字段中的每个列表由两个数组组成,表示一个点的坐标,这些点按照顺序连接起来形成一个形状的边界或轮廓。

 提取有用的文件

       根据labelme_20220329文件夹中的文件名找到image文件夹下同名的图片文件,并将其存放在新的文件夹中:

import os
import shutil

# 指定存放一堆JSON文件的文件夹路径和存放图片的文件夹路径
json_folder = 'labelme_20220329'
image_folder = 'image'

# 指定新创建的文件夹路径用于存放找到的图片
output_folder = 'found_images'
os.makedirs(output_folder, exist_ok=True)

# 遍历labelme_20220329文件夹中的所有文件
for filename in os.listdir(json_folder):
    json_path = os.path.join(json_folder, filename)
    
    # 提取文件名(不包含扩展名)
    file_name = os.path.splitext(filename)[0]
    
    # 构造对应的图片文件路径
    image_path = os.path.join(image_folder, file_name + '.jpg')  # 假设图片扩展名为.jpg
    
    # 如果图片文件存在,则将其复制到新创建的文件夹中
    if os.path.exists(image_path):
        shutil.copy(image_path, output_folder)

json文件转为txt文件

参考文章:

Yolov5 多边形标签转换,所有json文件自动转成txt格式[详细过程]_json格式转txt格式_Pandas_007的博客-CSDN博客

检测框由多边形转为矩形

#处理labelme多边形矩阵的标注  json转化txt
import json
import os
name2id={'closed_comedo':0,'opend_comedo':1,'papule':2,'pustule':3,'nodule':4,'atrophic_scar':5,'hypertrophic_scar':6,'melasma':7,'nevus':8,'other':9}
 
def convert(img_size, box):
    dw = 1. / (img_size[0])
    dh = 1. / (img_size[1])
    x = (box[0] + box[2]) / 2.0 
    y = (box[1] + box[3]) / 2.0 
    w = abs(box[2] - box[0])
    h = abs(box[3] - box[1])
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)
 
def decode_json(json_floder_path,txt_outer_path, json_name):
    txt_name = os.path.join(txt_outer_path, json_name[:-5] + '.txt')
    with open(txt_name,'w') as f:
        json_path = os.path.join(json_floder_path, json_name)#os路径融合
        data = json.load(open(json_path, 'r', encoding='gb2312',errors='ignore'))
        img_w = data['imageWidth']#图片的高
        img_h = data['imageHeight']#图片的宽
        isshape_type=data['shapes'][0]['shape_type']
        print(isshape_type)
        #print(isshape_type)
        #TODO print('下方判断根据这里的值可以设置为你自己的类型,我这里是polygon'多边形)
        for i in data['shapes']:
            label_name = i['label']#得到json中你标记的类名
            if (i['shape_type'] == 'polygon'):#数据类型为多边形 需要转化为矩形
                x_max=0
                y_max=0
                x_min=100000
                y_min=100000
                for lk in range(len(i['points'])):
                    x1=float(i['points'][lk][0])
                    y1=float(i['points'][lk][1])
                   # print(x1)
                    if x_max<x1:
                        x_max=x1
                    if y_max<y1:
                        y_max=y1
                    if y_min>y1:
                        y_min=y1
                    if x_min>x1:
                        x_min=x1
                bb = (x_min, y_max, x_max, y_min)
            if (i['shape_type'] == 'rectangle'):#为矩形不需要转换
                x1 = float(i['points'][0][0])
                y1 = float(i['points'][0][1])
                x2 = float(i['points'][1][0])
                y2 = float(i['points'][1][1])
                bb = (x1, y1, x2, y2)
            bbox = convert((img_w, img_h), bb)
            try:
                f.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n')
            except:
                pass
 
if __name__ == "__main__":
    json_floder_path = './labelme_20220329'#存放json的文件夹的绝对路径
    txt_outer_path='./labelme_txt'#存放txt的文件夹绝对路径
    json_names = os.listdir(json_floder_path)
    print("共有:{}个文件待转化".format(len(json_names)))
    flagcount=0
    for json_name in json_names:
        decode_json(json_floder_path,txt_outer_path,json_name)
        flagcount+=1
        print("还剩下{}个文件未转化".format(len(json_names)-flagcount))
       # break
    print('转化全部完毕')

将整个数据集化为9:1比例的训练集和测试集

split_data.py

import os
import random
import shutil

# 设置文件夹路径和划分比例
image_folder = "images"
label_folder = "labelme_txt"
train_folder = "train"
test_folder = "test"
split_ratio = 0.9

# 创建目标文件夹
os.makedirs(os.path.join(train_folder, "images"), exist_ok=True)
os.makedirs(os.path.join(train_folder, "labels"), exist_ok=True)
os.makedirs(os.path.join(test_folder, "images"), exist_ok=True)
os.makedirs(os.path.join(test_folder, "labels"), exist_ok=True)

# 获取图片文件列表
image_files = os.listdir(image_folder)

# 随机打乱文件列表
random.shuffle(image_files)

# 计算划分的索引
split_index = int(len(image_files) * split_ratio)

# 划分并移动文件到相应的文件夹
for i, image_file in enumerate(image_files):
    image_path = os.path.join(image_folder, image_file)
    label_file = image_file.replace(".jpg", ".txt")
    label_path = os.path.join(label_folder, label_file)

    if i < split_index:
        # 移动到训练集文件夹
        shutil.move(image_path, os.path.join(train_folder, "images", image_file))
        shutil.move(label_path, os.path.join(train_folder, "labels", label_file))
    else:
        # 移动到测试集文件夹
        shutil.move(image_path, os.path.join(test_folder, "images", image_file))
        shutil.move(label_path, os.path.join(test_folder, "labels", label_file))

3、结果显示调整

借鉴文章:

yolov5/v7修改标签和检测框显示【最全】_plots.py中的box_label函数-CSDN博客

都在plots.py文件中修改

def plot_one_box(x, img, color=None, label=None, line_thickness=3):
    # Plots one bounding box on image img
    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness
    color = color or [random.randint(0, 255) for _ in range(3)]
    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
    ################################################################################
    # cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'closed_comedo' in label:
        color = (242,140,165)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'opend_comedo' in label:
        color = (157, 217, 165)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'papule' in label:
        color = (255, 240, 140)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'pustule' in label:
        color = (161, 177, 235)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'nodule' in label:
        color = (250, 192, 152)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'atrophic_scar' in label:
        color = (200, 142, 217)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'hypertrophic_scagr' in label:
        color = (160, 233, 249)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'melasma' in label:
        color = (247, 152, 242)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'nevus' in label:
        color = (223, 247, 162)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if 'other' in label:
        color = (252, 222, 233)
        cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    ################################################################################
    if label:
        tf = max(tl - 1, 1)  # font thickness
        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
        ################################################################################
        # cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
        # cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
        ################################################################################
        cv2.putText(img, label, (c1[0], c1[1] - 12), 0, tl / 3, color, thickness=tf, lineType=cv2.LINE_AA)

4、计数

参考文章:

YOLOv5实现目标分类计数并显示在图像上_图像识别计数-CSDN博客

YOLOv5实现目标计数_yolov5计数_Albert_yeager的博客-CSDN博客

查找'cup'names列表中的索引:

names = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
         'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
         'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
         'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
         'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
         'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
         'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
         'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
         'hair drier', 'toothbrush']

cup_index = names.index('cup')
print(cup_index)

各类别计数:

在detect.py里修改,如果要嵌入PyQt,则直接在当时界面的后端里面修改,因为我的detect.py文件直接嵌入在了enterTest3.py文件中。

               ############################################################################################
                # Write results+计数
                # count=0
                # person_count = 0
                # cup_count = 0
                closed_comedo_count = 0
                opend_comedo_count = 0
                papule_count = 0
                pustule_count = 0
                nodule_count = 0
                atrophic_scar_count = 0
                hypertrophic_scar_count = 0
                melasma_count = 0
                nevus_count = 0
                other_count = 0
                for *xyxy, conf, cls in reversed(det):
                    if save_txt:  # Write to file
                        xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh
                        line = (cls, *xywh, conf) if opt.save_conf else (cls, *xywh)  # label format
                        with open(txt_path + '.txt', 'a') as f:
                            f.write(('%g ' * len(line)).rstrip() % line + '\n')

                    if save_img or view_img:  # Add bbox to image
                        #c = int(cls)# integer class分类数
                        #label = '%s %.2f  num: %d' % (names[int(cls)], conf, person_count)
                        label = f'{names[int(cls)]} {conf:.2f}'
                        plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
                    ##########################分类计数##########################
                        # if int(cls) == 0:
                        #     person_count += 1
                        # if int(cls) == 41:
                        #     cup_count += 1
                        if int(cls) == 0:
                            closed_comedo_count += 1
                        if int(cls) == 1:
                            opend_comedo_count += 1
                        if int(cls) == 2:
                            papule_count += 1
                        if int(cls) == 3:
                            pustule_count += 1
                        if int(cls) == 4:
                            nodule_count += 1
                        if int(cls) == 5:
                            atrophic_scar_count += 1
                        if int(cls) == 6:
                            hypertrophic_scar_count += 1
                        if int(cls) == 7:
                            melasma_count += 1
                        if int(cls) == 8:
                            nevus_count += 1
                        if int(cls) == 9:
                            other_count += 1
                        # count = count+1
                ############################################################################################

结果显示的修改

            if view_img:
                ##############################视频识别显示计数内容####################################
                text = 'person_num:%d ' % (person_count)
                cv2.putText(im0, text, (180, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)
                text = 'cup_num:%d ' % (cup_count)
                cv2.putText(im0, text, (180, 120), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 5)
                ####################################################################################
                cv2.imshow(str(p), im0)
                cv2.waitKey(1)  # 1 millisecond

            # Save results (image with detections)
            if save_img:
                ##############################视频识别显示计数内容####################################
                # text = 'person_num:%d ' % (person_count)
                # cv2.putText(im0, text, (180, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.2, (0, 0, 255), 2)
                # print(text)
                # text = 'cup_num:%d ' % (cup_count)
                # cv2.putText(im0, text, (180, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.2, (255, 0, 0), 2)
                # print(text)
                text = 'closed_comedo_count:%d ' % (closed_comedo_count)
                cv2.putText(im0, text, (180, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'opend_comedo_count:%d ' % (opend_comedo_count)
                cv2.putText(im0, text, (180, 120), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'papule_count:%d ' % (papule_count)
                cv2.putText(im0, text, (180, 190), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'pustule_count:%d ' % (pustule_count)
                cv2.putText(im0, text, (180, 260), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'nodule_count:%d ' % (nodule_count)
                cv2.putText(im0, text, (180, 330), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'atrophic_scar_count:%d ' % (atrophic_scar_count)
                cv2.putText(im0, text, (180, 400), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'hypertrophic_scar_count:%d ' % (hypertrophic_scar_count)
                cv2.putText(im0, text, (180, 470), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'melasma_count:%d ' % (melasma_count)
                cv2.putText(im0, text, (180, 540), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'nevus_count:%d ' % (nevus_count)
                cv2.putText(im0, text, (180, 610), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                text = 'other_count:%d ' % (other_count)
                cv2.putText(im0, text, (180, 680), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
                print(text)
                ####################################################################################
                if dataset.mode == 'image':
                    cv2.imwrite(save_path, im0)
                else:  # 'video' or 'stream'
                    if vid_path != save_path:  # new video
                        vid_path = save_path
                        if isinstance(vid_writer, cv2.VideoWriter):
                            vid_writer.release()  # release previous video writer
                        if vid_cap:  # video
                            fps = vid_cap.get(cv2.CAP_PROP_FPS)
                            w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
                            h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
                        else:  # stream
                            fps, w, h = 30, im0.shape[1], im0.shape[0]
                            save_path += '.mp4'
                        vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
                    vid_writer.write(im0)

这将输出48,表示'cup'names列表中的索引为48

5、yolov5可视化训练结果以及result.txt解析:

参考文献:

yolov5的训练过程中的打印信息“P”,"R","mAP@.5","mAP@.5:.95:100%"是什么意思:
  1. "P":这个指标表示精确率(Precision),即检测到的目标中真实目标的比例。它是通过计算模型预测的正样本中真实目标的比例得到的。

  2. "R":这个指标表示召回率(Recall),即成功检测到的目标在所有真实目标中的比例。它是通过计算模型成功检测到的正样本在所有真实正样本中的比例得到的。

  3. "mAP@.5":这个指标表示在IoU阈值为0.5时的平均精确率(mean Average Precision)。它是通过计算每个类别在IoU阈值为0.5时的Average Precision(AP),然后对所有类别的AP进行平均得到的。

  4. "mAP@.5:.95:100%":这个指标表示在IoU阈值从0.5到0.95以及步长为0.05的范围内的平均精确率。它是通过计算每个类别在不同IoU阈值下的AP,并在整个范围内进行插值得到的。

result.txt解析

yolov5-3.1中train.py第322行有如下的代码

# Write
with open(results_file, 'a') as f:
	f.write(s + '%10.4g' * 7 % results + '\n')  # P, R, mAP@.5, mAP@.5-.95, val_loss(box, obj, cls)
if len(opt.name) and opt.bucket:
	os.system('gsutil cp %s gs://%s/results/results%s.txt' % (results_file, opt.bucket, opt.name))

这部分代码应该是把每次迭代结果写入result.txt

根据相应注释可推测result.txt中

倒数第7列至倒数第4列是每次迭代后相应的Precision、Recall、mAP@0.5、mAP@0.5:0.95

6、PyQt

借鉴文章:

7、Jupyter

在Jupyter里压缩文件

# 压缩当前路径所有文件,输出zip文件
path='./autodl-tmp'

import zipfile,os
zipName = 'yolov5_learn.zip' #压缩后文件的位置及名称
f = zipfile.ZipFile( zipName, 'w', zipfile.ZIP_DEFLATED )
for dirpath, dirnames, filenames in os.walk(path):
    for filename in filenames:
        print(filename)
        f.write(os.path.join(dirpath,filename))
f.close()

完整代码

链接:https://pan.baidu.com/s/1F8Nme9Tawnil0FGb4dQhQg 
提取码:jr27

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/193808.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MidJourney笔记(4)-settings

前面已经大概介绍了MidJourney的基础知识,后面我主要是基于实操来分享自己的笔记。可能内容顺序会有点乱,请大家理解。 这次主要是想讲讲settings这个命令。我们只需在控制台输入/settings,然后回车,就可以执行这个命令。 (2023年11月26日版本界面) 可能有些朋友出来的界…

Git的原理与使用(一):Git的基本操作(包含:版本回退)

Git原理与使用一 一.Git的初识与安装1.什么是Git2.如何安装Git1.git命令与git help(Git下的"man手册")2.centos下安装Git3.ubantu下安装Git 二.Git的前置操作与前置知识1.创建Git本地仓库2.配置Git3.理解Git的分区1.工作区2.暂存区3.版本库4.分区关系总结 三.添加文件…

【电路笔记】-快速了解电阻

快速了解电阻 文章目录 快速了解电阻1、概述2、电阻器的组成类型2.1 碳电阻器2.2 薄膜电阻器2.3 绕线电阻器 3、总结 电阻器是所有电子元件中最基本、最常用的元件&#xff0c;人们几乎认为电阻器是理所当然的&#xff0c;但它们在电路中起着至关重要的作用。 1、概述 有许多不…

uniapp基础-教程之HBuilderX基础常识篇02

uniapp创建项目时属性多为vue后缀&#xff1b;其中每个文件中都包含了三段式结构分别是template&#xff1b;script&#xff1b;style形势&#xff0c;分别是前端显示的画面以及js和css样式。 template&#xff1a;说大白话就是给别人看的&#xff0c;我们打开页面就可以看到的…

一维数组传参的本质

一维数组传参的本质 数组我们之前学过了&#xff0c;之前也讲了&#xff0c;数组是可以传递给函数的&#xff0c;这个小节我们讨论一下数组传参的本质。 首先&#xff0c;我们从一个问题开始&#xff0c;我们之前都是在函数外部计算数组的元素个数&#xff0c;那我们可以把函…

【C++】多态(上) 多态 | 虚函数 | 重写 | final、override | 接口继承与实现继承 | 抽象类

一、多态 概念 多态&#xff0c;就是多种状态&#xff0c;即不同的对象去完成同一个行为时会产生出不同的状态。比如&#xff1a;买票时&#xff0c;成人要原价买&#xff0c;学生和老人就可以享受优惠价便宜一点儿。同样是买票这个行为&#xff0c;不同的对象来做就有不同的…

【brpc学习实践九】mbvar及bvar可观测

概念、学习地址 mbvar中有两个类&#xff0c;分别是MVariable和MultiDimension&#xff0c;MVariable是多维度统计的基类&#xff0c;MultiDimension是派生模板类。也是主要用来多多线程计数用的。这里用到再详细去了解即可 https://github.com/luozesong/brpc/blob/master/do…

231127 刷题日报

这周值班。。多少写道题吧&#xff0c;保持每天的手感。老婆给买了lubuladong纸质书&#xff0c;加油卷。 1. 131. 分割回文串 写个这个吧&#xff0c;钉在耻辱柱上的题。 为啥没写出来&#xff1a; 1. 递归树没画对 把树枝只看做是1个字母&#xff0c;而且不清楚树枝和节点…

JAVA:深入探讨String性能优化让你的程序更高效

1、简述 在现代软件开发中&#xff0c;字符串&#xff08;String&#xff09;是一个不可或缺的数据类型&#xff0c;几乎每个应用程序都在某种程度上使用字符串。然而&#xff0c;由于字符串操作的频繁性质&#xff0c;它们可能成为程序性能的瓶颈之一。在本文中&#xff0c;我…

【vue】a-table的斑马纹以及hover样式的修改:

文章目录 一、效果&#xff1a;二、实现&#xff08;以jeecg为例&#xff09;&#xff1a; 一、效果&#xff1a; 二、实现&#xff08;以jeecg为例&#xff09;&#xff1a; // 设置基数行样式 // .ant-table-tbody tr:nth-child(n) { // color: #fff; // }// hover时候每行…

第三节HarmonyOS DevEco Studio了解基本工程目录

一、工程级目录 工程的目录结构如下。 目录详情如下&#xff1a; AppScope&#xff1a;存放应用全局所需要的资源文件。Entry&#xff1a;应用的主模块&#xff0c;存放HarmonyOS应用的代码、资源等。oh_modules&#xff1a;工程的依赖包&#xff0c;存放工程依赖的源文件。b…

【STM32】GPIO输入

1 GPIO输出 1.1 按键简介 按键&#xff1a;常见的输入设备&#xff0c;按下导通&#xff0c;松手断开 按键抖动&#xff1a;由于按键内部使用的是机械式弹簧片来进行通断的&#xff0c;所以在按下和松手的瞬间会伴随有一连串的抖动 1.2 传感器模块简介 传感器模块&#xff…

【图像分割】【深度学习】PFNet官方Pytorch代码-PFNet网络PM定位模块解析

【图像分割】【深度学习】PFNet官方Pytorch代码-PFNet网络PM定位模块解析 文章目录 【图像分割】【深度学习】PFNet官方Pytorch代码-PFNet网络PM定位模块解析前言PFNet网络简述主干网络定位模块 Positioning Module通道注意力模块 Channel Attention空间注意力模块 Spatial Att…

1-1、汇编语言概述

语雀原文链接 文章目录 1、机器语言2、汇编语言&#xff08;Assembly Language&#xff09;汇编语言工作过程汇编语言三类指令 3、学习资料电子PDF课件论坛视频教程 1、机器语言 机器语言是机器指令的集合。机器指令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器…

古埃及金字塔的修建

从理论上说&#xff0c;古埃及人完全有能力设计并建造出充满各种奇妙细节的胡夫金字塔&#xff0c;但后世还是不断涌现出质疑之声&#xff0c;原因倒也简单&#xff0c;那就是胡夫金字塔实在太大了。据推算&#xff0c;整座金字塔使用大约230万块巨石&#xff0c;总质量可达约5…

SpringBoot+Redis编写一个抢红包雨的案例。附源码。

案例演示 SpringBootRedis编写一个抢红包雨的案例。附源码 1、案例分析&#xff0c;整体方案介绍 预备上线一个红包雨活动。这个红包雨的思路是活动开始前25分钟&#xff0c;在后台创建活动。然后前端用户进入&#xff0c;到点后将设置的金额拆分成多个小红包&#xff0c;开启倒…

数据分析实战案例:Python 分析员工为何离职(附完整代码)

大家好&#xff0c;今天给大家介绍一个Python数据分析项目实战&#xff0c;不仅包含代码&#xff0c;还提供分析数据集。 员工流失或是员工离开公司的比率是公司关注的一个重要问题。它不仅会导致宝贵人才的流失&#xff0c;还会产生成本并破坏生产力。了解员工辞职的原因对于…

勒索解密后oracle无法启动故障处理----惜分飞

客户linux平台被勒索病毒加密,其中有oracle数据库.客户联系黑客进行解密【勒索解密oracle失败】,但是数据库无法正常启动,dbv检查数据库文件报错 [oraclehisdb ~]$ dbv filesystem01.dbf DBVERIFY: Release 11.2.0.1.0 - Production on 星期一 11月 27 21:49:17 2023 Copyrig…

01-鸿蒙4.0学习之开发环境搭建 HelloWorld

HarmonyOS开发学习 1.环境配置 1.下载地址 开发工具&#xff1a;DevEco Studio 3.1.1 Release 下载地址 安装选择快捷方式 安装nodejs和Ohpm 安装SDK 选择同意Accept 检测8项目是否安装成功 2.创建项目 —— hello word