Python使用YOLOv5图像识别教程包成功-以识别桥墩缺陷详细步骤分享

前置环境资源下载

提示:要开外网才能下载的环境我都放在了网盘里,教程中用到的环境可从这里一并下载:

https://pan.quark.cn/s/f0c36aa1ef60

1. 下载YOLOv5源码

  • 官方地址:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite

2. 下载预训练检查点文件

  • 官方地址:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
  • 页面向下拉,会看到 "Pretrained Checkpoints" 表格,任选一个进行下载(我这里使用的是 yolov5x.pt)。
  • 下载完成后,将 .pt 文件放入 YOLOv5 源码的根目录。

3. 下载CUDA

  • 要用显卡GPU训练模型,就必须下载CUDA。
  • 官方链接:CUDA Toolkit Archive | NVIDIA Developer
  • 我下载的是 12.2.0 版本,安装时选择默认路径即可。

4. 下载3个Python库:torchtorchvisiontorchaudio

  • 提示torch 是算法核心,torchvision 用于处理图像,torchaudio 处理音频/视频。这一条很关键,仔细看,因为涉及到版本匹配

  • 刚才我们下载的CUDA是12.2版本对吧,我们进入PyTorch官网往下拉可以看到一个注释为CUDA 12.1的,所以我就选择差别不大的12.1版本的命令下载,这官网里都给我们把版本匹配好了,就不要自己一个一个不指定版本去下载,ok获取到命令如下,如果下载失败,看下面第5条:

# CUDA 12.1
pip install torch==2.2.1 torchvision==0.17.1 torchaudio==2.2.1 --index-url https://download.pytorch.org/whl/cu121

 

f2b1bf56225ef42e970d2c1ee762f71d.png

5. 使用国内镜像下载库失败的解决方法

官方的命令下载这三个库很多人因为网络超时导致中途下载失败,当然也有下载顺利的人,而尝试使用国内镜像去下载这三个库时,好像是没有GPU版本的,下载下来的只有CPU版本的,因此提供如下安装这三个库的方式,包成功!!!:

下载地址:浏览器进入 PyTorch 官方站 https://download.pytorch.org/whl/torch_stable.html

使用快捷键ctrl+f搜索并下载

torch:搜索 cu121/torch-2.2.1,选择 cp39-win 的版本。

 

e372dff1de8e9c6d4b5c2ef71c47a66e.png

torchvision:搜索 cu121/torchvision-0.17.1,选择 cp39-win 的版本。

 

16d3617a33c0280b3e5a2f56da263263.png

torchaudio:搜索 cu121/torchaudio-2.2.1,选择 cp39-win 的版本。

 

23c5b97dcd2d7c55e87366823cc3d467.png

安装步骤

下载完后随便放到一个目录(如:D:\C01MyENV),然后打开CMD命令行进入这个目录,执行以下三条命令安装:

pip install "torch-2.2.1+cu121-cp39-cp39-win_amd64.whl"
pip install "torchvision-0.17.1+cu121-cp39-cp39-win_amd64.whl"
pip install "torchaudio-2.2.1+cu121-cp39-cp39-win_amd64.whl"

安装过成如图

 

7b65b0115d0efbedc7d2ea2e27bfca36.png

 

ece426392560c6d4f75665a9f4a957f3.png

 

d5d9be7ebd7f0375b763f96ff8f808e1.png

环境验证

验证CUDA是否可用

在Python中运行以下代码,查看你的CUDA是否可用:

import torch# 检查是否有可用的 GPU
print("CUDA是否可用=>", torch.cuda.is_available())
print("pytorch版本=>"+torch.__version__)
print("是否支持CUDA=>"+str(torch.cuda.is_available()))
# 如果有 GPU 可用,打印 GPU 数量和名称
if torch.cuda.is_available():print("GPU设备数量=>", torch.cuda.device_count())print("当前使用GPU=>", torch.cuda.get_device_name(torch.cuda.current_device()))
else:print("没有GPU可用,当前将运行在CPU上")

运行后你会看到如下界面,表示GPU版本的Yolov5环境成功了,如图:

 

9b85443b6cc74b99ab6d39e700f96974.png

Yolov5源码用到的库一键下载

CMD命令进入yolov5源码包,执行pip install -r requirements.txt,此命令会下载requirements.txt文件中指定版本的包。只要你配置了国内的镜像,这一步必然是顺利的。

下载标注工具

