OAK相机如何将 YOLO NAS 模型转换成blob格式?

news/2024/5/20 23:51:31/文章来源:https://blog.csdn.net/oakchina/article/details/130519588

编辑:OAK中国
首发:oakchina.cn
喜欢的话,请多多👍⭐️✍
内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。

▌前言

Hello,大家好,这里是OAK中国,我是助手君。

最近咱社群里有几个朋友在将yolo转换成blob的过程有点不清楚,所以我就写了这篇博客。(请夸我贴心!咱的原则:合理要求,有求必应!)

1.其他Yolo转换及使用教程请参考
2.检测类的yolo模型建议使用在线转换(地址),如果在线转换不成功,你再根据本教程来做本地转换。

.pt 转换为 .onnx

使用下列脚本将 YOLO NAS 模型转换为 onnx 模型,若已安装 openvino_dev,则可进一步转换为 OpenVINO 模型:

安装依赖:

pip install super_gradients

示例用法:

python export_yolo_nas.py -m yolo_nas_s -imgsz 640 
usage: export_yolo_nas.py [-h] [-m {yolo_nas_s,yolo_nas_m,yolo_nas_l}] [-imgsz IMG_SIZE [IMG_SIZE ...]][-op OPSET] [-n NAME] [-o OUTPUT_DIR] [-b] [-s] [-sh SHAVES][-t {docker,blobconverter,local}]Tool for converting YOLO NAS models to the blob format used by OAKoptional arguments:-h, --help            show this help message and exit-m {yolo_nas_s,yolo_nas_m,yolo_nas_l}, -i {yolo_nas_s,yolo_nas_m,yolo_nas_l}, -w {yolo_nas_s,yolo_nas_m,yolo_nas_l}, --input_model {yolo_nas_s,yolo_nas_m,yolo_nas_l}model name (default: yolo_nas_s)-imgsz IMG_SIZE [IMG_SIZE ...], --img-size IMG_SIZE [IMG_SIZE ...]image size (default: [640, 640])-op OPSET, --opset OPSETopset version (default: 12)-n NAME, --name NAME  The name of the model to be saved, none means using the same name as the inputmodel (default: None)-o OUTPUT_DIR, --output_dir OUTPUT_DIRDirectory for saving files, none means using the same path as the input model(default: None)-b, --blob            OAK Blob export (default: False)-s, --spatial_detectionInference with depth information (default: False)-sh SHAVES, --shaves SHAVESInference with depth information (default: None)-t {docker,blobconverter,local}, --convert_tool {docker,blobconverter,local}Which tool is used to convert, docker: should already have docker(https://docs.docker.com/get-docker/) and docker-py (pip install docker)installed; blobconverter: uses an online server to convert the model and shouldalready have blobconverter (pip install blobconverter); local: use openvino-dev(pip install openvino-dev) and openvino 2022.1 (https://docs.oakchina.cn/en/latest/pages/Advanced/Neural_networks/local_convert_openvino.html#id2) to convert(default: blobconverter)

export_yolo_nas.py :

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import argparse
import json
import time
import warnings
from io import BytesIO
from pathlib import Pathimport torch
import torch.nn as nnwarnings.filterwarnings("ignore")ROOT = Path(__file__).resolve().parentyolo_nas = ["yolo_nas_s","yolo_nas_m","yolo_nas_l",
]class DetectNAS(nn.Module):"""YOLO-NAS Detect head for detection models"""def __init__(self, old_detect):super().__init__()self.num_classes = old_detect.num_classes  # number of classesself.reg_max = old_detect.reg_maxself.num_heads = old_detect.num_headsself.proj_conv = old_detect.proj_convfor i in range(self.num_heads):setattr(self, f"head{i + 1}", getattr(old_detect, f"head{i + 1}"))def forward(self, feats):output = []for i, feat in enumerate(feats):b, _, h, w = feat.shapeheight_mul_width = h * wreg_distri, cls_logit = getattr(self, f"head{i + 1}")(feat)reg_dist_reduced = torch.permute(reg_distri.reshape([-1, 4, self.reg_max + 1, height_mul_width]), [0, 2, 3, 1])reg_dist_reduced = nn.functional.conv2d(nn.functional.softmax(reg_dist_reduced, dim=1), weight=self.proj_conv).squeeze(1)# cls and regpred_scores = cls_logit.sigmoid()pred_conf, _ = pred_scores.max(1, keepdim=True)pred_bboxes = torch.permute(reg_dist_reduced, [0, 2, 1])output.append(torch.cat([pred_bboxes.reshape([-1, 4, h, w]), pred_conf, pred_scores], dim=1))return outputdef parse_args():parser = argparse.ArgumentParser(description="Tool for converting Yolov8 models to the blob format used by OAK",formatter_class=argparse.ArgumentDefaultsHelpFormatter,)parser.add_argument("-m","-i","-w","--input_model",type=str,help="model name ",default="yolo_nas_s",choices=yolo_nas,)parser.add_argument("-imgsz","--img-size",nargs="+",type=int,default=[640, 640],help="image size",)  # height, widthparser.add_argument("-op", "--opset", type=int, default=12, help="opset version")parser.add_argument("-n","--name",type=str,help="The name of the model to be saved, none means using the same name as the input model",)parser.add_argument("-o","--output_dir",type=Path,help="Directory for saving files, none means using the same path as the input model",)parser.add_argument("-b","--blob",action="store_true",help="OAK Blob export",)parser.add_argument("-s","--spatial_detection",action="store_true",help="Inference with depth information",)parser.add_argument("-sh","--shaves",type=int,help="Inference with depth information",)parser.add_argument("-t","--convert_tool",type=str,help="Which tool is used to convert, docker: should already have docker (https://docs.docker.com/get-docker/) and docker-py (pip install docker) installed; blobconverter: uses an online server to convert the model and should already have blobconverter (pip install blobconverter); local: use openvino-dev (pip install openvino-dev) and openvino 2022.1 ( https://docs.oakchina.cn/en/latest /pages/Advanced/Neural_networks/local_convert_openvino.html#id2) to convert",default="blobconverter",choices=["docker", "blobconverter", "local"],)parse_arg = parser.parse_args()if parse_arg.name is None:parse_arg.name = parse_arg.input_modelif parse_arg.output_dir is None:parse_arg.output_dir = ROOT.joinpath(parse_arg.input_model)parse_arg.output_dir = parse_arg.output_dir.resolve().absolute()parse_arg.output_dir.mkdir(parents=True, exist_ok=True)parse_arg.img_size *= 2 if len(parse_arg.img_size) == 1 else 1  # expandif parse_arg.shaves is None:parse_arg.shaves = 5 if parse_arg.spatial_detection else 6return parse_argdef export(input_model, img_size, output_model, opset, **kwargs):t = time.time()from super_gradients.training import models# Load PyTorch modelmodel = models.get("yolo_nas_s", pretrained_weights="coco")labels = model._class_names  # get class nameslabels = labels if isinstance(labels, list) else list(labels.values())# check num classes and labelsassert model.num_classes == len(labels), f"Model class count {model.num_classes} != len(names) {len(labels)}"# Replace with the custom Detection Headmodel.heads = DetectNAS(model.heads)num_branches = model.heads.num_heads# Inputimg = torch.zeros(1, 3, *img_size)model.eval()model.prep_model_for_conversion(input_size=[1, 3, *img_size])y = model(img)  # dry runs# ONNX exporttry:import onnxprint()print("Starting ONNX export with onnx %s..." % onnx.__version__)output_list = ["output%s_yolov6r2" % (i + 1) for i in range(num_branches)]with BytesIO() as f:torch.onnx.export(model,img,f,verbose=False,opset_version=opset,input_names=["images"],output_names=output_list,)# Checksonnx_model = onnx.load_from_string(f.getvalue())  # load onnx modelonnx.checker.check_model(onnx_model)  # check onnx modeltry:import onnxsimprint("Starting to simplify ONNX...")onnx_model, check = onnxsim.simplify(onnx_model)assert check, "assert check failed"except ImportError:print("onnxsim is not found, if you want to simplify the onnx, "+ "you should install it:\n\t"+ "pip install -U onnxsim onnxruntime\n"+ "then use:\n\t"+ f'python -m onnxsim "{output_model}" "{output_model}"')except Exception:print("Simplifier failure")onnx.save(onnx_model, output_model)print("ONNX export success, saved as:\n\t%s" % output_model)except Exception:print("ONNX export failure")# generate anchors and sidesanchors = []# generate masksmasks = dict()print("anchors:\n\t%s" % anchors)print("anchor_masks:\n\t%s" % masks)export_json = output_model.with_suffix(".json")export_json.write_text(json.dumps({"nn_config": {"output_format": "detection","NN_family": "YOLO","input_size": f"{img_size[0]}x{img_size[1]}","NN_specific_metadata": {"classes": model.num_classes,"coordinates": 4,"anchors": anchors,"anchor_masks": masks,"iou_threshold": 0.3,"confidence_threshold": 0.5,},},"mappings": {"labels": labels},},indent=4,))print("Anchors data export success, saved as:\n\t%s" % export_json)# Finishprint("Export complete (%.2fs).\n" % (time.time() - t))def convert(convert_tool, output_model, shaves, output_dir, name, **kwargs):t = time.time()export_dir: Path = output_dir.joinpath(name + "_openvino")export_dir.mkdir(parents=True, exist_ok=True)export_xml = export_dir.joinpath(name + ".xml")export_blob = export_dir.joinpath(name + ".blob")if convert_tool == "blobconverter":from zipfile import ZIP_LZMA, ZipFileimport blobconverterblob_path = blobconverter.from_onnx(model=str(output_model),data_type="FP16",shaves=shaves,use_cache=False,version="2022.1",output_dir=export_dir,optimizer_params=["--scale=255","--reverse_input_channel","--use_new_frontend",],download_ir=True,)with ZipFile(blob_path, "r", ZIP_LZMA) as zip_obj:for name in zip_obj.namelist():zip_obj.extract(name,output_dir,)blob_path.unlink()elif convert_tool == "docker":import dockerexport_dir_in_docker = Path("/io").joinpath(export_dir.name)export_xml_in_docker = export_dir_in_docker.joinpath(name + ".xml")export_blob_in_docker = export_dir_in_docker.joinpath(name + ".blob")client = docker.from_env()image = client.images.pull("openvino/ubuntu20_dev", tag="2022.1.0")docker_output = client.containers.run(image=image.tags[0],command=f'bash -c "mo -m {name}.onnx -n {name} -o {export_dir_in_docker} '+ "--static_shape --reverse_input_channels --scale=255 --use_new_frontend "+ "&& echo 'MYRIAD_ENABLE_MX_BOOT NO' | tee /tmp/myriad.conf >> /dev/null "+ "&& /opt/intel/openvino/tools/compile_tool/compile_tool -m "+ f"{export_xml_in_docker} -o {export_blob_in_docker} -ip U8 -VPU_NUMBER_OF_SHAVES {shaves} "+ f'-VPU_NUMBER_OF_CMX_SLICES {shaves} -d MYRIAD -c /tmp/myriad.conf"',remove=True,volumes=[f"{output_dir}:/io",],working_dir="/io",)print(docker_output.decode("utf8"))else:import subprocess as sp# OpenVINO exportprint("Starting to export OpenVINO...")OpenVINO_cmd = "mo --input_model %s --output_dir %s --data_type FP16 --scale 255 --reverse_input_channel" % (output_model, export_dir)try:sp.check_output(OpenVINO_cmd, shell=True)print("OpenVINO export success, saved as %s" % export_dir)except sp.CalledProcessError:print("")print("OpenVINO export failure!")print("By the way, you can try to export OpenVINO use:\n\t%s" % OpenVINO_cmd)# OAK Blob exportprint("Then you can try to export blob use:")blob_cmd = ("echo 'MYRIAD_ENABLE_MX_BOOT ON' | tee /tmp/myriad.conf"+ "compile_tool -m %s -o %s -ip U8 -d MYRIAD -VPU_NUMBER_OF_SHAVES %s -VPU_NUMBER_OF_CMX_SLICES %s -c /tmp/myriad.conf"% (export_xml, export_blob, shaves, shaves))print("%s" % blob_cmd)print("compile_tool maybe in the path: /opt/intel/openvino/tools/compile_tool/compile_tool, if you install openvino 2022.1 with apt")print("Blob file saved as:\n\t%s" % export_blob)print("Convert complete (%.2fs).\n" % (time.time() - t))if __name__ == "__main__":args = parse_args()print(args)output_model = args.output_dir / (args.name + ".onnx")export(output_model=output_model, **vars(args))if args.blob:convert(output_model=output_model, **vars(args))

可以使用 Netron 查看模型结构:
在这里插入图片描述

▌转换

openvino 本地转换

onnx -> openvino

mo 是 openvino_dev 2022.1 中脚本,安装命令为 pip install openvino-dev

mo --input_model yolo_nas_s.onnx --scale 255 --reverse_input_channel

openvino -> blob

<path>/compile_tool -m yolo_nas_s.xml \
-ip U8 -d MYRIAD \
-VPU_NUMBER_OF_SHAVES 6 \
-VPU_NUMBER_OF_CMX_SLICES 6

在线转换

blobconvert 网页 http://blobconverter.luxonis.com/

  • 进入网页,按下图指示操作:
    在这里插入图片描述
  • 修改参数,转换模型:
    在这里插入图片描述
    1. 选择 onnx 模型
    2. 修改 optimizer_params--data_type=FP16 --scale 255 --reverse_input_channel
    3. 修改 shaves6
    4. 转换

blobconverter python 代码

blobconverter.from_onnx("yolo_nas_s.onnx",	optimizer_params=["--scale 255","--reverse_input_channel",],shaves=6,)

blobconvert cli

blobconverter --onnx yolo_nas_s.onnx -sh 6 -o . --optimizer-params "scale=255 --reverse_input_channel"

▌DepthAI 示例

正确解码需要可配置的网络相关参数:

  • setNumClasses – YOLO 检测类别的数量
  • setIouThreshold – iou 阈值
  • setConfidenceThreshold – 置信度阈值,低于该阈值的对象将被过滤掉
# coding=utf-8
import cv2
import depthai as dai
import numpy as npnumClasses = 80
model = dai.OpenVINO.Blob("yolo_nas_s.blob")
dim = next(iter(model.networkInputs.values())).dims
W, H = dim[:2]output_name, output_tenser = next(iter(model.networkOutputs.items()))
if "yolov6" in output_name:numClasses = output_tenser.dims[2] - 5
else:numClasses = output_tenser.dims[2] // 3 - 5labelMap = [# "class_1","class_2","...""class_%s" % ifor i in range(numClasses)
]# Create pipeline
pipeline = dai.Pipeline()# Define sources and outputs
camRgb = pipeline.create(dai.node.ColorCamera)
detectionNetwork = pipeline.create(dai.node.YoloDetectionNetwork)
xoutRgb = pipeline.create(dai.node.XLinkOut)
xoutNN = pipeline.create(dai.node.XLinkOut)xoutRgb.setStreamName("image")
xoutNN.setStreamName("nn")# Properties
camRgb.setPreviewSize(W, H)
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
camRgb.setInterleaved(False)
camRgb.setColorOrder(dai.ColorCameraProperties.ColorOrder.BGR)# Network specific settings
detectionNetwork.setBlob(model)
detectionNetwork.setConfidenceThreshold(0.5)# Yolo specific parameters
detectionNetwork.setNumClasses(numClasses)
detectionNetwork.setCoordinateSize(4)
detectionNetwork.setAnchors([])
detectionNetwork.setAnchorMasks({})
detectionNetwork.setIouThreshold(0.5)# Linking
camRgb.preview.link(detectionNetwork.input)
camRgb.preview.link(xoutRgb.input)
detectionNetwork.out.link(xoutNN.input)# Connect to device and start pipeline
with dai.Device(pipeline) as device:# Output queues will be used to get the rgb frames and nn data from the outputs defined aboveimageQueue = device.getOutputQueue(name="image", maxSize=4, blocking=False)detectQueue = device.getOutputQueue(name="nn", maxSize=4, blocking=False)frame = Nonedetections = []# nn data, being the bounding box locations, are in <0..1> range - they need to be normalized with frame width/heightdef frameNorm(frame, bbox):normVals = np.full(len(bbox), frame.shape[0])normVals[::2] = frame.shape[1]return (np.clip(np.array(bbox), 0, 1) * normVals).astype(int)def drawText(frame, text, org, color=(255, 255, 255), thickness=1):cv2.putText(frame, text, org, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), thickness + 3, cv2.LINE_AA)cv2.putText(frame, text, org, cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, thickness, cv2.LINE_AA)def drawRect(frame, topLeft, bottomRight, color=(255, 255, 255), thickness=1):cv2.rectangle(frame, topLeft, bottomRight, (0, 0, 0), thickness + 3)cv2.rectangle(frame, topLeft, bottomRight, color, thickness)def displayFrame(name, frame):color = (128, 128, 128)for detection in detections:bbox = frameNorm(frame, (detection.xmin, detection.ymin, detection.xmax, detection.ymax))drawText(frame=frame,text=labelMap[detection.label],org=(bbox[0] + 10, bbox[1] + 20),)drawText(frame=frame,text=f"{detection.confidence:.2%}",org=(bbox[0] + 10, bbox[1] + 35),)drawRect(frame=frame,topLeft=(bbox[0], bbox[1]),bottomRight=(bbox[2], bbox[3]),color=color,)# Show the framecv2.imshow(name, frame)while True:imageQueueData = imageQueue.tryGet()detectQueueData = detectQueue.tryGet()if imageQueueData is not None:frame = imageQueueData.getCvFrame()if detectQueueData is not None:detections = detectQueueData.detectionsif frame is not None:displayFrame("rgb", frame)if cv2.waitKey(1) == ord("q"):break

