yolo实现数据增强(数据集不够,快速增加数据集)

目录结构
在这里插入图片描述

附上数据增强的全部代码

# -*- coding=utf-8 -*-import time
import random
import copy
import cv2
import os
import math
import numpy as np
from skimage.util import random_noise
from lxml import etree, objectify
import xml.etree.ElementTree as ET
import argparse# 显示图片
def show_pic(img, bboxes=None):'''输入:img:图像arraybboxes:图像的所有boudning box list, 格式为[[x_min, y_min, x_max, y_max]....]names:每个box对应的名称'''for i in range(len(bboxes)):bbox = bboxes[i]x_min = bbox[0]y_min = bbox[1]x_max = bbox[2]y_max = bbox[3]cv2.rectangle(img, (int(x_min), int(y_min)), (int(x_max), int(y_max)), (0, 255, 0), 3)cv2.namedWindow('pic', 0)  # 1表示原图cv2.moveWindow('pic', 0, 0)cv2.resizeWindow('pic', 1200, 800)  # 可视化的图片大小cv2.imshow('pic', img)cv2.waitKey(0)cv2.destroyAllWindows()# 图像均为cv2读取
class DataAugmentForObjectDetection():def __init__(self, rotation_rate=0.5, max_rotation_angle=5,crop_rate=0.5, shift_rate=0.5, change_light_rate=0.5,add_noise_rate=0.5, flip_rate=0.5,cutout_rate=0.5, cut_out_length=50, cut_out_holes=1, cut_out_threshold=0.5,is_addNoise=True, is_changeLight=True, is_cutout=True, is_rotate_img_bbox=True,is_crop_img_bboxes=True, is_shift_pic_bboxes=True, is_filp_pic_bboxes=True):# 配置各个操作的属性self.rotation_rate = rotation_rateself.max_rotation_angle = max_rotation_angleself.crop_rate = crop_rateself.shift_rate = shift_rateself.change_light_rate = change_light_rateself.add_noise_rate = add_noise_rateself.flip_rate = flip_rateself.cutout_rate = cutout_rateself.cut_out_length = cut_out_lengthself.cut_out_holes = cut_out_holesself.cut_out_threshold = cut_out_threshold# 是否使用某种增强方式self.is_addNoise = is_addNoiseself.is_changeLight = is_changeLightself.is_cutout = is_cutoutself.is_rotate_img_bbox = is_rotate_img_bboxself.is_crop_img_bboxes = is_crop_img_bboxesself.is_shift_pic_bboxes = is_shift_pic_bboxesself.is_filp_pic_bboxes = is_filp_pic_bboxes# ----1.加噪声---- #def _addNoise(self, img):'''输入:img:图像array输出:加噪声后的图像array,由于输出的像素是在[0,1]之间,所以得乘以255'''# return cv2.GaussianBlur(img, (11, 11), 0)return random_noise(img, mode='gaussian', seed=int(time.time()), clip=True) * 255# ---2.调整亮度--- #def _changeLight(self, img):alpha = random.uniform(0.35, 1)blank = np.zeros(img.shape, img.dtype)return cv2.addWeighted(img, alpha, blank, 1 - alpha, 0)# ---3.cutout--- #def _cutout(self, img, bboxes, length=100, n_holes=1, threshold=0.5):'''原版本:https://github.com/uoguelph-mlrg/Cutout/blob/master/util/cutout.pyRandomly mask out one or more patches from an image.Args:img : a 3D numpy array,(h,w,c)bboxes : 框的坐标n_holes (int): Number of patches to cut out of each image.length (int): The length (in pixels) of each square patch.'''def cal_iou(boxA, boxB):'''boxA, boxB为两个框,返回iouboxB为bouding box'''# determine the (x, y)-coordinates of the intersection rectanglexA = max(boxA[0], boxB[0])yA = max(boxA[1], boxB[1])xB = min(boxA[2], boxB[2])yB = min(boxA[3], boxB[3])if xB <= xA or yB <= yA:return 0.0# compute the area of intersection rectangleinterArea = (xB - xA + 1) * (yB - yA + 1)# compute the area of both the prediction and ground-truth# rectanglesboxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)iou = interArea / float(boxBArea)return iou# 得到h和wif img.ndim == 3:h, w, c = img.shapeelse:_, h, w, c = img.shapemask = np.ones((h, w, c), np.float32)for n in range(n_holes):chongdie = True  # 看切割的区域是否与box重叠太多while chongdie:y = np.random.randint(h)x = np.random.randint(w)y1 = np.clip(y - length // 2, 0,h)  # numpy.clip(a, a_min, a_max, out=None), clip这个函数将将数组中的元素限制在a_min, a_max之间,大于a_max的就使得它等于 a_max,小于a_min,的就使得它等于a_miny2 = np.clip(y + length // 2, 0, h)x1 = np.clip(x - length // 2, 0, w)x2 = np.clip(x + length // 2, 0, w)chongdie = Falsefor box in bboxes:if cal_iou([x1, y1, x2, y2], box) > threshold:chongdie = Truebreakmask[y1: y2, x1: x2, :] = 0.img = img * maskreturn img# ---4.旋转--- #def _rotate_img_bbox(self, img, bboxes, angle=5, scale=1.):'''参考:https://blog.csdn.net/u014540717/article/details/53301195crop_rate输入:img:图像array,(h,w,c)bboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值angle:旋转角度scale:默认1输出:rot_img:旋转后的图像arrayrot_bboxes:旋转后的boundingbox坐标list'''# 旋转图像w = img.shape[1]h = img.shape[0]# 角度变弧度rangle = np.deg2rad(angle)  # angle in radians# now calculate new image width and heightnw = (abs(np.sin(rangle) * h) + abs(np.cos(rangle) * w)) * scalenh = (abs(np.cos(rangle) * h) + abs(np.sin(rangle) * w)) * scale# ask OpenCV for the rotation matrixrot_mat = cv2.getRotationMatrix2D((nw * 0.5, nh * 0.5), angle, scale)# calculate the move from the old center to the new center combined# with the rotationrot_move = np.dot(rot_mat, np.array([(nw - w) * 0.5, (nh - h) * 0.5, 0]))# the move only affects the translation, so update the translationrot_mat[0, 2] += rot_move[0]rot_mat[1, 2] += rot_move[1]# 仿射变换rot_img = cv2.warpAffine(img, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)# 矫正bbox坐标# rot_mat是最终的旋转矩阵# 获取原始bbox的四个中点,然后将这四个点转换到旋转后的坐标系下rot_bboxes = list()for bbox in bboxes:xmin = bbox[0]ymin = bbox[1]xmax = bbox[2]ymax = bbox[3]point1 = np.dot(rot_mat, np.array([(xmin + xmax) / 2, ymin, 1]))point2 = np.dot(rot_mat, np.array([xmax, (ymin + ymax) / 2, 1]))point3 = np.dot(rot_mat, np.array([(xmin + xmax) / 2, ymax, 1]))point4 = np.dot(rot_mat, np.array([xmin, (ymin + ymax) / 2, 1]))# 合并np.arrayconcat = np.vstack((point1, point2, point3, point4))# 改变array类型concat = concat.astype(np.int32)# 得到旋转后的坐标rx, ry, rw, rh = cv2.boundingRect(concat)rx_min = rxry_min = ryrx_max = rx + rwry_max = ry + rh# 加入list中rot_bboxes.append([rx_min, ry_min, rx_max, ry_max])return rot_img, rot_bboxes# ---5.裁剪--- #def _crop_img_bboxes(self, img, bboxes):'''裁剪后的图片要包含所有的框输入:img:图像arraybboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值输出:crop_img:裁剪后的图像arraycrop_bboxes:裁剪后的bounding box的坐标list'''# 裁剪图像w = img.shape[1]h = img.shape[0]x_min = w  # 裁剪后的包含所有目标框的最小的框x_max = 0y_min = hy_max = 0for bbox in bboxes:x_min = min(x_min, bbox[0])y_min = min(y_min, bbox[1])x_max = max(x_max, bbox[2])y_max = max(y_max, bbox[3])d_to_left = x_min  # 包含所有目标框的最小框到左边的距离d_to_right = w - x_max  # 包含所有目标框的最小框到右边的距离d_to_top = y_min  # 包含所有目标框的最小框到顶端的距离d_to_bottom = h - y_max  # 包含所有目标框的最小框到底部的距离# 随机扩展这个最小框crop_x_min = int(x_min - random.uniform(0, d_to_left))crop_y_min = int(y_min - random.uniform(0, d_to_top))crop_x_max = int(x_max + random.uniform(0, d_to_right))crop_y_max = int(y_max + random.uniform(0, d_to_bottom))# 随机扩展这个最小框 , 防止别裁的太小# crop_x_min = int(x_min - random.uniform(d_to_left//2, d_to_left))# crop_y_min = int(y_min - random.uniform(d_to_top//2, d_to_top))# crop_x_max = int(x_max + random.uniform(d_to_right//2, d_to_right))# crop_y_max = int(y_max + random.uniform(d_to_bottom//2, d_to_bottom))# 确保不要越界crop_x_min = max(0, crop_x_min)crop_y_min = max(0, crop_y_min)crop_x_max = min(w, crop_x_max)crop_y_max = min(h, crop_y_max)crop_img = img[crop_y_min:crop_y_max, crop_x_min:crop_x_max]# 裁剪boundingbox# 裁剪后的boundingbox坐标计算crop_bboxes = list()for bbox in bboxes:crop_bboxes.append([bbox[0] - crop_x_min, bbox[1] - crop_y_min, bbox[2] - crop_x_min, bbox[3] - crop_y_min])return crop_img, crop_bboxes# ---6.平移--- #def _shift_pic_bboxes(self, img, bboxes):'''平移后的图片要包含所有的框输入:img:图像arraybboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值输出:shift_img:平移后的图像arrayshift_bboxes:平移后的bounding box的坐标list'''# 平移图像w = img.shape[1]h = img.shape[0]x_min = w  # 裁剪后的包含所有目标框的最小的框x_max = 0y_min = hy_max = 0for bbox in bboxes:x_min = min(x_min, bbox[0])y_min = min(y_min, bbox[1])x_max = max(x_max, bbox[2])y_max = max(y_max, bbox[3])d_to_left = x_min  # 包含所有目标框的最大左移动距离d_to_right = w - x_max  # 包含所有目标框的最大右移动距离d_to_top = y_min  # 包含所有目标框的最大上移动距离d_to_bottom = h - y_max  # 包含所有目标框的最大下移动距离x = random.uniform(-(d_to_left - 1) / 3, (d_to_right - 1) / 3)y = random.uniform(-(d_to_top - 1) / 3, (d_to_bottom - 1) / 3)M = np.float32([[1, 0, x], [0, 1, y]])  # x为向左或右移动的像素值,正为向右负为向左; y为向上或者向下移动的像素值,正为向下负为向上shift_img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))#  平移boundingboxshift_bboxes = list()for bbox in bboxes:shift_bboxes.append([bbox[0] + x, bbox[1] + y, bbox[2] + x, bbox[3] + y])return shift_img, shift_bboxes# ---7.镜像--- #def _filp_pic_bboxes(self, img, bboxes):'''平移后的图片要包含所有的框输入:img:图像arraybboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值输出:flip_img:平移后的图像arrayflip_bboxes:平移后的bounding box的坐标list'''# 翻转图像flip_img = copy.deepcopy(img)h, w, _ = img.shapesed = random.random()if 0 < sed < 0.33:  # 0.33的概率水平翻转,0.33的概率垂直翻转,0.33是对角反转flip_img = cv2.flip(flip_img, 0)  # _flip_xinver = 0elif 0.33 < sed < 0.66:flip_img = cv2.flip(flip_img, 1)  # _flip_yinver = 1else:flip_img = cv2.flip(flip_img, -1)  # flip_x_yinver = -1# 调整boundingboxflip_bboxes = list()for box in bboxes:x_min = box[0]y_min = box[1]x_max = box[2]y_max = box[3]if inver == 0:# 0:垂直翻转flip_bboxes.append([x_min, h - y_max, x_max, h - y_min])elif inver == 1:# 1:水平翻转flip_bboxes.append([w - x_max, y_min, w - x_min, y_max])elif inver == -1:# -1:水平垂直翻转flip_bboxes.append([w - x_max, h - y_max, w - x_min, h - y_min])return flip_img, flip_bboxes# 图像增强方法def dataAugment(self, img, bboxes):'''图像增强输入:img:图像arraybboxes:该图像的所有框坐标输出:img:增强后的图像bboxes:增强后图片对应的box'''change_num = 0  # 改变的次数# print('------')while change_num < 1:  # 默认至少有一种数据增强生效if self.is_rotate_img_bbox:if random.random() > self.rotation_rate:  # 旋转change_num += 1angle = random.uniform(-self.max_rotation_angle, self.max_rotation_angle)scale = random.uniform(0.7, 0.8)img, bboxes = self._rotate_img_bbox(img, bboxes, angle, scale)if self.is_shift_pic_bboxes:if random.random() < self.shift_rate:  # 平移change_num += 1img, bboxes = self._shift_pic_bboxes(img, bboxes)if self.is_changeLight:if random.random() > self.change_light_rate:  # 改变亮度change_num += 1img = self._changeLight(img)if self.is_addNoise:if random.random() < self.add_noise_rate:  # 加噪声change_num += 1img = self._addNoise(img)if self.is_cutout:if random.random() < self.cutout_rate:  # cutoutchange_num += 1img = self._cutout(img, bboxes, length=self.cut_out_length, n_holes=self.cut_out_holes,threshold=self.cut_out_threshold)if self.is_filp_pic_bboxes:if random.random() < self.flip_rate:  # 翻转change_num += 1img, bboxes = self._filp_pic_bboxes(img, bboxes)return img, bboxes# xml解析工具
class ToolHelper():# 从xml文件中提取bounding box信息, 格式为[[x_min, y_min, x_max, y_max, name]]def parse_xml(self, path):'''输入:xml_path: xml的文件路径输出:从xml文件中提取bounding box信息, 格式为[[x_min, y_min, x_max, y_max, name]]'''tree = ET.parse(path)root = tree.getroot()objs = root.findall('object')coords = list()for ix, obj in enumerate(objs):name = obj.find('name').textbox = obj.find('bndbox')x_min = int(box[0].text)y_min = int(box[1].text)x_max = int(box[2].text)y_max = int(box[3].text)coords.append([x_min, y_min, x_max, y_max, name])return coords# 保存图片结果def save_img(self, file_name, save_folder, img):cv2.imwrite(os.path.join(save_folder, file_name), img)# 保持xml结果def save_xml(self, file_name, save_folder, img_info, height, width, channel, bboxs_info):''':param file_name:文件名:param save_folder:#保存的xml文件的结果:param height:图片的信息:param width:图片的宽度:param channel:通道:return:'''folder_name, img_name = img_info  # 得到图片的信息E = objectify.ElementMaker(annotate=False)anno_tree = E.annotation(E.folder(folder_name),E.filename(img_name),E.path(os.path.join(folder_name, img_name)),E.source(E.database('Unknown'),),E.size(E.width(width),E.height(height),E.depth(channel)),E.segmented(0),)labels, bboxs = bboxs_info  # 得到边框和标签信息for label, box in zip(labels, bboxs):anno_tree.append(E.object(E.name(label),E.pose('Unspecified'),E.truncated('0'),E.difficult('0'),E.bndbox(E.xmin(box[0]),E.ymin(box[1]),E.xmax(box[2]),E.ymax(box[3]))))etree.ElementTree(anno_tree).write(os.path.join(save_folder, file_name), pretty_print=True)if __name__ == '__main__':need_aug_num = 5  # 每张图片需要增强的次数is_endwidth_dot = True  # 文件是否以.jpg或者png结尾dataAug = DataAugmentForObjectDetection()  # 数据增强工具类toolhelper = ToolHelper()  # 工具# 获取相关参数parser = argparse.ArgumentParser()parser.add_argument('--source_img_path', type=str, default='/home/train/images')parser.add_argument('--source_xml_path', type=str, default='/home/train/Annotations')parser.add_argument('--save_img_path', type=str, default='/home/train/Images2')parser.add_argument('--save_xml_path', type=str, default='/home/train/Annotations2')args = parser.parse_args()source_img_path = args.source_img_path  # 图片原始位置source_xml_path = args.source_xml_path  # xml的原始位置save_img_path = args.save_img_path  # 图片增强结果保存文件save_xml_path = args.save_xml_path  # xml增强结果保存文件# 如果保存文件夹不存在就创建if not os.path.exists(save_img_path):os.mkdir(save_img_path)if not os.path.exists(save_xml_path):os.mkdir(save_xml_path)for parent, _, files in os.walk(source_img_path):files.sort()for file in files:cnt = 0pic_path = os.path.join(parent, file)xml_path = os.path.join(source_xml_path, file[:-4] + '.xml')values = toolhelper.parse_xml(xml_path)  # 解析得到box信息,格式为[[x_min,y_min,x_max,y_max,name]]coords = [v[:4] for v in values]  # 得到框labels = [v[-1] for v in values]  # 对象的标签# 如果图片是有后缀的if is_endwidth_dot:# 找到文件的最后名字dot_index = file.rfind('.')_file_prefix = file[:dot_index]  # 文件名的前缀_file_suffix = file[dot_index:]  # 文件名的后缀img = cv2.imread(pic_path)# show_pic(img, coords)  # 显示原图while cnt < need_aug_num:  # 继续增强auged_img, auged_bboxes = dataAug.dataAugment(img, coords)auged_bboxes_int = np.array(auged_bboxes).astype(np.int32)height, width, channel = auged_img.shape  # 得到图片的属性img_name = '{}_{}{}'.format(_file_prefix, cnt + 1, _file_suffix)  # 图片保存的信息toolhelper.save_img(img_name, save_img_path,auged_img)  # 保存增强图片toolhelper.save_xml('{}_{}.xml'.format(_file_prefix, cnt + 1),save_xml_path, (save_img_path, img_name), height, width, channel,(labels, auged_bboxes_int))  # 保存xml文件# show_pic(auged_img, auged_bboxes)  # 强化后的图print(img_name)cnt += 1  # 继续增强下一张