1. 下载labelImg工具

  • 官方链接:https://github.com/tzutalin/labelImg
  • 下载完成后,解压到本地。

2. 安装 pyQT5 依赖

  • 由于 labelImg 依赖于 pyQT5,需要先安装它。

    安装命令

    pip install pyqt5

3. 安装 libs.resources 模块

  • 打开 CMD,进入到 labelImg 源码目录,执行以下命令安装 libs.resources 模块:

    安装命令

    pyrcc5 -o libs/resources.py resources.qrc

4. 删除预制标签

  • 为了避免初学者在标记时混淆,请删除 labelImg-master\data\predefined_classes.txt 文件中的所有内容,注意是删除内容,不是让你删除文件。

5. 启动 labelImg

  • CMD命令进入 labelImg 源码目录,运行以下命令启动标注工具:

    启动命令

    python labelImg.py
  • 之后,每次启动 labelImg 都可以直接运行此命令。

准备图片

为快速操作,我这里使用如下爬虫,快速爬取图片,然后筛选24张进行标注训练,当然实际过程中为了保证模型的准确,会需要更多的图片,不复杂的场景100张即可,复杂的场景要上千张

'''
key_word:图片名称关键词
img_num:爬取图片轮数,1轮30张
'''
import json
import math
import os.path
import sys
import timeimport requestsdef catch_img(key_word,rounds): #关键字、爬取轮次,一轮30张if not os.path.exists(key_word):os.mkdir(key_word)for count in range(rounds):print(str(count)+"轮")pn=count*30url = "https://images.baidu.com/search/acjson?tn=resultjson_com&logid=11514788725054802565&ipn=rj&ct=201326592&is=&fp=result&fr=&word="+str(key_word)+"&queryWord="+str(key_word)+"&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=&expermode=&nojc=&isAsync=&pn="+str(pn)+"&rn=30&gsm=1e&1717479169689="headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'}res = requests.get(url, headers=headers)if len(res.json()["data"])==1:print("无图片可获取了")sys.exit()json_data=res.json()["data"] #获取json数据json_str= json.dumps(json_data, indent=2) #json转json字符串list_data=json.loads(json_str) #json字符串转list/dictfor obj in list_data:try:pic_url=obj["thumbURL"] #图像链接except:continuer = requests.get(pic_url,headers=headers)with open(str(key_word)+"\\"+str(time.time())+".jpg", mode="wb") as f:f.write(r.content)if __name__ == '__main__':catch_img("桥梁地基冲刷照片",20)

1. 标注数据集

1.1 创建文件目录

  • yolov5 目录下创建 yoloData 目录,随后在 yoloData 目录下建立以下两个子目录:
    • txtData:用于存放标注的标签文件(.txt 格式)
    • picData:用于存放需要标注的图片文件

1.2 准备图片文件

  • 将需要标注的图片放入 yoloData/picData 目录中。

1.3 启动 labelImg 并设置参数

  1. 启动 labelImg
  2. 点击打开目录,选择 yoloData/picData 目录。
  3. 将左边的存储格式由默认的 PascalVOC 改为 YOLO
  4. 点击文件 -> 改变存放目录,将标签的存放目录设置为 yoloData/txtData
  5. 如图一定要按步骤来,不然可能会闪退

 

fdbc5e45a238e302a34d7eeeeca93d79.png

 

a278c3d4dac77fe6f84427776450203a.png

1.4 开始标注

  1. 例如,如果你要标注图片中的桥墩损坏部位,按下 W 键调出标注十字架,框选出损坏部位并保存,随后输入自定义的缺陷英文名称(如 error_pos),然后继续标注下一张图片。
  2. 可以在同一张图片中标记多个部位。
  3. 标记第一张图片时会提示你先命名标记的类别,类别可以自定义(我这里设置为 error_pos)。

1.5 常用快捷键

  • W:调出标注十字架
  • A:切换到上一张图片
  • D:切换到下一张图片
  • Del:删除标注框
  • Ctrl+U:选择标注的图片文件夹
  • Ctrl+R:选择标注好的标签文件夹

1.6 检查标注结果

  • 标记完后,检查 txtData 目录中的标签文件(.txt)与 picData 目录中的图片文件名称是否对应,数量是否一致。

2. 划分数据集

在我们创建的yoloData目录下建立SplitData.py文件,加入如下代码然后执行会将txt标签和图篇按照8:1:1的比例划分为训练集、测试集、验证集到新的目录