▌参考资料

https://www.oakchina.cn/tag/yolo/
https://docs.oakchina.cn/en/latest/
https://www.oakchina.cn/selection-guide/


OAK中国
| OpenCV AI Kit在中国区的官方代理商和技术服务商
| 追踪AI技术和产品新动态

戳「+关注」获取最新资讯↗↗

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

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

相关文章

k8s pv pvc的使用

k8s pv pvc的使用 安装nfs服务器 yum install rpcbind nfs-utils -y systemctl enable rpcbind systemctl enable nfs systemctl start rpcbind systemctl start nfsmkdir -p /root/data/sc-data [rootmaster sc-data]# cat /etc/exports /root/data/sc-data 192.168.1.0/24(…

运营商三要素验证原理,这篇文章就够了!

引言 运营商三要素验证 API 是一种基于手机号码、身份证号码和姓名等三种信息的验证服务&#xff0c;主要用于验证用户身份信息的真实性和一致性&#xff0c;以及查询手机号码所属的运营商信息。 运营商三要素 API 的验证原理 1. 身份验证的原理 身份信息验证是运营商三要素…

系统安全分析与设计

目录 第五章、系统安全分析与设计1、信息系统安全属性2、对称加密技术与非对称加密技术3、信息摘要4、数字签名5、数字信封与PGP6、网络安全6.1、各个网络层次的安全保障6.2、网络威胁与攻击6.3、防火墙 第五章、系统安全分析与设计 1、信息系统安全属性 安全属性 保密性&…