在上面代码中只需要你把文件路径改成自己的即可,写文件目录之前要保证这些文件夹都存在。
在这里插入图片描述
结果展示
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双端队列、优先级队列、阻塞队列

双端队列、优先级队列、阻塞队列 文章目录 双端队列、优先级队列、阻塞队列1 双端队列1.1 概述1.2 应用实例1.2.1 双端链表实现1.2.2 数组实现1.2.3 测试代码 1.3 课后作业- LeeTCode103 2. 优先级队列2.1 概述2.2 基于无序数组实现2.3 基于有序数组实现2.3 堆实现优先级队列2.…

注意力机制(数学公式)

人类视觉注意力机制极大地提高了视觉信息处理的效率与准确性 计算机注意力机制是为了让卷积神经网络注意到他更加需要注意的地方 &#xff0c;而不是什么都关注 。 分为三种注意力机制&#xff0c;空间注意力机制&#xff0c;通道注意力机制&#xff0c;以及两者的结合。 …

HTTP 原理

HTTP 原理 HTTP 是一个无状态的协议。无状态是指客户机&#xff08;Web 浏览器&#xff09;和服务器之间不需要建立持久的连接&#xff0c;这意味着当一个客户端向服务器端发出请求&#xff0c;然后服务器返回响应(response)&#xff0c;连接就被关闭了&#xff0c;在服务器端…