import os
import shutil
import random# 设置随机种子
random.seed(0)def split_data(file_path, xml_path, new_file_path, train_rate, val_rate, test_rate):'''====1.将数据集打乱===='''each_class_image = []each_class_label = []for image in os.listdir(file_path):each_class_image.append(image)for label in os.listdir(xml_path):each_class_label.append(label)# 将两个文件通过zip()函数绑定。data = list(zip(each_class_image, each_class_label))# 计算总长度total = len(each_class_image)# random.shuffle()函数打乱顺序random.shuffle(data)# 再将两个列表解绑each_class_image, each_class_label = zip(*data)'''====2.分别获取train、val、test这三个文件夹对应的图片和标签===='''train_images = each_class_image[0:int(train_rate * total)]val_images = each_class_image[int(train_rate * total):int((train_rate + val_rate) * total)]test_images = each_class_image[int((train_rate + val_rate) * total):]train_labels = each_class_label[0:int(train_rate * total)]val_labels = each_class_label[int(train_rate * total):int((train_rate + val_rate) * total)]test_labels = each_class_label[int((train_rate + val_rate) * total):]'''====3.设置相应的路径保存格式,将图片和标签对应保存下来===='''# trainfor image in train_images:print(image)old_path = file_path + '/' + imagenew_path1 = new_file_path + '/' + 'train' + '/' + 'images'if not os.path.exists(new_path1):os.makedirs(new_path1)new_path = new_path1 + '/' + imageshutil.copy(old_path, new_path)for label in train_labels:print(label)old_path = xml_path + '/' + labelnew_path1 = new_file_path + '/' + 'train' + '/' + 'labels'if not os.path.exists(new_path1):os.makedirs(new_path1)new_path = new_path1 + '/' + labelshutil.copy(old_path, new_path)# valfor image in val_images:old_path = file_path + '/' + imagenew_path1 = new_file_path + '/' + 'val' + '/' + 'images'if not os.path.exists(new_path1):os.makedirs(new_path1)new_path = new_path1 + '/' + imageshutil.copy(old_path, new_path)for label in val_labels:old_path = xml_path + '/' + labelnew_path1 = new_file_path + '/' + 'val' + '/' + 'labels'if not os.path.exists(new_path1):os.makedirs(new_path1)new_path = new_path1 + '/' + labelshutil.copy(old_path, new_path)# testfor image in test_images:old_path = file_path + '/' + imagenew_path1 = new_file_path + '/' + 'test' + '/' + 'images'if not os.path.exists(new_path1):os.makedirs(new_path1)new_path = new_path1 + '/' + imageshutil.copy(old_path, new_path)for label in test_labels:old_path = xml_path + '/' + labelnew_path1 = new_file_path + '/' + 'test' + '/' + 'labels'if not os.path.exists(new_path1):os.makedirs(new_path1)new_path = new_path1 + '/' + labelshutil.copy(old_path, new_path)if __name__ == '__main__':file_path = r"D:\A03PyThonProjects395\yolov5-master\yoloData\picData" #原图片路径txt_path = r"D:\A03PyThonProjects395\yolov5-master\yoloData\txtData"  #.txt标签路径new_file_path = r"D:\A03PyThonProjects395\yolov5-master\yoloData\splitData" #划分后的目录# 设置划分比例split_data(file_path, txt_path, new_file_path, train_rate=0.8, val_rate=0.1, test_rate=0.1)

3. 训练模型

1修改VOC.yaml:

将data目录下的VOC.yaml文件修改内容为如下: download及其以下的配置不用改动,download以上的全部改掉为如下

train: D:\A03PyThonProjects395\yolov5-master\yoloData\splitData\train #训练集绝对路径
val: D:\A03PyThonProjects395\yolov5-master\yoloData\splitData\val #验证集绝对路径# Classes
names: ['error_pos'] #这个error_pos是我们标记数据时设置的勾画物体名称,若忘记了可以在txtData目录下的classes.txt看到nc: 1 #这里填写1的原因:在我们标记数据集之前,我们清空了labelImg-master\data\predefined_classes.txt,然后标记数据时,添加了类别名为error_pos,yolov5在索引我们的类别时是从0开始的,我们的类别只有一个error_pos,所以这里填1,如果不太明白可以简单理解为多少个类别就填几# Download script/URL (optional) ---------------------------------------------------------------------------------------
download: |..........download这块及其一下都不用改动......