JavaScript实现求1-100之间不能被3整除的数之和,求100以内偶数的和的两个程序代码

以下为实现求1-100之间不能被3整除数之和求100以内偶数的和的两个程序代码和运行截图 目录 前言 一、实现输入两个数比较两个数的大小 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 二、求100以内偶数的和 2.1 运行流程及思想 2.2 代码段 2.3…

北峰通信,用专业打造“全方位、立体化”应急通信保障体系

最近热映的电影《惊天救援》里&#xff0c;杜江饰演的消防员韩凯&#xff0c;在一次化工园区发生爆炸后&#xff0c;他作为消防救援站里的通信员&#xff0c;第一时间奔赴重灾区&#xff0c;及时将第一现场的情况传到了后方指挥部。 众所周知&#xff0c;通讯系统是生命线系统的…

685页40万字某省市场监管智慧应用一体化项目(word可编辑)

1.2.3.1 数字XX公共能力建设现状 1.2.3.1.1 数字XX通用基础应用平台现状 通用基础应用平台提供具有共性特征的跨部门、跨层级业务应用&#xff0c;与本项目有关的平台包括某省网上办事大厅、某省政务服务 APP 统一平台&#xff08;X政通 APP&#xff09;、某省公共信用信息平…

rk3568 修改开机logo