算法基础之最长公共子序列

最长公共子序列 核心思想&#xff1a; 线性dp 集合定义 : f[i][j]存 a[1 ~ i] 和 b[1 ~ j] 的最长公共子序列长度 状态计算&#xff1a; 分为取/不取a[i]/b[j] 共四种情况 其中 中间两种会包含两个都不取的情况(去掉) 但是因为取最大值 有重复也没事用f[i-1][j] 和 f[i][j-1]表…

案例分析:西门子智能工厂

西门子全球首家原生数字化工厂&#xff0c;以其独特的数字化技术&#xff0c;在虚拟世界中构建了工厂的数字孪生&#xff0c;从而实现了从需求分析、规划设计、施工实施到生产运营全过程的数字化。这一原生数字化工厂的创新之处在于&#xff0c;它开创性地运用了原生数字孪生理…

2023年12月25日:串口发出控制命令

代码 uart4.c #include "uart4.h"void uart4_config() {//*****************************************//使能GPIOB|GPIOG|UART4外设时钟RCC->MP_AHB4ENSETR |(0x1<<6);RCC->MP_AHB4ENSETR |(0x1<<1);RCC->MP_APB1ENSETR |(0x1<<16);RCC…

27 redis 的 sentinel 集群

前言 redis 的哨兵的相关业务功能的实现 哨兵的主要作用是 检测 redis 主从集群中的 master 是否挂掉, 单个哨兵节点识别 master 下线为主管下线, 超过 quorum 个 哨兵节点 认为 master 挂掉, 识别为 客观下线 然后做 failover 的相关处理, 重新选举 master 节点 我们这里…