2.修改模型配置文件:

因为我们这里使用的预训练权重是yolov5x.pt,因此将models目录下的yolov5x.yaml文件改动如下:

nc: 1 # number of classes  ,只需要把这个改为1就行了

3.正式训练模型前的配置

训练模型是用train.py ,在训练之前,先定位到train.py的parse_opt方法,可以看到有很多训练参数,这里解释下可能需要修改的参数:

--weights:加载的权重文件路径,默认是根目录下的yolov5s.pt,我用的是yolov5x.pt,因此要改为yolov5x.pt
--cfg:这个要指定我们的models/yolov5x.yaml文件
--data:是指定数据集配置文件,我们这里填data/VOC.yaml
--epochs:表示训练的轮次,要训练300轮就改成300
--batch-size:表示每一批训练的批次大小,这个大小根据GPU或CPU指定,一般为16,32,64,128,256等
--workers:表示使用的核心数量,默认为8
--device:选项有0、1、2、3、cpu,0、1、2、3表示选择第几个GPU,我这里就一个显卡,填0就行了以上是可能需要修改的参数,下面列出所有参数解释:
opt参数解析: 
• cfg:   模型配置文件,网络结构
• data:   数据集配置文件,数据集路径,类名等
• hyp:   超参数文件
• epochs:   训练总轮次
• batch-size:   批次大小
• img-size:   输入图片分辨率大小
• rect:   是否采用矩形训练,默认False
• resume:   接着打断训练上次的结果接着训练
• nosave:   不保存模型,默认False
• notest:   不进行test,默认False
• noautoanchor:   不自动调整anchor,默认False
• evolve:   是否进行超参数进化,默认False
• bucket:   谷歌云盘bucket,一般不会用到
• cache-images:   是否提前缓存图片到内存,以加快训练速度,默认False
• weights:   加载的权重文件
• name:   数据集名字,如果设置:results.txt to results_name.txt,默认无
• device:   训练的设备,cpu;0(表示一个gpu设备cuda:0);0,1,2,3(多个gpu设备)
• multi-scale:   是否进行多尺度训练,默认False
• single-cls:    数据集是否只有一个类别,默认False
• adam:   是否使用adam优化器
• sync-bn:   是否使用跨卡同步BN,在DDP模式使用
• local_rank:   gpu编号
• logdir:   存放日志的目录
• workers:   dataloader的最大worker数量

最后我修改过的parse_opt结果如下:

parser.add_argument("--weights", type=str, default=ROOT / "yolov5x.pt", help="initial weights path")
parser.add_argument("--cfg", type=str, default="models/yolov5x.yaml", help="model.yaml path")
parser.add_argument("--data", type=str, default=ROOT / "data/VOC.yaml", help="dataset.yaml path")
parser.add_argument("--hyp", type=str, default=ROOT / "data/hyps/hyp.scratch-low.yaml", help="hyperparameters path")
parser.add_argument("--epochs", type=int, default=100, help="total training epochs")
parser.add_argument("--batch-size", type=int, default=16, help="total batch size for all GPUs, -1 for autobatch")
parser.add_argument("--device", default="0", help="cuda device, i.e. 0 or 0,1,2,3 or cpu")

4.开始训练:

参数配置完后执行train.py开始训练

如图表示在训练了,不愧是GPU,3秒一轮,CPU训练非常慢

 

27cc2066f3281ab1a0caeb5025fdd987.png

5.查询训练结果

训练完后结果会保存在runs的tarin文件里,训练出的最优模型它命名为best.pt,如图

 

0de96ecf426a324d9063ce72897fddf4.png

4.验证模型

验证模型靠的是根目录下的val.py文件,进入val.py文件,定位到parse_opt方法,这里要改动几个参数为我们自己的:

--data:指定验证集的配置文件,即我们data下的VOC.yaml--weights:指定模型权重文件,选择我们训练模型后runs下最好的权重文件best.pt,我这里最好的是exp2目录下的best.pt

最后我改动的参数为如下(就改了两个位置):

parser.add_argument("--data", type=str, default=ROOT / "data/VOC.yaml", help="dataset.yaml path")
parser.add_argument("--weights", nargs="+", type=str, default=ROOT / "runs/train/exp2/weights/best.pt", help="model path(s)")