rk3568 修改开机显示logo Android 显示 logo 的作用是为了标识应用程序或设备的品牌和身份。在应用程序中&#xff0c;logo 可以帮助用户快速识别应用程序&#xff0c;并与其他应用程序区分开来。在设备中&#xff0c;logo 可以帮助用户识别设备的品牌和型号&#xff0c;以及与…

python操作集合

# 集合 l{1,2,1} print(l) sset(range(5)) print(s)# 判断in 或 not in print(5 not in l) # 集合元素新增操作 l.add(4) l.update(1,3,6) print(l) l.update((1,3,5)) l.update([4,4,6]) # 删除集合元素 l.remove(2) l.discard(2) # 无目的的删除 自己不带参数 l.pop() l.cl…

AutoCV第七课:ML基础

目录 ML基础前言1. 复习sqrt函数2. 线性回归预测房价2.1 问题分析2.2 代码实现2.3 总结 个人总结 ML基础 前言 手写AI推出的全新保姆级从零手写自动驾驶CV课程&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考。 本次课程主要学习复习 sqrt 函数和线性回归预测房…

【C++】-const对象及成员函数之类和对象中篇完结(中)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树 ❤️‍&#x1fa79;作者宣言&#xff1a;认真写好每一篇博客 &#x1f4a8;作者gitee:gitee &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 文章目录 前言一、案例的引入二、const对象和成员函数三、取地…