平衡二叉树的构建(递归

目录 1.概念&#xff1a;2.特点&#xff1a;3.构建方法&#xff1a;4.代码&#xff1a;小结&#xff1a; 1.概念&#xff1a; 平衡二叉树&#xff08;Balanced Binary Tree&#xff09;&#xff0c;也称为AVL树&#xff0c;是一种二叉树&#xff0c;它满足每个节点的左子树和右…

异常和智能指针

智能指针的认识 智能指针是一种C语言中用于管理动态内存的工具&#xff0c;它们可以自动管理内存的分配和释放&#xff0c;从而避免内存泄漏和悬空指针等问题。智能指针可以跟踪指向的对象的引用次数&#xff0c;并在需要时自动释放被引用的内存&#xff0c;这极大地提高了内存…

openGauss学习笔记-173 openGauss 数据库运维-备份与恢复-导入数据-对表执行VACUUM

文章目录 openGauss学习笔记-173 openGauss 数据库运维-备份与恢复-导入数据-对表执行VACUUM openGauss学习笔记-173 openGauss 数据库运维-备份与恢复-导入数据-对表执行VACUUM 如果导入过程中&#xff0c;进行了大量的更新或删除行时&#xff0c;应运行VACUUM FULL命令&…

关于合同能源管理

合同能源管理模式&#xff1a;我投资、你节能、收益共享 合同能源管理&#xff08;EPC——Energy Performance Contracting&#xff09;&#xff1a;节能服务公司与用能单位以契约形式约定节能项目的节能目标&#xff0c;节能服务公司为实现节能目标向用能单位提供必要的服务&…

Python 直方图的绘制-`hist()`方法(Matplotlib篇-第7讲)

Python 直方图的绘制-hist()方法(Matplotlib篇-第7讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…

什么是制造业的数字化车间

什么是制造业的数字化车间&#xff0c;在企业数字化转型中&#xff0c;数字化车间的存在至关重要&#xff0c;其意思就是将制造业车间里所有的工作流程数字化&#xff0c;实现设备、生产流程、工人等各环节之间的数字化管理与协同&#xff0c;全面提升制造业企业的生产效率和产…

data选项声明-vite项目

新建App.vue,内容如下 <script>export default{//data选项声明响应式状态&#xff0c;必须是返回一个对象的函数data(){return{//声明状态属性&#xff0c;属性名不能以$和_开头&#xff0c;内置使用保留&#xff0c;不让我们声明使用msg:我是谁,age:18,salary:99.99,st…

「Verilog学习笔记」并串转换

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 串并转换操作是非常灵活的操作&#xff0c;核心思想就是移位。串转并就是把1位的输入放到N位reg的最低位&#xff0c;然后N位reg左移一位&#xff0c;在把1位输入放到左移后…

如何做好接口测试?资深测试老鸟总结,一篇带你打通...

前言 1、接口测试 1&#xff09;什么是接口测试&#xff1f; 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相…

TCP协议工作原理及实战(一)

实战项目目标&#xff1a; ui搭建&#xff1a;clientconnect 客户端连接 clientdisconnect 客户端断开 socketreaddate 使用套接字传输数据 newconnection新的连接 获取本机的IP地址&#xff1a; 获取本机的ip地址可以参考前面的QT网络编程协议 将得到的ip地址放入combox中…

VMware安装linux系统一

1、创建虚拟机 1.1、创建新的虚拟机 1.2、进入安装向导 1.3、安装操作系统&#xff0c;选择稍后安装操作系统 1.4、选择Linux,版本选择CentOS64位 1.5、设置虚拟机名称和安装位置 1.6、设置磁盘大小 1.7、创建虚拟机 1.8、完成安装 2、配置虚拟机 2.1、选择编辑虚拟机 2.2、修…

sql_lab之sqli注入中的cookie注入

Cookei注入&#xff08;gxa的从cookei注入&#xff09; 1.打开控制台 2.验证id2时的值 document.cookie"id2" 3.判断是上面闭合方式 document.cookie"id2 -- s" 有回显 说明是’单引号闭合 4.用order by 判断字段数 5.用联合查询判断回显点 接下来的…

“用户名不在 sudoers文件中,此事将被报告” 解决方法

原因 当普通用户需要安装文件时&#xff0c;无法用yum install ** -y直接安装时&#xff0c;采用sudo yum install **; 但是发现提示“用户名不在 sudoers文件中&#xff0c;此事将被报告” 解决方法。 这是因为该普通用户不在sudoers文件中&#xff0c;所以要找到该文件&am…