然后运行val.py进行验证,运行后,会在runs目录下生成val的目录,里面就是验证的结果,可能你现在还看不懂,总之可以简单理解为这些图表表示了模型的准确率,当然我这里为了快速教学,用了24张图片肯定是不够的,如图

 

3025beb1b5f94774cca48ba301a59630.png

5. 用模型检测其他图片

当我们用val.py验证后通过图标查看识别率还不错的话,就可以开始用detect.py进行检测看看效果了

先在根目录创建一个otherPics目录,然后随便网上找几张和你模型需要识别相关的图片,比如我是用来识别桥梁地基冲刷缺陷的,我就找这类图,然后放入otherPics目录

来到detect.py文件下,同样是定位到parse_opt方法,要改动几个参数,这里同验证模型改参数一样:

--weights:指定为自己的最好的训练模型,即runs/train下最好的best.pt
--source:指定要测试的图片的目录,我这里是otherPics
--data:指定数据集配置文件,即我们的data/VOC.yaml
--conf-thres:指定置信度,越小则越信任识别的内容,当然也就越不准确,默认0.25,我这里因为用的图片少,所以调的很低

最终我配置为如下

parser.add_argument("--weights", nargs="+", type=str, default=ROOT / "runs/train/exp2/weights/best.pt", help="model path or triton URL")
parser.add_argument("--source", type=str, default=ROOT / "otherPics", help="file/dir/URL/glob/screen/0(webcam)")
parser.add_argument("--data", type=str, default=ROOT / "data/VOC.yaml", help="(optional) dataset.yaml path")
parser.add_argument("--conf-thres", type=float, default=0.07, help="confidence threshold")

然后运行detect.py,执行完成后会在runs下生成detect目录,目录内便是识别后的图片,如图

 

ee50cd700f4e849d3bab86c71b4c58e7.png

至此,幽络源的图像识别教程结束

补充:如有需要,可以自行将detect改为传入照片然后就返回识别后的信息。

大牛交流QQ群:307531422

 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

9。maven必备小技巧

(1)配置Maven加速时,除了settings之外,还可如下图所示,配置如下: 若想实现Maven加速,最重要的即User settings file。(先修改settings.xml) (2)当…

哪个牌子的头戴式耳机性价比高?四大爆款性价比品牌推荐!

随着科技的不断进步和发展,头戴式耳机已经成为音乐爱好者和专业人士不可或缺的设备。进入2024年,市场上涌现出了一批性能卓越、音质优秀的新产品。这些新品不仅在音质上有了显著的提升,还在设计、舒适度和功能性上进行了全面的优化&#xff0…

(科普篇)公司防止泄密,应该做到哪些?教你10个方法有效阻止泄密事件发生!

公司防止泄密,应该做到哪些? 世事如棋局局新,信息之海波涛汹涌! 甲曰:"企业之基,在于保密。泄密之祸,猛于虎也,如何防患于未然。吾友,可有良策?" …

lettuce引起的Redis command timeout异常

项目使用Lettuce,在自己的环境下跑是没有问题的。在给客户做售前压测时,因为客户端环境比较恶劣,service服务和中间件服务不在同一机房。服务启动后不一会就会出现Redis command timeout异常。 经过差不多两周的追查,最后没办法把…

机器学习的应用领域

机器学习在许多领域有广泛的应用,下面列出了一些主要的应用领域及其典型应用: 1. 图像识别 人脸识别:用于解锁手机、自动标记照片、监控安全系统。物体识别:应用于自动驾驶汽车、机器人、医疗影像分析中,帮助机器理解…

三分钟 ChatGPT 接入钉钉机器人

前言 ChatGPT 大家应该都已经用了一段时间了,功能非常强大,作为开发人员,我用它写文档、写日报、润色 OKR,知识搜索等等,它给我带来了极大的帮助,但我在使用过程中最大的痛点就是网络。 痛点 由于国内不…

Java_Se--方法

方法就是一个代码片段. 类似于 C 语言中的 "函数"。方法存在的意义(不要背, 重在体会): 1. 是能够模块化的组织代码 ( 当代码规模比较复杂的时候 ). 2. 做到代码被重复使用 , 一份代码可以在多个位置使用 . 3. 让代码更好理解更简单 . 4. 直接调用现有方法开…

搭建WSL2+Ubuntu22.04 LTS环境

一、BIOS 开启虚拟化支持 现在的主板一般都默认开启的,也可以检查和开启BIOS虚拟化支持 二、windows开启子系统及虚拟化 打开控制面板 选择 程序 -> 启用或关闭 Windows功能 勾选 Hyper-V、适用于 Linux的 Windows子系统和虚拟机平台 点击确定 重启计算…