【2023 · CANN训练营第一季】应用开发深入讲解——第三章应用调试

学习资源 日志参考文档 应用开发FAQ 日志主要用于记录系统的运行过程及异常信息&#xff0c;帮助快速定位系统运行过程中出现的问题以及开发过程中的程序调试问题。 日志分为如下两大类&#xff1a; 系统类日志&#xff1a;系统运行产生的日志。主要包括&#xff1a; Contro…

【跟着陈七一起学C语言】今天总结:函数、数组、指针之间的关系

友情链接&#xff1a;专栏地址 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的错误&#x…

数智无限|东土科技科东软件5月活动预告

这个5月&#xff0c;东土科技&科东软件将携带自主研发的国产操作系统Intewell、智能控制通用工具软件MaVIEW、边缘通用控制器NewPre、基于TSN技术的智能化工业网络硬件、数字工厂智能产线一站式解决方案&#xff0c;以及面向智能工厂的离散控制、流程控制、运动控制、机器人…

第十四届蓝桥杯大赛软件赛省赛(Java 大学A组)

蓝桥杯 2023年省赛真题 Java 大学A组 试题 A: 特殊日期  试题 B: 与或异或 把填空挂上跟大伙对对答案&#xff0c;先把C/C B组的做了。 试题 A: 特殊日期 本题总分&#xff1a;5 分 【问题描述】 记一个日期为 y y \small yy yy 年 m m \small mm mm 月 d d \small dd dd 日…

