zhang_logs

Days1 by zhang

准备环境

配置镜像源

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查看anaconda中已经存在的镜像源

conda config --show channels

添加镜像源(永久添加)

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/
free/

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/
main/

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/
conda-forge/

设置搜索时显示通道地址

conda config --set show_channel_urls yes

检查是否换源成功!!!终端输入以下命令:conda info

清华:https://pypi.tuna.tsinghua.edu.cn/simple

阿里云:https://mirrors.aliyun.com/pypi/simple/

中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple/

华中理工大学:https://pypi.hustunique.com/

山东理工大学:https://pypi.sdutlinux.org/

豆瓣:https://pypi.douban.com/simple/

安装tf1.15
conda create --name tf2.3 python=3.7

>conda activate tf2.3

>conda install cudatoolkit=10.0

>conda install cudnn=7.6.5

>pip install numpy==1.19.5 -i https://pypi.tuna.tsinghua.edu.cn/simple


>$env:LD_LIBRARY_PATH = $env:LD_LIBRARY_PATH + ";" + $env:CONDA_PREFIX + "\lib"

>pip install --upgrade pip 

>pip install tensorflow-gpu==2.3.0 -i https://pypi.tuna.tsinghua.edu.cn/simple


>python3 -c "import tensorflow as tf; print(tf.test.is_gpu_available())"

安装其他的库

>conda install keras=2.3.1

>conda install jupyter

>conda install numpy scikit-image scipy pillow cython h5py matplotlib opencv pycocotools

安装imgaug

安装imgaug库前的准备:

>numpy

>scipy

>pip(pip3推荐)install -U scikit-image

>pip(pip3推荐)install -U six

>OpenCV

>pip install git+https://github.com/aleju/imgaug

>pip3 install imgaug

通过csdn加速

https://link.csdn.net/?target=

安装h5py

pip install tensorflow-gpu==1.15.0

pip install tensorboard1.15.0 tensorflow-estimator1.15.1

pip install h5py==2.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simple --timeout
100

安装keras

pip uninstall keras

pip install keras==2.2.4

遇到的困难

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Days2

下载yolov7基本数据

下载后

环境搭建

过程记录:使用Anaconda创建实验所需要的touch环境,在提供的压缩包中一共分为了俩部分的环境配置requirements。

第一部分是:在训练之前准备工作所需要的库:opencv-python、PyQt5、labelme、sklearn,在requirements的当前路径执行pip install –r requirements.txt即可以此安装上面的库环境 ,实验室默认配置了安装网路路径为清华源。

第二部分是:训练所需要的库环境scipy>=1.2.1、numpy>=1.17.0、matplotlib>=3.1.2、opencv_python>=4.1.2.30、torch>=1.2.0、torchvision>=0.4.0、tqdm>=4.60.0、Pillow>=8.2.0、h5py>=2.10.0,安装方式依然在requirements的当前路径下执行pip install –r requirements.txt。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题及总结:

在安装环境时,没有在相关文件的路径下就执行命令;和在命令行时执行文件时不在文件的当前路径都会报NotFoundFile等相关错误。

目标检测模型安装配置

过程记录:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题及总结:
在这段代码中,使用了一个称为 YOLO(You Only Look Once)的目标检测算法。YOLO 是一种快速、高效的目标检测算法,它能够在图像中准确地检测出多个对象,并且在实时性要求较高的情况下也能够保持较高的检测速度。

YOLO 的工作原理可以简单概括为以下几个步骤:

图像分割:首先,将输入的图像划分为一个固定大小的网格。每个网格单元负责检测该网格内是否存在目标,并且负责预测目标的位置和类别。

预测:对于每个网格单元,使用卷积神经网络(CNN)进行预测。预测包括两个部分:

目标框(Bounding Box):用于描述检测到的目标的位置和大小。
目标类别:用于描述检测到的目标属于哪一类(如人、车、狗等)。
后处理:通过应用阈值来筛选出置信度(confidence)高于某个阈值的预测结果,并采用非最大抑制(Non-Maximum Suppression,NMS)来消除重叠的检测框,保留置信度最高的检测结果。

在这段代码中,YOLO 的具体实现可能包括以下几个方面的内容:

加载模型:通过调用 YOLO 类来加载预训练的 YOLO 模型,该模型已经在大规模数据集上进行了训练,可以用来进行目标检测任务。
图像预处理:对输入的图像进行预处理,包括调整大小、归一化等

部分代码


class YOLO(object):
    _defaults = {
        "model_path": 'model_data/ep020-loss0.065-val_loss0.053.pth',
        "classes_path": 'model_data/voc_monkey_girl_classes.txt',
        "anchors_path": 'model_data/yolo_anchors.txt',
        "anchors_mask": [[6, 7, 8], [3, 4, 5], [0, 1, 2]],
        "input_shape": [640, 640],
        "phi": 'l',
        "confidence": 0.1,
        "nms_iou": 0.5,
        "letterbox_image": True,
        "cuda": True,
    }

    @classmethod
    def get_defaults(cls, n):
        if n in cls._defaults:
            return cls._defaults[n]
        else:
            return "Unrecognized attribute name '" + n + "'"

    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults)
        for name, value in kwargs.items():
            setattr(self, name, value)
            self._defaults[name] = value

        self.class_names, self.num_classes = get_classes(self.classes_path)
        self.anchors, self.num_anchors = get_anchors(self.anchors_path)
        self.bbox_util = DecodeBox(self.anchors, self.num_classes, (self.input_shape[0], self.input_shape[1]), self.anchors_mask)

        hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors))
        self.generate()

        show_config(**self._defaults)

    def generate(self, onnx=False):
        self.net = YoloBody(self.anchors_mask, self.num_classes, self.phi)
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.net.load_state_dict(torch.load(self.model_path, map_location=device))
        self.net = self.net.fuse().eval()
        if not onnx and self.cuda:
            self.net = nn.DataParallel(self.net)
            self.net = self.net.cuda()
        print('{} model, and classes loaded.'.format(self.model_path))

    def detect_image(self, image, crop=False, count=False):
        image_shape = np.array(np.shape(image)[0:2])
        image = cvtColor(image)
        image_data = resize_image(image, (self.input_shape[1], self.input_shape[0]), self.letterbox_image)
        image_data = np.expand_dims(np.transpose(preprocess_input(np.array(image_data, dtype='float32')), (2, 0, 1)), 0)

        with torch.no_grad():
            images = torch.from_numpy(image_data)
            if self.cuda:
                images = images.cuda()
            outputs = self.net(images)
            outputs = self.bbox_util.decode_box(outputs)
            results = self.bbox_util.non_max_suppression(torch.cat(outputs, 1), self.num_classes, self.input_shape,
                                                         image_shape, self.letterbox_image, conf_thres=self.confidence,
                                                         nms_thres=self.nms_iou)
            if results[0] is None:
                return image

            top_label = np.array(results[0][:, 6], dtype='int32')
            top_conf = results[0][:, 4] * results[0][:, 5]
            top_boxes = results[0][:, :4]

        font = ImageFont.truetype(font='model_data/simhei.ttf', size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = int(max((image.size[0] + image.size[1]) // np.mean(self.input_shape), 1))
        return image

class YOLO(object): YOLO 类初始化和默认参数设置

初始化方法: def init(self, **kwargs)

def generate(self, onnx=False):
    self.net = YoloBody(self.anchors_mask, self.num_classes, self.phi)
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    self.net.load_state_dict(torch.load(self.model_path,map_location=device))
    self.net = self.net.fuse().eval()
    if not onnx and self.cuda:
        self.net = nn.DataParallel(self.net)
        self.net = self.net.cuda()
    print('{} model, and classes loaded.'.format(self.model_path))

generate 方法用于创建 YOLO 网络模型,加载预训练的权重,并将模型设置为评估模式。如果使用 CUDA,则将模型转移到 GPU 上。

    def detect_image(self, image, crop=False, count=False):
        image_shape = np.array(np.shape(image)[0:2])
        image = cvtColor(image)
        image_data = resize_image(image, (self.input_shape[1], self.input_shape[0]), self.letterbox_image)
        image_data = np.expand_dims(np.transpose(preprocess_input(np.array(image_data, dtype='float32')), (2, 0, 1)), 0)

        with torch.no_grad():
            images = torch.from_numpy(image_data)
            if self.cuda:
                images = images.cuda()
            outputs = self.net(images)
            outputs = self.bbox_util.decode_box(outputs)
            results = self.bbox_util.non_max_suppression(torch.cat(outputs, 1), self.num_classes, self.input_shape,
                                                         image_shape, self.letterbox_image, conf_thres=self.confidence,
                                                         nms_thres=self.nms_iou)
            if results[0] is None:
                return image

            top_label = np.array(results[0][:, 6], dtype='int32')
            top_conf = results[0][:, 4] * results[0][:, 5]
            top_boxes = results[0][:, :4]

        font = ImageFont.truetype(font='model_data/simhei.ttf', size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = int(max((image.size[0] + image.size[1]) // np.mean(self.input_shape), 1))
        return image

detect_image 方法用于对输入图像进行目标检测。首先获取图像的形状,将图像转换为 RGB,并调整大小。然后将图像转换为张量并输入模型进行预测。通过非极大值抑制 (NMS) 筛选出最终的检测结果,提取类别标签、置信度和边框坐标,最终绘制检测框和标签。

Days3

开始训练

训练代码

import os
import torch
import torch.backends.cudnn as cudnn
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from nets.yolo import YoloBody
from nets.yolo_training import YOLOLoss, get_lr_scheduler, set_optimizer_lr
from utils.callbacks import EvalCallback, LossHistory
from utils.dataloader import YoloDataset, yolo_dataset_collate
from utils.utils import download_weights, get_anchors, get_classes
from utils.utils_fit import fit_one_epoch

if __name__ == "__main__":
    # 初始化设备和参数
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    classes_path = 'model_data/voc_monkey_girl_classes.txt'
    anchors_path = 'model_data/yolo_anchors.txt'
    model_path = 'model_data/yolov7_weights.pth'
    input_shape = [640, 640]
    phi = 'l'

    # 获取 classes 和 anchors
    class_names, num_classes = get_classes(classes_path)
    anchors, num_anchors = get_anchors(anchors_path)

    # 下载预训练权重并创建模型
    download_weights(phi)
    model = YoloBody([[6, 7, 8], [3, 4, 5], [0, 1, 2]], num_classes, phi, pretrained=True)
    model_dict = model.state_dict()
    pretrained_dict = torch.load(model_path, map_location=device)
    model_dict.update(pretrained_dict)
    model.load_state_dict(model_dict)

    # 设置损失函数和优化器
    yolo_loss = YOLOLoss(anchors, num_classes, input_shape, [[6, 7, 8], [3, 4, 5], [0, 1, 2]])
    optimizer = optim.SGD(model.parameters(), lr=1e-2, momentum=0.937, weight_decay=5e-4, nesterov=True)
    lr_scheduler_func = get_lr_scheduler('cos', 1e-2, 1e-4, 300)

    # 读取数据集
    train_annotation_path = '2007_train.txt'
    val_annotation_path = '2007_val.txt'
    with open(train_annotation_path, encoding='utf-8') as f:
        train_lines = f.readlines()
    with open(val_annotation_path, encoding='utf-8') as f:
        val_lines = f.readlines()

    # 准备数据加载器
    train_dataset = YoloDataset(train_lines, input_shape, num_classes, anchors, [[6, 7, 8], [3, 4, 5], [0, 1, 2]], train=True)
    val_dataset = YoloDataset(val_lines, input_shape, num_classes, anchors, [[6, 7, 8], [3, 4, 5], [0, 1, 2]], train=False)
    gen = DataLoader(train_dataset, shuffle=True, batch_size=4, num_workers=2, pin_memory=True, drop_last=True, collate_fn=yolo_dataset_collate)
    gen_val = DataLoader(val_dataset, shuffle=False, batch_size=4, num_workers=2, pin_memory=True, drop_last=True, collate_fn=yolo_dataset_collate)

    # 训练和评估回调
    loss_history = LossHistory('logs', model, input_shape=input_shape)
    eval_callback = EvalCallback(model, input_shape, anchors, [[6, 7, 8], [3, 4, 5], [0, 1, 2]], class_names, num_classes, val_lines, 'logs', True, eval_flag=True, period=10)

    # 开始训练
    for epoch in range(0, 300):
        if epoch == 30:
            for param in model.backbone.parameters():
                param.requires_grad = True
            set_optimizer_lr(optimizer, lr_scheduler_func, epoch)
            gen = DataLoader(train_dataset, shuffle=True, batch_size=4, num_workers=2, pin_memory=True, drop_last=True, collate_fn=yolo_dataset_collate)
            gen_val = DataLoader(val_dataset, shuffle=False, batch_size=4, num_workers=2, pin_memory=True, drop_last=True, collate_fn=yolo_dataset_collate)

        set_optimizer_lr(optimizer, lr_scheduler_func, epoch)
        fit_one_epoch(model, model, yolo_loss, loss_history, eval_callback, optimizer, epoch, len(train_lines) // 4, len(val_lines) // 4, gen, gen_val, 300, True, False, None, 10, 'logs', 0)

    loss_history.writer.close()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始化设备和参数

设置训练设备(CPU 或 GPU)和相关路径。

获取 classes 和 anchors

读取类别名称和锚点信息。

下载预训练权重并创建模型

下载预训练权重,创建 YOLO 模型实例,并加载预训练权重。

设置损失函数和优化器

设置损失函数和优化器(SGD),并配置学习率调度器。

读取数据集

读取训练和验证数据集的文件路径。

准备数据加载器

创建数据加载器,用于批量读取训练和验证数据。

训练和评估回调

初始化训练日志记录器和评估回调函数。

开始训练

使用 fit_one_epoch 函数进行训练和评估。

训练页面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型数据

AP

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在机器学习和计算机视觉领域,AP通常代表 Average Precision(平均精度),它是衡量目标检
测和分类模型性能的一种指标。AP结合了模型在不同置信度阈值下的精度(Precision)和召回率
(Recall)来评估模型的整体性能。

F1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在机器学习和统计学领域,F1分数(F1 Score)是用来衡量分类模型性能的一个指标,它是模型精
度(Precision)和召回率(Recall)的调和平均数。F1分数综合考虑了精度和召回率,可以在精度
和召回率之间取得平衡,尤其适用于类别不平衡的数据集。

Precision

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Precision(精度)是一个用于衡量分类模型性能的指标,特别关注正类预测的准确性。具体来说,
精度表示模型预测为正类的样本中,实际为正类的比例。

Recall

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Recall(召回率)是用于衡量分类模型性能的另一个重要指标,它专注于模型对正类样本的捕获能
力。具体来说,召回率表示所有实际为正类的样本中,被模型正确预测为正类的比例。

整体数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Days4

关于可视化的方案

为什么不选stremlit

优点
易于使用:

  • 简洁的 API:Streamlit 的 API 设计得非常直观,使得数据科学家和分析师可以轻松地将 Python 脚本转换为交互式应用程序。

  • 快速开发:使用 Streamlit,开发者可以在几分钟内构建并展示数据可视化应用,而无需学习复杂的 Web 开发框架。

  • 实时更新:
    自动化刷新:Streamlit 应用程序可以实时更新,用户在修改代码后不需要手动刷新页面,Streamlit 会自动重新加载。

  • 集成性强:
    支持多种数据可视化工具:Streamlit 支持多种 Python 数据可视化库,如 Matplotlib、Plotly、Altair 等,方便开发者使用自己熟悉的工具。
    与 Python 生态系统兼容:Streamlit 可以无缝集成到 Python 的数据科学生态系统中,与 Pandas、NumPy 等库协同工作。

  • 交互性:
    丰富的控件:Streamlit 提供了丰富的交互控件,如按钮、滑块、选择框等,使得用户可以轻松地与应用程序进行交互。
    简单的表单处理:开发者可以快速创建和处理用户输入的表单。
    免费和开源:

  • 开源软件:Streamlit 是一个开源项目,任何人都可以免费使用和修改其源代码。

对于我个人来说他的界面太过简单,没有过多的样式,与此同时:

  • 性能限制:
    对大型应用的支持:Streamlit 主要适用于中小型数据应用,对于需要复杂计算和大规模数据处理的大型应用,Streamlit 的性能可能会成为瓶颈。

  • 功能有限:
    自定义化程度:虽然 Streamlit 提供了许多基础控件和功能,但与专业的 Web 开发框架相比,其自定义和扩展能力仍有一定的局限性。
    缺乏前端开发工具:对于需要高度自定义前端界面的应用,Streamlit 可能无法满足需求。

  • 部署和扩展:
    部署复杂度:尽管 Streamlit 提供了一些部署工具,但对于不熟悉 Web 部署的开发者来说,可能仍然需要一些学习成本。
    扩展性问题:在一些复杂的企业级应用场景中,Streamlit 可能无法提供足够的扩展性和灵活性。

Web+IPOV方案

首先,使用Web可以通过css样式来高度定制自己喜欢的页面,对于我个人来说,腾讯视频的首页我是非常喜欢的。同样地,想要复刻这也是非常困难的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不过,github解君愁。当然,由于要展示的东西很少,所以并没有找到适合我们这个项目体质的框架。

关于IPOV

这个东西非常简单,要考虑的唯一问题就是端口转发,如何避免这个问题。有一下几个方案:

  • 给桌面端设置一个公共的端口,他的难点在于学校的网络环境不太友好

  • 使用直播推流,失去了IPOV的灵魂

  • 使用手机热点局域网,我刚好有一个usb网卡,所以采用这个方案

关于Web

为什么不直接使用后端演示模型:

  • 成本大:时间成本,学习成本,组内沟通成本

  • 组内没有人网络服务器,没法部署到网络,所以后端失去了灵魂

部分html

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>道路感知车辆行人检测</title>
    <link rel="stylesheet" href="Tencent.css">
    ......
    </link>
    <style>
    ......
    </style>
</head>

<body>
    <div class="ren">
        <!-- 头部 -->
        <header>
            <div class="out">
                <!-- 1、top部分 -->
                <div class="header-top">
                    <img src="images/header/log.png" alt="">
                </div>
                <!-- 2、aside部分 -->
                <div class="header-right_aside">
                    <div class="aside-up">
                        <img src="images/header/图标/看点1.png" alt="">
                        <h2>模型</h2>
                    </div>
                    <div class="aside-down">
                        <div class="down">
                            <img src="images/header/图标/热搜榜 (1).png" alt="">
                            <h2>点击跳转</h2>
                        </div>
                        <ul>
                            <li><a href="yolov7.html" target="_blank">yolov7</a></li>
                            <li><a href="yolov5.html" target="_blank">yolov5</a></li>
                            <li><a href="faster1.html" target="_blank">faster1</a></li>
                            <li class="my">
                                <a href="faster2.html" target="_blank">faster2</a>
                            </li>
                        </ul>
                    </div>
                </div>
                <!-- 3、轮播图部分 -->
                <div class="lunbotu">
                    <div class="donghua">
                        <img src="images/header/0 (2).png" alt="" class="tu">
                        <img src="images/header/0 (6).png" alt="" class="tu">
                    </div>
                </div>
            </div>

        </header>

对于css部分不做过多展示

Days5

调试Web效果

大概的内容为:轮播图(不带herf),一个列表,4个视频构成index,
效果如下:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

logs部分由于进度不一致,所以对于模型的跳转推进起来有点缓慢。

  • 这几天在h5上也遇到了不少问题,譬如,修改css对应部分没有效果或者就是和自己的预期截然相反(怀念streamlit的第一天)

  • 解决办法:使用国内的大模型如:豆包等

  • 如何高效的使用大模型区快速构建html代码,我的建议是先找一个想要的前端页面,然后直接把这个链接告诉大模型,虽然第一次不能直接给出我们想要的代码,但是一定要有耐心,多尝试几次,每次尽可能的使用关键词:如按钮,Css,标贴等,使用过程中强调过程忽略细节。

部分代码(Css):

@keyframes move {
    5% {
        left: 0px;
    }

    10% {
        left: -2016px;
    }

    15% {
        left: -2016px;
    }

    20% {
        left: -4032px;
    }

    25% {
        left: -4032px;
    }

    30% {
        left: -6048px;
    }

    35% {
        left: -6048px;
    }

    ..........

    /* 95% {
        left: -18144px;
    } */

    100% {
        left: -0px;
    }
}

这里的百分比是由首页的index轮播图数量决定的

/* 公共css */
* {
    padding: 0px;
    margin: 0px;
}

a {
    color: #d4cac0;
    text-decoration: none;
}

a:hover {
    color: #ff5c38;
    text-decoration: none;
}

li {
    list-style-type: none;
    color: #666666;
    font-size: 18px;
}

h2 {
    font-size: 27px;
}

这部分是给index定了一定的基调

.header-top {
    position: absolute;
    z-index: 2;
    top: 0px;
    left: 0px;
    width: 1920px;
    height: 82px;
    background: rgba(255, 255, 255, .2);
    opacity: 0.8;
}

.header-top img {
    float: left;
    height: 46px;
    margin: 18px 0px 18px 50px;
}

这段代码定义了电子科技大学中山学院的logo样式

button {
    float: left;
    width: 85px;
    height: 50px;
    border: none;
    border-radius: 0px 25px 25px 0px;
    background-color: #ff5c38;
    font-size: 19px;
    color: #ffffff;
    line-height: 50px;
}

定义了模型列表按钮

.out {
    position: relative;
    width: 100%; /* 修改为100%,以适应屏幕宽度 */
    height: 696px; /* 设置高度为图片的高度 */
    overflow: hidden; /* 确保溢出的部分被隐藏 */
    background: #fff; /* 如果需要背景色 */
}

.lunbotu {
    position: relative;
    width: 100%; /* 设置宽度为100%,以适应屏幕宽度 */
    height: 696px; /* 设置高度为图片的高度 */
    overflow: hidden; /* 确保溢出的部分被隐藏 */
}

.donghua {
    position: absolute;
    width: calc(2016px * 图片数量); /* 动态计算宽度,图片数量为轮播图的图片总数 */
    height: 696px; /* 设置为图片的高度 */
    left: 0;
    top: 0;
    animation: move 90s ease normal infinite;
}

.tu {
    float: left;
    width: 2016px; /* 设置为图片的宽度 */
    height: 696px; /* 设置为图片的高度 */
}

.tu img {
    width: 100%; /* 使图片宽度充满容器 */
    height: auto; /* 保持宽高比 */
    display: block; /* 移除内联元素的空隙 */
}

.out .lunbotu {
    position: absolute;
    width: 1920px;
    height: 696px;
    z-index: 1;

    /* 相对于轮播图 */
    position: relative;
    height: 696px;
    /* overflow: hidden; */
}

.out .lunbotu .donghua {
    position: absolute;
    width: calc(2016px * 10); /* 动态计算宽度,图片数量为你轮播图的图片总数 */
    height: 696px; /* 设置为图片的高度 */
    left: 0px;
    top: 0px;
    animation: move 35s ease normal infinite;
}

.out .lunbotu .donghua .tu {
    float: left;
    height: 696px;
}

定义了轮播图的图片信息

.video-gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
    margin-top: 20px;
}

.video-gallery a {
    display: block;
    width: 600px; /* 调整视频显示大小 */
    height: 400px;
    position: relative;
}

.video-gallery video {
    width: 100%;
    height: 100%;
    object-fit: cover; /* 保证视频适应容器 */
    transition: transform 0.3s ease;
}

.video-gallery video:hover {
    transform: scale(1.05);
}

idden; */
}

.out .lunbotu .donghua {
position: absolute;
width: calc(2016px * 10); /* 动态计算宽度,图片数量为你轮播图的图片总数 /
height: 696px; /
设置为图片的高度 */
left: 0px;
top: 0px;
animation: move 35s ease normal infinite;
}

.out .lunbotu .donghua .tu {
float: left;
height: 696px;
}


> 定义了轮播图的图片信息


```css
.video-gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
    margin-top: 20px;
}

.video-gallery a {
    display: block;
    width: 600px; /* 调整视频显示大小 */
    height: 400px;
    position: relative;
}

.video-gallery video {
    width: 100%;
    height: 100%;
    object-fit: cover; /* 保证视频适应容器 */
    transition: transform 0.3s ease;
}

.video-gallery video:hover {
    transform: scale(1.05);
}

定义了视频框的大小和位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值