【近源攻击】badusb上线cs

❤️博客主页: iknow181 🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP 🎉欢迎大家点赞👍收藏⭐评论✍ 0x01 实验前提 攻击设备:badusb cs服务器:公网部署了 cs 服务端 0x02 实验步骤 …

【计算机网络】理解应用层协议HTTP

目录 HTTP协议认识URLHTTP协议的请求如果我们想获得请求报文的完整内容,怎么办? HTTP协议的响应HTTP的方法GETvsPOST HTTP的状态码HTTP常见HeaderHTTP版本实现一个简单的HTTP服务器 HTTP协议 HTTP协议是一种超文本传输协议,它定义了客户端与…

Kafka 3.0.0集群部署教程

1、集群规划 主机名 ip地址 node.id process.roles kafka1 192.168.0.29 1 broker,controller Kafka2 192.168.0.30 2 broker,controller Kafka3 192.168.0.31 3 broker,controller 将kafka包上传以上节点/app目录下 mkdir /app 解压kafka包 tar -zxvf kafka_…

java之斗地主部分功能的实现

今天我们要实现斗地主中发牌和洗牌这两个功能,该如何去实现呢? 1.创建牌类:52张牌每一张牌包含两个属性:牌的大小和牌的花色。 故我们优先创建一个牌的类(Card):包含大小和花色。 public class Card { //单张牌的大小及类型/…

伊犁-linux 硬盘添加,分区,格式化

主要是linux 下操作硬盘分区,格式化 这样1个sata 盘就添加成功了 !  继续添加三块 sata1 hda sata hdb sata hdc sata hdd scsi sda 作为启动盘 进行操作系统的引导 如果scsi 往下调整 先敲enter 在用- 号往下 如果是往上调整敲…

【IDEA】使用IDEA连接MySQL数据库并自动生成MySQL的建表SQL语句

前言: 在软件开发过程中,数据库的设计与实现是至关重要的一环。IntelliJ IDEA作为一款强大的集成开发环境(IDE),提供了丰富的数据库工具,使得连接MySQL数据库并自动生成建表SQL语句变得简单快捷。本文将详细…

《python语言程序设计》2018版第8章18题几何circle2D类(上部)

一、利用第7章的内容来做前5个点 第一章之1--从各种角度来测量第一章之2--各种结果第二章之1--建立了针对比对点在圆内的几段第二章之2--利用建立的对比代码,得出的第2点位置 第一章之1–从各种角度来测量 class Circle2D:def __init__(self, x, y, radius):self._…

Stable Diffusion绘画 | ControlNet应用-qrcode 二维码控制器:艺术二维码来啦

qrcode 二维码控制器,是一款专用于生成艺术二维码的控制器, 需要单独下载,下载后,将文件放置在:SD安装目录\extensions\sd-webui-controlnet\models 实操 开启第一个 ControlNet,上传一个二维码图片&…

【24华为杯数模研赛赛题思路已出】国赛E题第二套思路丨附参考代码丨免费分享

2024年数模研赛E题解题思路 在高速公路建设中,通常会设置应急车道,以便应对救援和医疗需求。应急车道一般不允许占用,但在某些情况下,如监测到某路段即将拥堵且没有事故时,合理使用应急车道可以帮助降低车流密度&…

对不起,放弃了wiki.js转向了obsidian

wifi.js可以满足我的以下要求: 支持文档在线编辑支持浏览器编辑支持二进制文件上传和下载支持历史记录和回滚支持用户账号分权支持数据和nas同步支持markdown的预览模式 但是wiki.js不能满足如下: markdown编辑无法做到图片复制粘贴无法查看pdf无法独立于文档上传…

影刀RPA实战:网页爬虫之药品数据

1 实战目标 这次给大家带来的实战示例是采集中国医药信息平台上的药品数据,主要获取药品名称,介绍,药品类型,处方类型,医保类型,参考价格,药品成分,性状,适应病症&#…

SAP B1 Web Client MS Teams App集成连载四

过程/Procedure: 1.通过点击选项卡旁边的下拉箭头,可以重新配置、重命名和移除现有选项卡。 You can reconfigure, rename and remove an existing tab by clicking the drop down arrow alongside the tab. 要重新配置选项卡,请选择“设置”…