Cron表达式X分钟执行一次的设计缺陷。SQL JOIN的设计缺陷。在线Cron表达式网站的缺陷。Spring 定时任务的年问题。

Cron Cron表达式 定时任务计划任务 Chronological英 /ˌkrɒnəˈlɒdʒɪk(ə)l/adj. 按发生时间顺序排列的&#xff1b;&#xff08;年龄&#xff09;按时间计算的1. 月 周设计精妙吗&#xff1f; 学习 0/5 * * * * ? * 秒 分 时 日 月 周 年1. 年一般省略。为&#xf…

Vue-弹层显示样式

弹层显示样式1 1.先将左侧样式写 <template><div classhome-category><ul class"menu"><li v-for"i in 10" :key"i"><RouterLink to"/">居家</RouterLink><RouterLink to"/">洗…

入门级的家用洗地机怎么样?入门级洗地机推荐

洗地机的功能有很多&#xff0c;比如除菌、洗地机清洁地面的确是一把好手。但是&#xff01;清洁完之后还要手动清洗洗地机&#xff0c;是一件麻烦事啊&#xff01;现在市面上大部分洗地机都有自清洁这个功能&#xff0c;但是很多洗地机的自清洁并不算真正的自清洁&#xff0c;…

6.其他函数

1.时间日期类 -- current_date() 返回当前日期 -- date_add(date, n) 返回从date开始n天之后的日期 -- date_sub(date, n) 返回从date开始n天之前的日期 -- datediff(date1, date2) 返回date1-date2的日期差 -- year(date) 返回…

创新指南|5大策略让创新业务扩张最大避免“增长痛苦”

公司在开发和孵化新业务计划方面进行了大量投资&#xff0c;但很少有公司遵循严格的途径来扩大新业务规模。虽然80%的公司声称构思和孵化新企业&#xff0c;但只有16%的公司成功扩大了规模。典型案例是百思买在许多失败倒闭的扩大新业务取得了成功。它经历了建立新业务所需的3个…

EC6108V9/V9C-Hi3798MV100-当贝纯净桌面-卡刷固件包

EC6108V9&#xff0f;V9C-Hi3798MV100-当贝纯净桌面-卡刷固件包-内有教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用的软…