RGB的意思是红色(Red)、绿色(Green)和蓝色(Blue)
rgb565 是16位(2字节)
565表示在16位编码中每个颜色分量所占的位数。红色占5个bit,绿色占6个bit,蓝色占5个bit。
argb888 是32位 (4字节)
888表示红色占8个bit,绿色占8个bit,蓝色占8个bit,还有a表示透明度,也是占8个bit
那么一个像素点占8+8+8+8=32位(4字节)
直接贴参考代码
//将渲染后的Surface转换成Bitmap void MySample_SurfaceWord_ToBMP(SDL_Surface *surface,BITMAP_S *stBitmap,SDL_Color fntcol) { unsigned short words_color = ((fntcol.r >> 3) << 11) + ((fntcol.g >> 2) << 5) + (fntcol.b >> 3); //字体颜色 unsigned short bck_color = 0xffff - words_color; //字体以外的背景颜色 stBitmap->u32Height = (surface->h); //BITMAP 的宽高向上2对齐 stBitmap->u32Width = (surface->w); stBitmap->pData = malloc(4*(stBitmap->u32Height)*(stBitmap->u32Width)); //申请空间,ARGB8888=>4Byte/Pixel,总大小为4*w*h memset(stBitmap->pData,0,4*(stBitmap->u32Height)*(stBitmap->u32Width)); int i,j; int w = surface->w; int h = surface->h; for (i = 0; i < h; ++i) { RK_U32 *p_dst = (RK_U32*)stBitmap->pData; RK_U16 *p_src = (RK_U16*)surface->pixels; int dis_pos = 0; if(w % 2 !
进行rtmp推流时,使用wireshark抓包,发现部分包显示Unknown
解决方法:
编辑 -> 首选项 -> Protocols -> RTMPT,这里Maximum packet size默认是32768
将该值调大,比如调成1048576,即可解决该问题。
参考:《解决Wireshark分析RTMP抓包时Unknown问题》
vue3版本vue3-element-admin 1.官网资源(我这个资源文件夹是配置好的,不用下载依赖了,可以直接npm start运行,下面只是介绍下官网是怎么操作的) vue3-element-admin官网(非TS版,为JS的,这个文件夹的项目也是从这个官网下载过来的)
官网地址: https://huzhushan.gitee.io/vue3-element-admin/guide/
效果展示: https://huzhushan.gitee.io/vue3-element-admin-site/#/home
项目需要先安装依赖再运行
# 克隆项目 git clone https://github.com/huzhushan/vue3-element-admin.git # 进入项目目录 cd vue3-element-admin # 安装依赖 npm install # 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题(或者使用yarn install 一样的效果) npm install --registry=https://registry.npm.taobao.org # 启动服务 npm start 运行成功会发现加载不了页面,有个请求资源404,
在src下找到permission.js,找到以下代码(import { TOKEN } from ‘@/store/modules/app’)换成import { TOKEN } from '@/pinia/modules/app’即可解决
2.别人封装的资源(可以作为参考,TS版本) 这里附上一个别人写的基于vue3-element-admin+TS+vite版本的封装展示
gitee地址: https://gitee.com/youlaiorg/vue3-element-admin/tree/master/src
博客地址: https://juejin.cn/post/7228990409909108793
效果展示: https://vue3.youlai.tech/#/
vue2版本的vue-element-admin 上面的压缩包是已经配好了的,直接npm run dev运行即可
基于vue2+element的后台管理系统
官方文档:https://panjiachen.github.io/vue-element-admin-site/zh/guide/#%E5%8A%9F%E8%83%BD
gitee地址:https://gitee.com/panjiachen/vue-element-admin?utm_source=alading&utm_campaign=repo(不是克隆的地址,是页面地址)
# 克隆项目 git clone https://github.
最近需要扩大公司新项目环境,新买够了,四台二层交换机和两台三层交换机,二层交换机型号为H3C S5120,三层交换机为H3C S5500,因为项目有关于国家项目,必须使用国产网络设备,现在需要对四台交换机做两组堆叠,但是我们尝试使用四台交换机进行做堆叠结果也是成功,没有什么问题,但是配置有一些差异,需要对堆叠逻辑端口进行理解。
IRF( Intelligent Resilient Framework,智能弹性架构)是 H3C 自主研发的软件虚拟化技术。它的核心思想是将多台设备通过 IRF 物理端口连接在一起,进行必要的配置后,虚拟化成一台“分布式设备”。使用这种虚拟化技术可以集合多台设备的硬件资源和软件处理能力,实现多台设备的协同工作、统一管理和不间断维护。为了便于描述,这个“虚拟设备”也称为 IRF。所以,本文中的 IRF 有两层意思,一个是指 IRF 技术,一个是指 IRF 设备。
IRF 主要具有以下优点:
简化管理: IRF 形成之后,用户通过任意成员设备的任意端口都可以登录 IRF 系统,对 IRF内所有成员设备进行统一管理。高可靠性:IRF 的高可靠性体现在多个方面,例如: IRF 由多台成员设备组成, Master 设备负责 IRF 的运行、管理和维护, Slave 设备在作为备份的同时也可以处理业务。一旦 Master 设备故障,系统会迅速自动选举新的 Master,以保证业务中断,从而实现了设备的 1:N 备份;此外,成员设备之间的 IRF 链路支持聚合功能, IRF 和上、下层设备之间的物理链路也支持聚合功能,多条链路之间可以互为备份也可以进行负载分担,从而进一步提高了 IRF 的可靠性。强大的网络扩展能力:通过增加成员设备,可以轻松自如的扩展 IRF 的端口数、带宽。因为各成员设备都有 CPU,能够独立处理协议报文、进行报文转发,所以 IRF 还能够轻松自如的扩展处理能力。 两台配置堆叠流程
两台二层交换机堆叠网络拓扑图
1. master配置 1.设置端口号,因为堆叠是将两台交换机逻辑上变成一台交换机需要将交换机设置不同的端口 号如G0/0/1,G1/0/1,他们就是两台交换机同一位置的端口号,默认为0,看个人习惯,可以将0改为1,后面交换机以此类推。
需要进行重启,服务生效
[H3C] irf member 0 renumber 1 <H3C>save <H3C>reboot 2.设置irf成员优先级,在S5120型号下,优先级被限制于1-32,不同交换机有所不同,优先级越高,成为master的机会越大。
需要进行重启生效
#配置irf成员及优先级 [H3C]irf member 1 priority 30 [H3C]quit [H3C]save <H3C>reboot 3.
前言 现在后端管理系统主页面基本都是由三部分组成 查询条件,高度不固定,可能有的页面查询条件多,有的少表格,高度不固定,占据页面剩余高度分页,高度固定 这三部分加起来肯定是占满全屏的,那么我们可以结合flex布局,来实现。 代码及效果 app.vue 相当于页面首页 <template> <div id="app"> <!-- 假设为页头内容,导航等...--> <div class="routers"> <router-link :to="item.path" v-for="item in routerLinks" :key="item.name">{{ item.name }}</router-link> </div> <!-- 内容区域 --> <div class="content"> <router-view /> </div> </div> </template> <script> export default { data() { return { routerLinks: [], }; }, created() { this.handleRouterLink(); }, methods: { handleRouterLink() { // 获取所有路由配置 this.routerLinks = this.$router.getRoutes(); }, }, }; </script> <style lang="scss" scoped> #app { height: 100vh; display: flex; flex-direction: column; } .
题目 编写一个高效的算法来搜索 m * n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例 1:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
示例 2:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false
答案 这道题可以使用二分查找来解决。由于每行的元素从左到右升序排列,每列的元素从上到下升序排列,因此对于每个位置,其左下角的元素一定小于当前元素,其右上角的元素一定大于当前元素。我们可以利用这个性质进行二分查找。
以下是实现这个算法的 Python 代码:
def searchMatrix(matrix, target): if not matrix or not matrix[0]: # 判断矩阵是否为空 return False rows, cols = len(matrix), len(matrix[0]) # 获取矩阵的行数和列数 left, right = 0, rows * cols - 1 # 初始化搜索范围 while left <= right: # 当搜索范围非空时 mid = (left + right) // 2 # 计算中间位置 row, col = divmod(mid, cols) # 计算中间位置在矩阵中的行列信息 if matrix[row][col] == target: # 如果中间位置的元素等于目标值 return True elif matrix[row][col] < target: # 如果中间位置的元素小于目标值 left = mid + 1 # 目标值可能在右侧,更新搜索范围 else: # 如果中间位置的元素大于目标值 right = mid - 1 # 目标值可能在左侧,更新搜索范围 return False # 没有找到目标值,返回 False
下载地址:
GitHub - Bing-su/adetailer: Auto detecting, masking and inpainting with detection model. 修复介绍:
具体的得根据实际情况进行选择。 模型适用对象face_yolov8n.pt2D / 真实人脸face_yolov8s.pt2D / 真实人脸hand_yolov8n.pt2D / 真实人手person_yolov8n-seg.pt2D / 真实全身person_yolov8s-seg.pt2D/真实全身mediapipe_face_full真实人脸mediapipe_face_short真实人脸mediapipe_face_mesh真实人脸 测试语句:
正向:
Star face,long black hair,beauty,wearing a white shirt,upper body frontal photo,ultra-clear,cute,lolita,natural black pupils,bright eyes,Chinese style,well-proportioned,regular facial features,no stretching,first love,light blue Color background,tie,campus,desks and chairs,school uniform,long hair to waist,smile,dimples,
反向:
(semi-realistic, cgi, 3d, render, sketch, cartoon, drawing, anime:1.4),text,close up,cropped,out of frame,worst quality,low quality,jpeg artifacts,pgly,duplicate,morbid,mutilated,extra fingers,mutated hands,poorly drawn hands,poorly drawn face,mutation,deformed,blurry,dehydrated,bad anatomy,bad proportions,extra limbs,cloned face,disfigured,gross proportions,malformed limbs,missing arms,missing legs,extra arms,extra legs,fused fingers,too many fingers,long neck,
题目 给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
答案 要实现这个题目,我们可以使用递归的方法。具体来说,我们可以将矩阵的每一行看作是一个单独的子矩阵。首先,我们将子矩阵的最后一行(即最初的第 n 列)复制到新的第一行(即旋转后的第 n 列)。然后,我们将子矩阵的最后一列(即最初的第 n 行)复制到新的第一列(即旋转后的第 n 行)。最后,我们将子矩阵本身旋转。这就得到了旋转后的子矩阵。我们可以通过递归地应用这个过程来旋转整个矩阵。
以下是实现这个算法的 Python 代码:
def rotate(matrix): n = len(matrix) # 如果矩阵只有一行或一列,直接反转即可 if n == 1: matrix.reverse() return matrix # 将子矩阵的最后一行(即最初的第 n 列)复制到新的第一行(即旋转后的第 n 列) matrix[0][n-1:n] = matrix[0][n-1:n][::-1] # 将子矩阵的最后一列(即最初的第 n 行)复制到新的第一列(即旋转后的第 n 行) for i in range(1, n): matrix[i][0:1] = matrix[i][0:1][::-1] # 递归地旋转子矩阵 for i in range(n-1): for j in range(n-1): matrix[i][j+1:n] = matrix[i][j+1:n][::-1] matrix[i+1:n][j] = matrix[i+1:n][j][::-1] return matrix 这个函数首先检查矩阵是否只有一行或一列。如果是这样,它将直接反转矩阵。否则,它将复制最初的第 n 列到新的第一列,复制最初的第 n 行到新的第一行,然后递归地旋转子矩阵。
文章目录 week 19 GAN3摘要Abstract一、李宏毅机器学习——GAN31. Introduce2. Difficulty in GAN training3. Evaluation of Generation4. Conditional Generation 二、文献阅读1. 题目2. abstract3. 文章主要内容3.1 基于GANs的双时间尺度更新规则3.2 Adam确保TTUR收敛3.2.1 使用Adam以降低收敛至局域最小的概率3.2.2 分析是否收敛的过程 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1 性能指标4.3.2 模型选择与评估4.3.3 图像数据上的WGAN-GP4.3.4 语言数据上的WGAN-GP 4.4 结论 三、pytorch实现diffusion模型1. 实验结果2. 实验代码小结参考文献 week 19 GAN3 摘要 本文主要讨论了生成式对抗神经网络。首先,本文介绍了GAN训练困难性以及其在训练过程中可能出现的问题。在此基础下,本文阐述了一种可以更好评估网络的标准——Fréchet Inception Distance(FID)。此外,本文简要介绍了Conditional GAN的各种应用以及大致框架。其次本文展示了题为GANs Trained by a Two Time-Scale Update Rule Converge to a Local Nash Equilibrium的论文主要内容。这篇论文提出了双时间尺度更新规则(TTUR),并证明了使用Adam和TTUR训练GAN的收敛性。同时,该文设计了一系列实验用于评估该方法的优越性并在实验中引入了FID作为评估标准。最后,本文基于pytorch实现了Diffusion并用于绘制S型曲线。
Abstract This article focuses on GAN. First of all, this article introduces the difficulty of GAN training and the problems that may arise during its training.
解决的办法是在ffmpeg命令后面加上“-fflags +genpts”参数重新生成pts
ffmpeg -fflags +genpts -i input.mp4 -vf scale=1280:720 -b:v 500k -vcodec libx264 -acodec aac -bf 0 output.mp4 参考:《FFMPEG转码视频源帧数据中没有PTS问题的解决》
文章目录 1、线性回归(Linear Regression)1.1 优点1.2 缺点1.3 适用场景1.4 图例说明 2、多项式回归(Polynomial Regression)2.1 优点2.2 缺点2.3 适用场景2.4 图例说明 3、决策树回归(Decision Tree Regression)3.1 优点3.2 缺点3.3 适用场景 4、随机森林回归(Random Forest Regression)4.1 优点4.2 缺点4.3 适用场景 5、逻辑斯蒂回归(Logistic Regression)5.1 优点5.2 缺点5.3 适用场景 6、弹性网络回归(Elastic Net Regression)6.1 优点6.2 缺点6.3 适用场景 7、岭回归(Ridge Regression)7.1 优点7.2 缺点7.3 适用场景 8、Lasso回归(Lasso Regression)8.1 优点8.2 缺点8.3 适用场景 回归的概念:回归算法是一种用于预测连续数值输出的监督学习算法,可以根据输入特征预测一个或多个目标变量。它有多个分支,每个分支都有其独特的优缺点。下面是深度学习中几类回归变种: 1、线性回归(Linear Regression) 线性回归算法可以说是回归算法里面最简单的一种。
1.1 优点 简单且易于解释。计算效率高,适用于大规模数据集。在特征与目标之间存在线性关系时效果良好。 1.2 缺点 无法处理非线性关系。对于一些异常值,无法做到拟合曲线。对异常值敏感。需要满足线性回归假设(如线性关系、残差正态分布等)。 1.3 适用场景 适用场景:预测数值型目标,建立输入特征和输出之间的线性关系。
案例:预测房价。根据房屋特征(面积、卧室数量等),建立线性关系来估计房价。
1.4 图例说明 代码:
import matplotlib.pyplot as plt import numpy as np # 设置中文显示 plt.
PromptIR: Prompting for All-in-One Blind Image Restoration, NeurIPS 2023 论文:https://arxiv.org/abs/2306.13090
代码:https://github.com/va1shn9v/promptir
解读:即插即用系列 | PromptIR:MBZUAI提出一种基于Prompt的全能图像恢复网络 - 知乎 (zhihu.com)
摘要 图像恢复是从其受损版本中恢复高质量清晰图像的过程。deep-learning方法显著提升了图像恢复性能,然而,它们在不同类型和级别的退化上的泛化能力有限。这限制了它们在实际应用中的使用,因为需要针对每种具体的退化进行单独训练模型,并了解输入图像的退化类型才能应用相应的模型。本文介绍了一种基于提示的学习方法,称为PromptIR,用于全能图像恢复,可以有效地从各种类型和级别的退化中恢复图像。具体而言,本文方法使用提示来编码退化特定信息,并动态引导恢复网络。 PromptIR提供了一个通用且高效的插件模块,只需少量轻量级提示即可用于恢复各种类型和级别的受损图像,无需事先了解图像中存在的损坏信息。
动机 图像恢复过程中,会由于各种客观因素或限制(相机设备、环境条件)出现各种退化现象。deep-learning方法虽然有用,但在特定的退化类型和程度之外缺乏泛化性。因此,迫切需要开发一种能够有效恢复各种类型和程度的退化图像的一体化方法。
AirNet,采用对比学习解决一体化恢复任务,但需要训练额外的编码器,会增加训练负担。
为此,本文提出了一种基于提示学习的方法来执行一体化图像恢复。该方法利用提示(一组可调参数),用于编码关于各种图像退化类型的重要区分信息。通过将提示与主恢复网络的特征表示相互作用,动态地增强表示,以获得具有退化特定知识的适应性,这种适应性使网络能够通过动态调整其行为有效地恢复图像。
该图显示了在PromptIR和AirNet中使用的退化嵌入的tSNE图。不同的颜色表示不同的退化类型。每个任务的嵌入更好地聚集在一起,显示了提示标记学习具有区分性的退化上下文的有效性,从而有助于恢复过程。 所提的Prompt 方法 本文PromptIR,提出了一个即插即用的提示模块,它隐式地预测与退化条件相关的提示,以引导具有未知退化的输入图像的恢复过程。来自提示的指导被注入到网络的多个解码阶段,其中包含少量可学习参数。 贡献 提出了一种基于提示的一体化恢复框架PromptIR,它仅依赖于输入图像来恢复清晰图像,而不需要任何关于图像中存在的退化的先验知识。本文prompt block 是一个可轻松集成到任何现有恢复网络中的插件模块。它由提示生成模块(PGM)和提示交互模块(PIM)组成。提示块的目标是生成与输入条件相关的提示(通过PGM),这些提示具有有用的上下文信息,以指导恢复网络(通过PIM)有效地消除输入图像中的破坏。本文实验证明了PromptIR的动态适应行为,在包括图像降噪、去雨和去雾在内的各种图像恢复任务上实现了最先进的性能。 方法 PromptIR “一体式”图像恢复的目标是,学习单个模型M,以从退化的图像中恢复干净图像,该图像已使用退化方式D退化,而没有关于D的先验信息。虽然该模型对退化方式“不可见”,可以通过提供关于退化类型的隐含上下文信息来增强其在恢复干净图像方面的性能。基于提示学习的图像恢复框架PromptIR,用于在恢复干净图像的同时用退化类型的相关知识补充模型。关键元素是 提示块prompt block。
PromptIR使用提示块来生成可学习的提示参数,并在恢复过程中利用这些提示来指导模型。框架通过逐级编码器-解码器将特征逐步转换为深层特征,并在解码器中引入提示块来辅助恢复过程。提示块在解码器的每个级别中连接,隐式地为输入特征提供关于退化类型的信息,以实现引导恢复。总体来说,PromptIR框架通过逐级编码和解码以及引入提示块的方式实现图像恢复任务。 Prompt Block 提示块 prompt block,由两个模块组成:提示生成模块(PGM)和提示交互模块(PIM)。
提示生成模块使用输入特征Fl和提示组件生成与输入条件相关的提示P。提示交互模块通过Transformer块使用生成的提示动态调整输入特征。提示与解码器特征在多个级别交互,以丰富特定于退化的上下文信息。 给N个prompt-components 和 input feature , prompt block 可表示为:
其中,PGM表示提示生成模块,PIM表示提示交互模块。
Prompt Generation Module (PGM) 提示组件 是一组可学习的参数,与输入特征交互,嵌入了退化信息。一种直接的特征-提示交互方法是直接使用学习到的提示来校准特征,可能会产生次优结果,因为它对输入内容是无知的。本文提出了提示生成模块(PGM),它从输入特征中动态预测基于注意力的权重,并将这些权重应用于提示组件,生成与输入条件相关的提示P。此外,PGM创建了一个共享空间,促进了提示组件之间的相关知识共享。PGM公式表达为:
Prompt Interaction Module (PIM) PIM的主要目标是实现输入特征和提示P之间的交互,以实现有指导的恢复过程。
在PIM中,沿着通道维度将生成的提示与输入特征进行拼接。接下来将拼接后的表示通过一个Transformer块进行处理,该块利用提示中编码的退化信息来转换输入特征。
本文的主要贡献是提示块,它是一个插件模块,与具体的架构无关。PromptIR框架中,使用了现有的Transformer块。Transformer块由两个顺序连接的子模块组成:多转置卷积头转置注意力(MDTA)和门控转置卷积前馈网络(GDFN)。MDTA在通道而不是空间维度上应用自注意操作,并具有线性复杂度。GDFN的目标是以可控的方式转换特征,即抑制信息较少的特征,只允许有用的特征在网络中传播。PIM的整体过程为:
实验 主要实验与可视化样例 全能恢复设置下的比较:
ES6 知识点及常考面试题 var、let 及 const 区别 涉及面试题:什么是提升?什么是暂时性死区?var、let 及 const 区别? 对于这个问题,我们应该先来了解提升(hoisting)这个概念。
console.log(a) // undefined var a = 1 从上述代码中我们可以发现,虽然变量还没有被声明,但是我们却可以使用这个未被声明的变量,这种情况就叫做提升,并且提升的是声明。
对于这种情况,我们可以把代码这样来看
var a console.log(a) // undefined a = 1 接下来我们再来看一个例子
var a = 10 var a console.log(a) 对于这个例子,如果你认为打印的值为 undefined 那么就错了,答案应该是 10,对于这种情况,我们这样来看代码
var a var a a = 10 console.log(a) 到这里为止,我们已经了解了 var 声明的变量会发生提升的情况,其实不仅变量会提升函数也会被提升。
console.log(a) // ƒ a() {} function a() {} var a = 1 对于上述代码,打印结果会是 ƒ a() {},即使变量声明在函数之后,这也说明了函数会被提升,并且优先于变量提升。
说完了这些,想必大家也知道 var 存在的问题了,使用 var 声明的变量会被提升到作用域的顶部,接下来我们再来看 let 和 const 。
在学习完堆的创建后,就轮到了标题的两个问题
这两个问题在实际生活中会有比较强的实际问题解决能力
先分别解释一下
堆排序:
运用堆的思想进行排序,时间复杂度为O(NlogN)TopK:
从一大堆数据中选择K个最大或最小的数据,我们简称tTopK 堆的创建,关于堆的详情请点击。
目录 堆排序:思想:代码实现:源代码: TopK:思想:代码实现:源代码: 堆排序: 思想: 假设我们有一个小堆为N个数,先在要对其排序,那么这个小堆适合什么排序呢?
答案是降序
绝大部分同学可能都会认为是升序,
因为最上边的元素是最小的,我们将第一个固定住,在对其后边N-1个再次进行建堆,就可以完美得到一个升序的数组,
注意:
但是我们忽略了建堆的时间复杂度为O(lNogN),对N个数进行建堆,比冒泡排序有过之而无不及,所以我们不会去用这样一个华而不实的方法
所以我们小堆其实更适合降序,将建堆之后的第一个元素与数组末尾进行交换,再对这N-1个数进行向下调整算法,每调整一次时间复杂度为O(N),以此类推,再将第一个与倒数第二个交换…
代码实现: 我们既然进行排序,就要有一个待排序的数组,我们将数组传给堆排序,同样,当然也需要知道数组个数
int arr[] = { 5,7,3,9,1,2,6,0 }; HeapSort(arr, sizeof(arr) / sizeof(arr[0])); 然后我们就可以对这个数组进行建堆了,你的升降序也是根据你建的堆来进行的,要仔细区分
对于建堆,我们有两种方法
自上而下建堆:
这也是我们最容易想到的一种
利用循环将数组变成小堆
for (int child = 0; child < size; child++) { AdjustUp(arr, child); } 自下而上建堆:
这是我们推荐的一种,因为他的时间复杂度小于上一种方式(从最后一个叶子节点的父节点开始,少了最后一层,而最后一层接近N/2个节点),同时,他只会用到向下调整算法,在进行排序时也只会用到向下算法,故很适合我们使用
int parent = (size - 1 - 1) / 2; while (parent) { AdjustDown(arr, size, parent); parent--; } AdjustDown(arr, size, parent); 排序代码:
文章目录 8.1 有关TCP 连接的退出,你该知道的事....(下)9.1 灵魂拷问 TCP ,你要投降了吗?(菜鸟教程)9.1.1 TCP 三次握手丢包情况9.1.2 TCP 四次挥手丢包情况 9.2 常见问题9.2.1 TCP为什么是三次握手9.2.1 TCP为什么是四次挥手9.2.2 TIME_WAIT状态(2MSL)的作用9.2.3 为什么TCP网络编程中close前shutdown?9.2.4 TCP 假状态/假连接9.2.5 如何判断TCP连接是否正常/可用?TCP连接的状态详解以及故障排查9.2.5 TCP 网络阻塞数据一直重传会怎样?TCP-IP详解:重传机制9.2.6 tcp 超时参数9.2.7 内核关闭socket,应用再调用close会不会释放其他连接9.2.8 TCP 报文需不需要帧头 关注设计原理关注异常处理 8.1 有关TCP 连接的退出,你该知道的事…(下) 有关TCP 连接的退出,你该知道的事…(下)
9.1 灵魂拷问 TCP ,你要投降了吗?(菜鸟教程) https://mp.weixin.qq.com/s/YuatfDtpWcj4yCdeeMxULA发送&接收、正常|超时结束、为了尽可能的正常结束/开始 TCP 三次握手和四次挥手过程中,途中某一步的报文丢失了,会发生什么?
今天就和大家一起来详细了解下,TCP 三次握手和四次挥手过程中每一步的异常情况。
发车!
9.1.1 TCP 三次握手丢包情况 第一次握手丢失了,会发生什么?
当客户端想和服务端建立 TCP 连接的时候,首先第一个发的就是 SYN 报文,然后进入到 SYN_SENT 状态。
在这之后,如果客户端迟迟收不到服务端的 SYN-ACK 报文(第二次握手),就会触发「超时重传」机制,重传 SYN 报文,而且重传的 SYN 报文的序列号都是一样的。
不同版本的操作系统可能超时时间不同,有 1 秒的,也有 3 秒的,这个超时时间是写死在内核里的,如果想要更改则需要重新编译内核,比较麻烦。
当客户端在 1 秒后还没收到服务端的 SYN-ACK 报文,客户端就会重发 SYN 报文,那到底重发几次呢?
题目 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
答案 这道题要求我们按照顺时针螺旋顺序返回矩阵中的所有元素。我们可以使用四个变量来定义矩阵的上下左右边界,然后按照右-下-左-上的顺序遍历矩阵,同时更新这四个边界。
具体实现如下:
def spiralOrder(matrix): """ :type matrix: List[List[int]] :rtype: List[int] """ # 定义矩阵的上下左右边界 top, bottom = 0, len(matrix) - 1 left, right = 0, len(matrix[0]) - 1 # 定义结果列表 res = [] # 按照右-下-左-上的顺序遍历矩阵 while left <= right and top <= bottom: # 右 for i in range(left, right + 1): res.
文章目录 1、卷积神经网络(Convolutional Neural Networks,CNN)1.1 优点1.2 缺点1.3 应用场景1.4 网络图 2、循环神经网络(Recurrent Neural Networks,RNNs)2.1 优点2.2 缺点2.3 应用场景2.4 网络图 3、长短时记忆网络(Long Short-Term Memory,LSTM)3.1 优点3.2 缺点3.3 应用场景3.4 网络图 4、门控循环单元(Gated Recurrent Unit,GRU)4.1 优点4.2 缺点4.3 应用场景4.4 网络图 5、自注意力模型(Transformer)5.1 优点5.2 缺点5.3 应用场景5.4 网络图 6、生成对抗网络(Generative Adversarial Networks,GANs)6.1 优点6.2 缺点6.3 应用场景6.4 网络图 7、人工神经网络7.1 优点7.2 缺点7.3 应用场景7.4 网络图 1、卷积神经网络(Convolutional Neural Networks,CNN) 1.1 优点 可用于图像处理和计算机视觉领域任务,包括图像分类、人物检索、物体重识别、物体检测和图像分割。通过卷积层有效捕捉图像中的局部特征(这是跟 transformer 的区别,transformer 关注全局信息)。具有平移不变性。 1.2 缺点 需要大规模的标记图像数据进行训练。在其他领域的任务上性能可能不如前馈神经网络。 1.3 应用场景 适用场景:图像分类、目标检测等。
案例:图像识别。将图像分类为不同的物体或场景。
1.4 网络图 《Gradient-based learning applied to document recognition》;LeNet-5
RTdetr ecoder和decoder部分pytorch复现代码链接见文末
1.初始化策略与源码有所差异,使用过程中可以根据自己的需求进行更换!
2.代码经过一条一条的debug,本身没有bug,并且是依据作者源码用pytorch实现,但是在进行数据预处理时,需要保证每张图片标签不为空,否则会报错。如果您需要处理相关情况,需要自己思考策略。源码中作者没有考虑标签为空的情况。
3.本代码没有复现分割部分内容
4.代码中,后处理输出顺序进行了调整,您可以完美嵌入YOLO的代码中,进行map的计算 1.概述 目前以大名鼎鼎的YOLO为代表的基于CNN的实时监测网络需要NMS进行后处理,导致不能很好的优化网络,并且网络不够健壮,从而导致检测器的推理速度出现延迟。研究者也分析了Anchor-based和Anchor-free的YOLO的性能,发现Anchor并不是影响实时监测的关键要素,而NMS后处理彩色。
DETR很好的解决了后处理对于模型的限制,却受限于Transformer巨大的计算量,无法发挥实时监测性。
因此,作者想要重构detr,使其具有实时性。研究者发现,虽然多尺度特征的引入有利于加速训练收敛和提高性能,但它也能显著增加输入编码器的序列的长度。因此,Transformer编码器由于计算成本高而成为模型的计算瓶颈。因此,作者设计了一种高效的混合编码器来代替原来的Transformer编码器。通过解耦多尺度特征的尺度内交互和跨尺度融合,该编码器可以有效地处理不同尺度的特征。此外,之前的工作表明,解码器的对象查询初始化方案对检测性能至关重要(Detr存在训练收敛缓慢和Query难以优化的问题)。为了进一步提高性能,作者提出了对iou进行感知的查询选择。通过在训练期间提供IoU约束,为解码器提供更高质量的初始对象查询。此外,提出的检测器支持通过使用不同的解码器层来灵活地调整推理速度,而不需要再训练,这得益于DETR架构中解码器的设计,方便了实时检测器的实际应用。
2. End-to-end Speed of Detectors NMS的分析 NMS是目标检测中广泛采用的一种后处理算法,用于消除检测器输出的重叠预测框。而NMS的速度容易受到预测框的个数和两个超参数的影响。
在YOLOv5和YOLOV8进行验证,结合图和表格可以看到,置信度阈值越高,剩余的预测框的个数越少,NMS时间越短。而在同一置信度阈值的前提下,IOU阈值越高,NMS时间越长。
End-to-end Speed Benchmark 对于需要NMS后处理的实时检测器,无锚检测器的性能优于基于锚的检测器,因为前者占用的后处理时间明显少于后者,这在以往的工作中被忽略了。造成这种现象的原因是,基于锚的探测器比无锚的探测器产生更多的预测框。
4. The Real-time DETR 4.1. Model Overview
RT-DETR由一个主干网、一个混合编码器和一个带有辅助预测头的Transformer解码器组成。模型架构的概述如图所示。具体来说,利用主干{S3、S4,S53}的最后三个阶段的输出特性作为编码器的输入。该混合编码器通过尺度内交互和跨尺度融合,将多尺度特征转换为一系列图像特征。随后,使用iou感知的查询选择从编码器输出序列中选择固定数量的图像特征,作为解码器的初始对象查询。最后,带有辅助预测头的解码器迭代地优化对象查询,生成预测框和置信度分数。
4.2. Effificient Hybrid Encoder
Computational bottleneck analysis. 多尺度特征会导致输入序列长度急剧增加,虽然能够加速训练的收敛性和提高性能,但是却大大提高了计算量。为了克服这一障碍,作者分析了多尺度Transformer编码器中存在的计算冗余,并设计了一组变体来证明尺度内和跨尺度特征的同时交互作用是计算效率低的。
高级特征是从包含关于图像中对象的丰富语义信息的低级特征中提取出来的。直观地说 ,在连接的多尺度特征上执行特征交互是冗余的。为了验证这一观点,作者重新考虑了编码器的结构,并设计了一系列具有不同编码器的变体,如图5所示。 这将变量集通过将多尺度特征交互解耦为尺度内交互和跨尺度融合的两步操作,逐步提高模型精度,同时显著降低计算成本.我们首先删除DINO-R50 [40]中的多尺度变压器编码器作为基线a。接下来,插入不同形式的编码器,基于基线A产生一系列变体,阐述如下: A→B:变体B插入一个单比例的Transformer编码器,它使用一层Transformer块。每个尺度的特征共享尺度内特征交互的编码器,然后将输出的多尺度特征连接起来B→C:变体C引入了基于B的跨尺度特征融合,并将连接的多尺度特征输入编码器,进行特征交互。C→D:变体D解耦了多尺度特征的尺度内相互作用和跨尺度融合。首先,利用单尺度变压器编码器进行尺度内交互,然后利用类似panet的结构进行跨尺度融合。D→E:变体E进一步优化了基于D的多尺度特征的尺度内交互和跨尺度融合,采用了设计的高效混合编码器。 混合设计:
在此基础上,作者重新考虑了该编码器的结构,并提出了一种新的高效混合编码器。如图3所示,所提出的编码器由两个模块组成,即基于注意的尺度内特征交互(AIFI)模块和基于cnn的跨尺度特征融合模块(CCFM)。AIFI进一步减少了基于变体D的计算冗余,它只在S5上执行尺度内交互。作者认为,将自注意操作应用于具有更丰富语义概念的高级特征,可以捕获图像中概念实体之间的联系,便于后续模块对图像中对象的检测和识别。同时,由于缺乏语义概念,存在与高级特征交互的重复和混淆的风险,低级特征的尺度内交互是不必要的。为了验证这一观点,作者只对变体D中的S5进行了尺度内交互作用,与普通的变体D相比,DS5显著降低了延迟(快了35%),但提高了准确性(AP提高了0.4%)。这一结论对于实时探测器的设计至关重要。CCFM还基于变体D进行了优化,在融合路径中插入了几个由卷积层组成的融合块。融合块的作用是将相邻的特征融合成一个新的特征,其结构如图4所示。融合块包含N个重新块,双路径输出通过元素添加进行融合。可以将这个过程表述如下:
4.3. IoU-aware Query Selection DETR中的对象查询是一组可学习的嵌入,它们由解码器进行优化,并由预测头映射到分类分数和边界框。然而,这些对象查询很难进行解释和优化,因为它们没有明确的物理意义。其改进方案共同点是利用分类分数从编码器中选择前K个特征来初始化对象查询(或仅选择位置查询[40])。然而,由于分类分数的不一致分布和位置信心,一些预测框高分类分数但不接近真实框,导致高分类分数和低IOU的预测框被选择,而低分类分数和高IOU的预测框被丢弃。 这就损害了探测器的性能。为了解决这个问题,作者提出了IoU感知查询选择,让模型在训练期间对高IOU的特征产生高分类分数,对低IoU的特征产生低分类分数。因此,模型根据分类评分选择的前K个编码器特征对应的预测框具有较高的分类评分和较高的IoU评分。重新制定了检测器的优化目标(引入IOU)如下:
为了分析所提出的IoU感知查询选择的有效性,作者对IOU score和分类分数进行了可视化,如图所示。红点和蓝点分别通过应用普通查询选择和iou感知查询选择训练的模型中计算出来。根据可视化结果,我们发现最显著的特征是大量的蓝色点集中在图的右上角,而红色的点集中在右下角。这表明,用iou感知的查询选择训练的模型可以产生更多高质量的编码器特征。 4.4. Scaled RT-DETR 作者将Backbone由ResNet替换为了HGNetv2,此外,作者还使用了不同的宽度和深度对模型进行拓展。作者提出的不同尺度的RT-DETR保持了一个均匀的解码器,这便于模型蒸馏。 5. Experiments 5.3. Ablation Study on Hybrid Encoder
A-E不同混合编码器变体的性能
5.4. Ablation Study on IoU-aware Query Selection 5.
第1关 CSS id选择器
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>ID选择器</title> <style type="text/css"> /* 元素选择器 */ html { background-color: #F0F0F0; } header { padding: 40px; background-color: white; } footer { margin-top: 20px; font-size: 0.6em; color: grey; } /* 类选择器 */ .main { margin: 10px; } .newsSection { margin-top: 20px; padding: 20px; background-color: white; } /* ********** BEIGN ********** */ #chosen { color: red; font-weight: bold; } #news { color: blue; font-weight: bold; } #finance { color: olive; font-weight: bold; } #think { color: green; font-weight: bold; } #life { color: orange; font-weight: bold; } /*选择menu元素下的li子元素*/ #menu li { float: left; width: 70px; font-size: 1.
第1关 CSS 类选择器
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>类选择器</title> <style type="text/css"> /* 元素选择器 */ html { background-color: #F0F0F0; } header { padding: 40px; background-color: white; } footer { margin-top: 20px; font-size: 0.6em; color: grey; } /* 类选择器 */ .main { background-color: ivory; margin: 10px; } /* ********** BEGIN ********** */ .newsSection{ margin-top: 20px; padding: 20px; background-color: white; } /* ********** END ********** */ </style> </head> <body> <div class="
第1关 CSS 元素选择器
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>元素选择器</title> <style type="text/css"> /* ********** BEGIN ********** */ /* 元素选择器 */ html { background-color: #F0F0F0; } header { padding: 40px; background-color: white; } footer { margin-top: 20px; font-size: 0.6em; color: grey; } /* ********** END ********** */ </style> </head> <body> <div> <header> <li><a href="#chosen">精选</a></li> <li><a href="#news">时事</a></li> <li><a href="#finance">财政</a></li> <li><a href="#think">思想</a></li> <li><a href="#life">生活</a></li> </header> <div> <section> <h2>精选</h2> <li>精选新闻1</li> <li>精选新闻2</li> <li>精选新闻3</li> </section> <section> <h2>时事</h2> <li>时事新闻1</li> <li>时事新闻2</li> <li>时事新闻3</li> </section> <section> <h2>财政</h2> <li>财政新闻1</li> <li>财政新闻2</li> <li>财政新闻3</li> </section> <section> <h2>思想</h2> <li>思想新闻1</li> <li>思想新闻2</li> <li>思想新闻3</li> </section> <section> <h2>生活</h2> <li>生活新闻1</li> <li>生活新闻2</li> <li>生活新闻3</li> </section> </div> <footer>Copyright (c) News Copyright Holder All Rights Reserved.
1、内容简介
略
可以交流、咨询、答疑
2、内容说明
基于线性二次调节器(LQR)法实现机器人路径规划可变轨迹跟踪
3、仿真分析
略
load path.mat %% 轨迹处理 % 定义参考轨迹 refPos_x = path(:,1); refPos_y = path(:,2); refPos = [refPos_x, refPos_y]; % 计算航向角和曲率 diff_x = diff(refPos_x) ; diff_x(end+1) = diff_x(end); diff_y = diff(refPos_y) ; diff_y(end+1) = diff_y(end); derivative1 = gradient(refPos_y) ./ abs(diff_x); % 一阶导数 derivative2 = del2(refPos_y) ./ abs(diff_x); % 二阶导数 refHeading = atan2(diff_y , diff_x); % 航向角 traj_x=refPos_x; traj_y=refPos_y; 4、参考论文
略
链接:https://pan.baidu.com/s/1AAJ_SlHseYpa5HAwMJlk1w 提取码:rvol
1、内容简介
略
29-可以交流、咨询、答疑
2、内容说明
单车模型固定点跟踪算法 单车模型,固定点跟踪算法,动画演示, 汽车单车模型、转弯动画、固定点跟踪算法、pid控制
3、仿真分析
略
A=[0,5;0,0];B=[0;1];
Q=10*eye(2);R=1;
K=lqr(A,B,Q,R)
%%
plot(xy.signals.values(:,1),xy.signals.values(:,2))
xlabel('x(m)');ylabel('y(m)');grid on
figure
plot(theta.time,theta.signals.values)
xlabel('时间(s)');ylabel('航向角(rad)');grid on
4、参考论文
略
链接:https://pan.baidu.com/s/1AAJ_SlHseYpa5HAwMJlk1w 提取码:rvol
1、内容简介
略
28-可以交流、咨询、答疑
2、内容说明
汽车行驶不同工况数据 汽车行驶不同工况数据 ECE、EUDC、FTP75、NEDC、自定义
3、仿真分析
4、参考论文
略
链接:https://pan.baidu.com/s/1AAJ_SlHseYpa5HAwMJlk1w 提取码:rvol
1、内容简介
略
27-可以交流、咨询、答疑
2、内容说明
永磁同步电机调速控制 永磁同步电机PI调速控制 永磁同步电机PI调速控制、PMSM
3、仿真分析
略
4、参考论文
略
链接:https://pan.baidu.com/s/1AAJ_SlHseYpa5HAwMJlk1w 提取码:rvol
路鸦立--基于两种先进控制策略的永磁同步电机调速控制
目录
0. 前言-决策树介绍
一、决策树有哪些
二、各种决策树详细解释
2.1 ID3决策树
2.2 C4.5决策树
2.3 C5.0决策树
2.4 CART分类树
2.5 CART回归树
本文部分图文借鉴自《老饼讲解-机器学习》
0. 前言-决策树介绍 决策树(Decision Tree)是一种常见的机器学习方法,它基于树形结构来进行决策。
决策树在分类问题中特别有效,也可以用于回归问题。它通过将数据集划分成若干个子集,从而实现对整个数据集的预测。决策树的每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。决策树是一种直观运用概率分析的一种图解法,其目的是为了产生一棵泛化能力强,即处理未见示例能力强的决策树。
一、决策树有哪些 那么,但我们经常到到CART决策树、ID3决策树等等,对于刚接触决策树的同学是非常困惑的,下面我们详细讲讲决策树有哪些种类。
主要有以下5种常见决策树
1.ID3决策树
2. C4.5决策树,
3.C5.0决策树
4.CART分类树
5.CART回归树
但从技术角度进行分类,它们又可以分为两条支线
1.CART: classification and regression tree,分类与回归树
即CART自身包括了分类树与回归树
2.ID3系列: ID3算法,C4.5算法,C5.0算法 目前matlab和python软件都只实现了CART决策树,如果要实现ID3,C4.5,C5.0等,一般需要自行编写代码进行实现
二、各种决策树详细解释 下面我们详细介绍各种决策树,同时区分各种决策树的特性
2.1 ID3决策树 ID3决策树是由Ross Quinlan发明的用于决策树的算法,该算法建立在奥卡姆剃刀的基础上:越是小型的决策树越优于大的决策树。
ID3决策树只支持枚举变量。每个节点选择一个变量,按该变量所有可能取值分叉。
下面是一棵ID3决策树:
ID3算法使用信息增益来选择属性,以构建决策树。它首先计算当前例子集合的熵,然后计算每个属性的信息增益,并选择信息增益最大的属性作为当前节点的测试条件。然后,算法将根据该属性的值将例子集合划分为两个子集,并递归地在每个子集上执行相同的过程,直到满足停止条件为止。
ID3决策树的优点:
1.算法简单,通俗易懂。
2.可以处理离散型数据。
3.能够利用信息增益来选择属性,选择信息增益最大的属性作为根节点,从而帮助算法有效地进行决策。
ID3决策树的缺点:
1.无法处理缺失值,需要对缺失值进行预处理。
2.只能处理离散值,无法处理连续值。对于连续值的处理需要先进行离散化处理,这个过程可能会带来信息的损失。
3.存在偏向于选择取值较多的特征的问题。因为特征取值越多,说明划分的越细,不确定性越低,信息增益则越高。
4.容易出现过拟合。为了避免过拟合问题,可以裁剪决策树,去掉一些不必要的子树或叶节点,或者设置决策树的最大深度。
2.2 C4.5决策树 C4.5决策树是ID3决策树算法的改进版,由Ross Quinlan提出。C4.5决策树在以下几方面对ID3算法进行了改进:
1.用信息增益率来选择属性,克服了用信息增益选择属性时偏向选择取值多的属性的不足。
2.在树构造过程中进行剪枝。
3.能够完成对连续属性的离散化处理。
4.能够处理不完整数据。
C4.5决策树算法的优点是产生的分类规则易于理解且准确率较高。但是,在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,从而导致算法的低效。
C4.5决策树算法的优点包括:
1.产生的分类规则易于理解,准确率较高。
1,ListView的简单用法
ListView是Android UI组件之一,用于在屏幕上显示一个垂直滚动的列表。每个列表项可以是一个简单的文本视图,也可以是一个复杂的自定义布局。ListView通常用于显示大量数据,例如联系人列表、电子邮件列表或新闻文章列表等。
以下是一个使用ListView显示简单文本列表的参考代码:
在XML文件中定义一个ListView:
<ListView android:id="@+id/my_list_view" android:layout_width="match_parent" android:layout_height="match_parent" /> 在Java代码中创建一个字符串数组,用于存储要显示的列表项:
String[] myListItems = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}; 创建一个ArrayAdapter对象,用于将字符串数组映射到ListView中的视图:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myListItems); 在上述代码中,我们使用了Android内置的simple_list_item_1布局作为列表项的视图。这个布局包含一个TextView,用于显示文本。您也可以使用自定义布局作为列表项的视图。
将适配器对象设置为ListView的适配器:
ListView listView = (ListView) findViewById(R.id.my_list_view); listView.setAdapter(adapter); 在上述代码中,我们首先使用findViewById()方法获取ListView的引用,然后使用setAdapter()方法将适配器对象设置为ListView的适配器。这将导致ListView显示适配器提供的列表项。
完整的Java代码如下所示:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String[] myListItems = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.
1 专业版和社区版
Other Versions - PyCharm
2 教育版
Other Versions - PyCharm Community Edition
3 版本系统需求
Install PyCharm | PyCharm Documentation
附录:
# 专业版(收费)和社区版(免费): https://www.jetbrains.com/pycharm/download/other.html # 教育版(免费) https://www.jetbrains.com/edu-products/download/other-PCE.html Pycharm版本系统需求: https://www.jetbrains.com/help/pycharm/installation-guide.html#requirements 注: 2019.3 :Win7 x64 最后一个版本, Python 2.7; Python 3.5 -- 3.8; JRE 11 2018.3 :Win7 x86 最后一个版本, Python 2.6 -- 2.7 ; Python 3.4 -- 3.7 ; JRE 1.8 下载示例,假如想下载 2019.3 的版本:输入上面的 Pycharm下载地址 ,选择专业版或社区版,点击 2019.3.5 -Windows(exe) 即可下载。
参考:
Pycharm与Python版本对应关系_pycharm2019支持什么版本的python-CSDN博客
在MATLAB中得到系统当前日期、时间也是经常用到的内容,由以下函数实现。
1.生成指定格式日期和时间 datestr-生成指定格式日期和时间,是字符型变量。
>> datestr(now) %其中now是获取当前日期和时间
ans =
30-Dec-2009 16:05:16
其中输出格式可由用户指定,共有31种格式,以下是第26种格式,其它格式见下表。
>> datestr(now,26)
ans =
2009/12/30 Standard MATLAB Date format definitions
NumberStringExample0'dd-mmm-yyyy HH:MM:SS'01-Mar-2000 15:45:171'dd-mmm-yyyy'01-Mar-20002'mm/dd/yy'03/01/003'mmm'Mar4'm'M5'mm'036'mm/dd'03/017'dd'018'ddd'Wed9'd'W10'yyyy'200011'yy'0012'mmmyy'Mar0013'HH:MM:SS'15:45:1714'HH:MM:SS PM'3:45:17PM15'HH:MM'15:4516'HH:MMPM'3:45PM17'QQ-YY'Q1-9618'QQ'Q119'dd/mm'01/0320'dd/mm/yy'01/03/0021'mmm.dd,yyyy HH:MM:SS'Mar.01,2000 15:45:1722'mmm.dd,yyyy'Mar.01,200023'mm/dd/yyyy'03/01/200024'dd/mm/yyyy'01/03/200025'yy/mm/dd'00/03/0126'yyyy/mm/dd'2000/03/0127'QQ-YYYY'Q1-199628'mmmyyyy'Mar200029(ISO 8601)'yyyy-mm-dd'2000-03-0130(ISO 8601)'yyyymmdd THHMMSS'20000301T15451731'yyyy-mm-dd HH:MM:SS'2000-03-01 15:45:17 MATLAB给照片文件名上加日期 2.获取当前时间的数值 clock-获取当前日期和时间的数值,即clock=[year month day hour minute seconds]。
>> format short g
>> clock
ans =
2009 12 30 16 44 44.687
将clock函数取得的当前日期和时间取整,得
>> now=fix(ans)
now =
2009 12 30 16 44 44
则now(1)=2008, now(2)=5,......,now(6)=44
3.其他时间和日期函数或命令 >> date
噱头大于实际?
扫地机器人的真实避障能力有几分?
避障功能作为扫地机器人的核心卖点之一,类似精准、智能、零误撞等词汇,基本是市面上大部分产品的常用词,但对于经过市场教育的消费者而言,显然并不完全同意。
随着避障技术不断升级,扫地机器人从最初的碰撞式避障进化到“主动”避障,避障表现可以说得到了跨越式提升,面对各种家具、鞋类、电器等常见物体都能够有效应对,但真实的家庭环境下,障碍物种类更加复杂多样,仍存在较多让扫地机器人“汗流浃背”的障碍物,一旦遇到往往需要听天由命,时常出现缠绕、卡死、碰撞等情况。
这些障碍物可以简单分为低矮类(儿童积木、线团、桌椅底座等)、全高类(桌子/沙发底架等)、高反类(镜子、玻璃杯等)。
从技术角度来看,目前大多数产品基本采用激光雷达避障技术,虽然优点延迟低,效果稳定,准确度高,成本也较低,但缺点也较明显,受限于激光雷达布局,有探测盲区,容易对低矮障碍物产生误判,且无法规避玻璃等高反物体,同时激光雷达无法识别语义的天然缺陷,也导致无法实现策略化的智能避障。
挑战不可能,看视觉方案表现几何?
作为视觉技术起家的机器人技术公司,INDEMIND在家用方向一直坚持纯视觉路线,并全栈自研推出「家用机器人AI Kit」机器人解决方案。该方案以INDEMIND自研的INDEMIND OS Lite家用机器人AGI系统为核心,搭配面向家用小型机器人专门研发的一体化立体视觉模组,可实现家用机器人导航定位、智能避障、路径规划、决策交互等核心功能。
面对那些让扫地机器人“汗流浃背”的障碍物,搭载「家用机器人AI Kit」的机器人又能表现几何?
在测试中,INDEMIND模拟了一个真实的家庭场景,并通过放置不同障碍物进行了多种障碍物挑战。
低矮类(儿童积木、线团、桌椅底座等)
全高类(桌子/沙发底架等)
高反类(镜子、玻璃杯等)
经过多次严格测试,机器人面对这三类障碍物均能精准稳定避障。
纯视觉稳定避障的秘密
虽然视觉方案潜力巨大,但算力要求也较高,且精度和稳定性也较差,对于一台消费级的产品,过高的算力要求显然不现实。为了解决算力和稳定性问题,INDEMIND不仅在算法上实现了VSLAM和深度学习模型轻量化,还通过配合硬件采用CPU(NEON)、GPU、NPU算法加速技术,有效降低了平台的计算压力,目前已能够在几美金的计算平台实现稳定运行建图、导航、避障等任务逻辑。
与此同时,基于INDEMIND研发训练的物体识别卷积神经网络模型,可以准确识别家用场景中的低矮障碍物(例如:动物粪便、拖鞋、钥匙串、线材、地插等)、透明玻璃容器类障碍物、动态障碍物(人、宠物)等等,自研的智能决策引擎可结合物体识别信息根据物体分类进行避障,可以有效避开动物粪便、拖鞋等特定障碍物,识别策略可配置,目前精度可达1%,最小尺寸1cm。
此外,面对光线影响问题,INDEMIND还开发了一套系统化环境补光策略,包含主动式环境补光配置和光照变化条件下的建图策略,在实际表现中,面对强光直射、无光源、昏暗等特殊光照环境均能无差异工作,满足全天候作业要求。
Tmux奇技淫巧 在日常的开发工作中,终端是我们最常用的工具之一。在终端中我们可以调用各种解释器,来执行命令,完成我们的工作。然而,对于只使用终端的默认功能的开发者来说,他们可能会错过一些强大的工具和技巧,这些工具和技巧可以大大提高工作效率。
其中一个非常有用的终端工具就是Tmux。Tmux是一个终端复用器,它允许我们在一个终端窗口中同时运行多个终端会话,并提供了许多有用的功能,如会话管理、窗口分割、窗格布局等。本文将介绍Tmux的基本概念和一些常用的功能,帮助读者更好地利用Tmux提升终端工作效率。
你当然可以使用oh-my-tmux,但是学习基础知识能够帮助你更好的使用这些工具。
1. Why Tmux? 1.1 终端复用 想象这样一个场景,我们通过ssh连接到了远程服务器之后,默认我们会连接到一个交互式解释器中(例如bash、zsh)。在同一个交互式解释器中,每次只能运行一条命令,而后等到命令运行结束之后我们才能再运行下一条命令。但很多时候,我们希望能连接到多个解释器,并行执行多个命令。
例如,假设你是一名软件开发者,正在进行一个大型项目的开发工作。为了方便开发,我们需要同时进行多个任务,如运行应用程序、查看日志、执行命令等。
首先,你创建了一个窗口,并将其命名为"代码编辑"。在这个窗口中,你打开了代码编辑器,并开始编写项目的代码。这个窗口用于代码编辑,而为了查看终端的输出,我们还需要创建另外一个窗口接下来,你创建了另一个窗口,并将其命名为"测试"。在这个窗口中,我们运行测试脚本和查看测试结果。同时,你还创建了一个名为"服务器"的窗口,用于连接到远程服务器并执行一些部署和管理任务。 在这个场景下,为了完成我们的开发工作,我们打开了多个不同的窗口,而每次切换窗口时都手都需要离开键盘,去点击鼠标。这样一来我们的效率就会被极大地降低。
想象现在有一个软件:
我们可以通过它创建了一个和解释器的会话。在这个会话中,你可以同时进行多个任务,如运行应用程序、查看日志、执行命令等。其次利用它我们能创建一个窗口,并将其命名为"代码编辑"。在这个窗口中,你打开了代码编辑器,并开始编写项目的代码。而后利用它,我们能将窗口水平分割成两个窗格,一个用于编辑代码,另一个用于查看终端输出。接下来,你创建了另一个窗口,并将其命名为"测试"。在这个窗口中,你打开了一个终端,用于运行测试脚本和查看测试结果。你可以通过它提供的快捷键在不同的窗口之间快速切换,方便地在编写代码和运行测试之间进行切换。最后,你还创建了一个名为"服务器"的窗口,用于连接到远程服务器并执行一些部署和管理任务。你可以在这个窗口中使用它提供窗格布局功能,将窗口垂直分割成两个窗格,一个用于连接到服务器,另一个用于执行命令和查看日志。 通过使用这个软件,你可以在同一个终端窗口中同时进行代码编辑、测试和服务器管理等多个任务,而无需打开多个终端窗口。你可以通过它的快捷键快速切换窗口和窗格,轻松地在不同任务之间切换,提高工作效率。
1.2 持久性会话 另外一个场景是,假设你正在远程连接到一台服务器,并需要在该服务器上运行一个需要较长时间才能完成的任务,比如数据处理、模型训练或后台服务。
那么我们连接到服务器并启动任务后,并希望在断开SSH连接后继续运行。这意味着即使你的SSH会话中断或你关闭了终端窗口,任务仍会在后台继续运行。这对于长时间运行的任务非常有用,因为你不必担心任务被中断或终止。但是SSH默认连接的终端在我们关闭SSH连接后就会终止运行,相应的我们还在运行的任务也会被终止。 因此,在这个场景下,我们希望可以和终端进行持久性会话,这样就关闭SSH链接或者关闭终端窗口后再次打开,你仍然可以恢复到之前的工作状态。
2. 安装Tmux 2.1 包管理器安装 在大多数Linux发行版中,可以使用包管理器进行安装。例如,在Ubuntu上,可以使用以下命令进行安装:
sudo apt-get install tmux 2.2 手动编译安装 作为追求技术的程序员,我们当然也可以手动从源码编译安装,毕竟这样更酷。而且包管理器的软件源中的版本可能比较老,因此手动编译安装也是不错的选择。
首先下载并解压源代码
mkdir ~/opt/tmux && cd ~/opt/tmux wget -c https://github.com/tmux/tmux/releases/download/3.3a/tmux-3.3a.tar.gz tar xzvf tmux-3.3a.tar.gz mkdir v3.3a && mv tmux* v3.3a 然后编译
cd v3.3a/tmux-3.3a ./configure --prefix=/home/jack/opt/tmux/v3.3a/ make -j $(nproc) make install 编译完成后,就能看到已经有tmux了
cd .. tree -L 2 -I tmux-3.3a 最后创建一个软连接,方便未来版本更新。
我自己博客网站里的文章
Linux周期任务:at和crontab 每个人或多或少都有一些约会或者是工作,有的工作是长期周期性的, 例如:
每个月一次的工作报告每周一次的午餐会报每天需要的打卡…… 有的工作则是一次性临时的,例如:
刚好课题组老师演讲,需要你明天准备演讲器材等等临时和师妹晚上约了吃饭…… 同理,Linux中也有很多周期性任务或者临时任务,例如:
每周打包一份备份文件:每周一的凌晨 3:25 把/home/wwwroot 目录打包备份为 backup.tar.gz。今晚 23:30 重启网站服务…… 为此,Linux中提供了at和crontab两个程序来完成一次性临时任务和长期周期任务。
1. 一次性临时任务:at at命令 用于在指定时间执行命令。
A. 启动atd 为了能够在指定的时间执行命令,需要有一个守护进程在后台不断地运行,而后到指定的时间之后运行我们指定的程序。这个守护进程就是 atd。因此,为了使用at程序,需要先开启 atd 守护进程。Linux中使用 systemctl 来管理所有的守护进程,包括启动、重启、禁止、……
首先开启 atd 守护进程启动那个服务
sudo systemctl enable rpc-statd 然后启动一下 atd 守护进程(默认是启动的,这里是以防万一)
sudo systemctl start atd 最后查看一下 atd 守护进程的状态
systemctl status atd 可以看到正常在运行
B. at配置文件 atd 通过两个文件 /etc/at.allow 和 /etc/at.deny 来决定系统中哪些用户可以使用 at 设置定时任务
它首先检查 /etc/at.allow,如果文件存在,则只有文件中列出的用户(每行一个用户名)能使用 at如果 /etc/at.allow不存在,则检查文件 /etc/at.deny,不在此文件中的所有用户都可以使用 at如果 /etc/at.deny 是空文件,则表示系统中所有用户都可以使用 at如果 /etc/at.deny 文件也不存在,则只有root才能使用at C.
自己博客网站里的文章
Shell脚本进阶:使用${}提取变量 在Shell脚本编程中,提取变量通常使用$符号,即使用$VARIABLE来提取变量VARIABLE的值。而${}是另外一种用于引用变量的语法。
相比于$,${]的功能更加强大,提供了一系列额外的功能,包括获取变量的值、进行字符串替换、执行命令以及提供默认值等。本文将详细介绍${}的用法和示例。
1. 获取变量的值 ${var}用于获取变量var的值。这适用于普通变量、数组变量和环境变量。以下是一个示例:
name="John" echo "欢迎,${name}!" 在上述示例中,${name}将会被替换为变量name的值,输出为"欢迎,John!"。
2. 大小写转换 在变量后使用^和,可以修改字符串的大小写。
${var^}会让字符串首字母大写${var^^}会让字符串全部大写${var,}会让字符串首字母小写${var,,}会让字符串全部小写 var="hello world" echo "Original string: $var" # hello world echo "Capitalizing the first letter: ${var^}" # Hello world echo "Converting to uppercase: ${var^^}" # HELLO WORLD var="HELLO WORLD" echo "Lowercasing the first letter: ${var,}" # hELLO WORLD echo "Converting to lowercase: ${var,,}" # hello world 3. 未定义时使用默认值 ${var:-default}用于获取变量var的值,如果var未定义或为空,则使用默认值default。以下是一个示例:
echo "${debug_level:-"error"}" # error debug_level="info" echo "
Java的次幂运算: 今天主要在复习一些前面的内容,在练习的时候遇到了一个次幂的运算,我发现JAVA里面是没有
”^“ 作为次幂运算符号的,它要进行次幂运算,需要借助 pow( ) 方法。其语法如下:
double pow(double base, double exponent) 它会返回第一个参数的第二个参数次方。
pow(x,y):简单点说就是 x 的 y 次方
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <cmath> #include<iostream> using namespace std; int main() { float x,y,z,result; cout<<"请输入幂值:"; cin>>x; cout<<"请输入指数值:"; cin>>z; y=1/z; result = pow(x,y); cout<<"以"<<x<<" 为幂值,指数为 "<<z<<" 的底数是: "<<result; cout<<endl; system("pause"); return 0; } 上面这个是我用C++写的求幂函数底数的一个小计算器,我用JAVA再编写一次。
package com.xiaobai; import java.util.Scanner; public class BottomNum { public static void main(String[] agr) { double x, y, z, result; System.
在Objective-C中,ASIHTTPRequest是一个非常受欢迎的库,用于处理HTTP请求。它可用于下载网页内容,处理API请求,甚至进行复杂的网络交互。下面是一个简单的示例,展示了如何使用ASIHTTPRequest库来爬取网页代码。
首先,你需要在你的项目中导入ASIHTTPRequest库。你可以通过CocoaPods或者手动方式导入。一旦你已经设置好,你就可以开始编写代码了。
objective复制代码
#import "ASIHTTPRequest.h" #import "ASIWebPage.h" // 请求URL NSString * const kRequestURL = @"http://example.com"; // 请求方法 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:kRequestURL]]; // 设置请求方法为GET [request setRequestMethod:@"GET"]; // 开始请求 [request startSynchronous]; // 检查是否有错误发生 NSError *error = [request error]; if (!error) { // 获取响应状态码 NSInteger responseStatusCode = [request responseStatusCode]; if (responseStatusCode == 200) { // 获取网页内容 NSString *responseString = [[request responseString] stringByReplacingOccurrencesOfString:@"<br>" withString:@"\n"]; NSLog(@"网页内容: %@", responseString); } else { NSLog(@"请求失败,状态码: %ld"
图像降噪是一个十分具有实用价值的研究方向,因为噪声总是无处不在的。当处于比较昏暗的环境时,噪声将极大地影响着我们所拍摄的图像。如今,随着深度学习算法以及相关硬件的不断发展,深度卷积网络同样在图像降噪领域占据了主流,并且代表了该领域最优异的成绩。但是,深度神经网络同样有着其缺点,例如模型过于庞大而计算复杂度过高,以及缺乏一些理论上的解释性,当然这些缺点正不断地得到弥补。为了更好地理解图像降噪的基本原理,我们有必要回过头来仔细研读一些传统算法的具体思路,了解其所使用基本理论依据,以及一些巧妙的改进方法。在这些传统降噪算法中,最经典而强大的莫过于 BM3D 了。这篇文章将全面地对其原理进行解读,并且对其论文中一些没有提及的细节进行补充,让各位读者能够更加轻松地理解其算法的内核。在开始这篇文章之前,本人建议大家可以先看一下以下的文章,主要是对本文中一些需要用到但是为了节省篇幅而没有细讲的基本原理进行补充:
1.https://blog.csdn.net/qq_33552519/article/details/108236388
2.https://blog.csdn.net/qq_33552519/article/details/108372176
3.https://blog.csdn.net/qq_33552519/article/details/108589799
1 加性高斯白噪声 BM3D 主要用于去除图像中的加性高斯白噪声(Additive White Gaussian Noise, AWGN)。这里主要涉及三个概念:
1) 加性,即噪声其对原始信号的影响可表示为线性叠加。对于 AWGN,我们一般假设其与原始信号无关,在同一幅图像中,无论各像素点的明暗如何,其噪声的分布函数都是一致的,即独立同分布(i.i.d.)。另一种常见的加性噪声是散粒噪声,主要由光子的量子特性所造成,像素单元实际接收到的光子数量符合泊松分布,是一种与信号相关的噪声,像素本身的亮度越高,噪声越大,但整体的信噪比却是在提高的,这里不详细讨论。
2) 高斯,即噪声瞬时值服从高斯分布。之所以为高斯分布,是因为图像成像过程中会受到很多因素的影响,例如电子的热扰动,信号的放大与量化误差,光子量子特性所带来的散粒噪声,黑体辐射,太阳或其他宇宙天体的活动等等,根据中心极限定理,大量独立随机事件的影响的总和将会趋近于高斯分布,这里通常假设其均值为 0。高斯分布的方差与所处的光照环境、相机传感器质量、快门速度、感光度等等相关,在相同条件下一般认为是一样的。
3) 白噪声,即噪声功率谱密度服从均匀分布。类似于白光包含了可见光中的所有频率,白噪声也包含了所有频率的波,并且在各频率上的功率谱密度都是一样的,这表明 AWGN 的强度并不会与像素的颜色相关(但实际上图像像素的颜色是由多种频率的光混合而成的,并不是严格的单频率光,所以也不是严格的无关)。另外,因为频域中的均匀分布对应着时域中的冲激函数,所以当前时刻的噪声不会与其他时刻相关,例如前一时刻的噪声值很大,并不意味当前时刻的噪声值也会很大,也就是说在相同拍摄条件下不同时刻拍摄的图像也是符合独立同分布假设的。注意,这里所说的时刻是指拍摄单张图像的整个过程,而不是单纯的某一瞬间。例如相机内部传感器以及其他一些信号处理器件的温度会随着拍摄时间的延长而升高,从而带来更严重的热噪声,所以在这个拍摄过程中不同瞬间的噪声的强度是有一定相关性的。
显然,AWGN 是一种理想化的模型,真实图像的噪声远要比以上的假设复杂。但大量的实验与经验也表明,在低照度以及高温的情况下,高斯噪声占据了图像噪声的主要部分,这时使用 AWGN 一方面能够较好地反映图像的真实噪声,另一方面也方便了理论上的分析以及各种算法实验的展开。例如,想要获取噪声图像对应的原始无噪声图像并不是一件易事,而在有监督深度学习中,我们需要大量的样本来训练我们的网络,这时使用人工生成的 AWGN 就能大大地减轻数据收集的工作压力,同时也能在一定程度上保证该降噪算法对于真实噪声图像的适用性。
综上所述,记真实无噪声图像为 u,AWGN 噪声为 n,有噪声图像为 v,那么三者的关系可表示为
其中 x 代表像素点位置。标准差 σ 反映了噪声值的水平,根据其概率密度函数,99.6% 的噪声值都会在 3 σ 的范围之内。在这里,噪声 n 为随机变量,而真实图像 u 为常量,所以有
那么,对于有限个相互独立的像素点的线性叠加,有
这也是大多数 AWGN 降噪算法的基本理论依据,即多个独立同分布的高斯分布的加权平均会使得新像素的方差相对于原始噪声方差成比例地缩小,相应地我们就可以得到更加纯净的图像。
2 基本降噪思路 根据式 (1.3),我们可以找到一种消除 AWGN 的有效方法,就是在同一拍摄条件下重复拍摄多幅图像并进行平均,利用噪声在时间上的独立性将其方差缩小到可以接受的范围。这也是一些训练数据集中真实无噪声图像的常用采集方法。但这种方法的局限性也十分明显,即重复拍摄需要保证被拍摄物的始终静止,否则图像在叠加时就会产生拖影。这导致我们无法对那些包含运动物体的图像进行降噪,自然地也不可能处理普遍包含运动物体的视频。
既然不能方便地通过时域的独立性来消除 AWGN,那我们只能在空域上下手了,因为 AWGN 在空域上也是满足独立同分布假设的。如果我们能够找出所有具有相近真实值 u 的像素,然后求平均,就可以同样得到一个新的像素值,其方差相比于原始像素成倍地缩小。但是,由于我们只能得到有噪声图像 v ,要寻找具有相近真实值u的像素还是十分困难的。从随机变量的角度来讲,对于有噪声图像 v 中任意两个像素,记其误差(差值平方)为
为了简便,有时会省略坐标 x xx。可求得其数学期望和方差(见链接1)分别为
上代码:
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { // 这个mutation是同步的,直接修改状态 state.count++; } }, actions: { incrementAsync({ commit }) { // 这个action是异步的,通过mutation来修改状态 setTimeout(() => { commit('increment'); }, 1000); } } }); const app = new Vue({ el: '#app', store, template: '<div>{{ count }}</div>' }); 总结 state => 基本数据
getters => 从基本数据派生的数据
mutations => 提交更改数据的方法,同步!
Python内置函数详解
此文参考python文档,然后结合自己的理解,写下来,一方面方便自己,让自己好好学习,顺便回忆回忆;另一方面,让喜欢的盆友也参考一下。 经查询,3.6版本总共有68个内置函数,主要分类如下: 数学运算(7个) 类型转换(24个) 序列操作(8个) 对象操作(9个) 反射操作(8个) 变量操作(2个) 交互操作(2个) 文件操作(1个) 编译执行(4个) 装饰器(3个) 数学运算:
数学运算
abs() 求数值的绝对值 divmod() 返回两个数值的商和余数 max() 返回可迭代对象哄的元素中的最大值或者所有参数的最大值 min() 返回可迭代对象哄的元素中的最大值或者所有参数的最小值 pow() 返回两个数值的幂运算或者其与指定整数的模值 round() 对浮点数进行四舍五入值 sum() 对元素类型是数值的可迭代对象中的每个元素求和 类型转换:
类型转换
bool() 根据传入的参数的逻辑值创建一个新的布尔值 int() 根据传入的参数创建一个新的整数 float() 根据传入的参数创建一个新的浮点数 complex() 根据传入的参数创建一个新的复数 str() 返回一个对象的字符串表现形式 bytearray() 根据传入的参数创建一个新的字节数组 bytes() 根据传入的参数创建一个新的不可变字节数组 memoryview() 根据传入的参数创建一个新的内存查看对象 ord() 返回Unicode字符对应的整数 chr() 返回整数所对应的Unicode字符 bin() 将整数转化为2进制字符串 oct() 将整数转化为8进制字符串 hex() 将整数转化为16进制字符串 tuple() 根据传入的参数创建一个新的元组 list() 根据传入的参数创建一个新的列表 dictionary() 根据传入的参数创建一个新的字典 set() 根据传入的参数创建一个新的集合 frozenset() 根据传入的参数创建一个不可变集合 enumerate() 根据可迭代对象创建枚举对象 range() 根据传入的参数创建一个新的range对象 iter() 根据传入的参数创建一个新的可迭代对象 slice() 根据传入的参数创建一个新的切片对象 super() 根据传入的参数创建一个新的子类和父类关系的代理对象 object() 创建一个新的object对象 序列操作:
写项目的mapper和xml文件时发现的,来分享下
在 MyBatis 的 XML 映射文件中使用 @Param 注解为方法参数起别名时,就无需再指定 parameterType属性。MyBatis 会根据 @Param 注解为每个参数起的别名来匹配 SQL 语句中的占位符。
注意:在 MyBatis 3.5.0 版本之前,如果方法参数只有一个,并且使用了 @Param 注解,那么你需要在 XML 映射文件中使用 parameterType
文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中,观看视频绝对是主力应用场景之一,加上移动网络技术的发展,随时随地看视频已经成为基本需求。不过,随着资本向视频应用的集中,想要看视频就必须先充会员,这让笔者很是郁闷,于是产生了自建影音云盘的想法,期间也尝试了多种影音服务器。今天,笔者就为大家介绍,如何在Windows系统中,使用Cpolar内网穿透+Emby,搭建自己的私人影音平台。
2. Emby网站搭建 作为国外玩家推崇的影音平台三剑客之一的Emby,拥有漂亮的软件界面(虽然笔者感觉和jellyfin很像)和强大功能,并且能够支持多种操作系统(Windows、MacOS、Linux、Android等等),最重要的是,它以.exe形式安装部署,省去了部署网页运行环境的麻烦。
2.1. Emby下载和安装 正如前面所提到的,Emby的安装很简单,只要登录Emby的官网emby.media,点击页面上方的download按钮,就能进入软件下载页面。在下载页面,我们选择对应操作系统的emby软件下载即可(笔者下载的是Windows X64版本)。
Emby软件是以压缩包形式下载,下载完成后将其解压到本地电脑。根据Emby官网的安装指引,我们在解压后的Emby文件夹的system文件夹下,找到名为EmbyServer.exe的文件,双击执行安装。
在双击EmbyServer.exe文件后,Windows可能会弹出防火墙安全警告,我们只要允许其访问互联网即可。
只要很短时间,Emby就会安装完成。软件安装完成后,会在Windows任务栏右下角的系统托盘处生成一个绿色的Emby图标。右键单击这个图标,并点选弹出菜单的Emby Premiere选项,就能进入本地Emby服务器的设置页面。
Emby的设置页面平平无奇,都是常规的“界面语言”、“本地媒体文件存放位置”、“管理员信息”之类。此处笔者就不过多冗述。
2.2 Emby网页测试 完成本地Emby服务器的设置后,Emby软件会转入登录页面(如没有跳转,可以在浏览器地址栏输入localhost:8096/Web),此处只要输入设置时输入的登录名,就能登录Emby Server主页面。
此时的Emby Server就在本地8096端口输出,接下来我们只需要使用cpolar内网穿透,为本地8096端口建立一条内网穿透数据隧道,就能在公共互联网上,访问到本地(局域网内)电脑上的Emby Server页面。
3. 本地网页发布 3.1 注册并安装cpolar内网穿透 cpolar内网穿透工具:https://www.cpolar.com/
完成Emby Server在本地电脑的安装后,就可以转入cpolar内网穿透工具的安装。与Emby Server的安装一样,cpolar的安装注册同样简单易行。我们可以直接在cpolar的官网页面找到下载按钮。
笔者使用的是Windows操作系统,因此选择Windows版本进行下载。
Cpolar下载完成后,将下载的文件解压,双击解压后的.msi文件,就能自动执行安装程序,接着一路点击Next就能完成安装。
cpolar会为每个用户创建独立的数据隧道,并通过用户密码和token码保证每位用户的数据安全,因此在使用cpolar之前,需要进行注册登录。在cpolar官网注册新用户的过程也非常简单,只要在cpolar主页右上角点击“用户注册”按钮,并在注册页面填入必要信息,就能完成注册。
完成了Emby Server和cpolar内网穿透程序的安装,接着我们就可以使用cpolar,创建一个能够连接本地测试页面的公共互联网地址,让我们能在有限范围对的支付页面进行测试。
3.2 Cpolar云端设置 由于笔者想要能随时访问到自己的私人影音云盘,不想每天进行重连设置(cpolar免费版设置的内网穿透数据隧道每24小时就会重置一次),因此将cpolar升级至vip版,以获得长期稳定存在的内网穿透数据隧道。如果是cpolar免费版或只是临时创建数据隧道,可以直接在cpolar客户端进行设置而不必在cpolar云端进行设置。
为创建能够长期稳定存续的内网穿透数据隧道,我们先登录cpolar的官网,在用户主页面左侧找到预留按钮,并点击进入cpolar的数据隧道预留页面。在这里生成一个公共互联网地址(可以理解为数据隧道的入口),由于此时这个地址没有连接本地的软件输出端口,因此也可以看做是空白的数据隧道。
在预留页面,可以看到很多种可保留的数据隧道,这里我们选择保留二级子域名栏位。
在“保留二级子域名”栏位,需要进行几项信息的简单设置,即:
地区:服务器所在区域,就近选择即可)二级域名:会最终出现在生成的公共互联网地址中,作为网络地址的标识之一)描述:可以看做这条数据隧道的描述,能够与其他隧道区分开即可)。 完成这几项设置后,就可以点击右侧的保留按钮,将这条数据隧道保留下来。
当然,如果这条数据隧道不打算再使用,还可以点击右侧的“x”将其轻松删除,节约宝贵的隧道名额。
3.3 Cpolar内网穿透本地设置 完成cpolar云端的设置,建立内网穿透数据隧道的入口后,我们回到本地的cpolar客户端,将云端生成的空白数据隧道与本地eEmby server页面连接起来,让我们能在公共互联网上访问到本地的测试页面。
在本地打开并登录cpolar客户端(可以在浏览器中输入localhost:9200直接访问,也可以在开始菜单中点击cpolar客户端的快捷方式)。
点击客户端主界面左侧隧道管理项下的创建隧道按钮,进入本地隧道创建页面(如果要创建没24小时重置地址的临时数据隧道,可直接在此进行设置,不必再cpolar官网设置空白数据隧道)。
在这个页面,同样需要进行几项信息设置,这些信息设置包括:
隧道名称:可以看做cpolar本地的隧道信息注释,方便我们分辨不用隧道的用途即可;协议:Emby server是网页形式输出,因此选择http协议;本地地址:本地地址即为本地网站的输出端口号,Emby server网页端口为8096,因此这里也填入8096;域名类型:在这个例子中,我们已经在cpolar云端预留了二级子域名的数据隧道,因此勾选“二级子域名”(如果预留的是自定义域名,则勾选自定义域名);在下一行Sub Domain栏中填入预留的二级子域名,这里填入“Embyserverweb”。如果打算创建临时数据隧道,则直接勾选“随机域名”,由cpolar客户端自行生成网络地址;地区:与cpolar云端预留的信息一样,我们依照实际使用地填写即可; 完成这些设置后,就可以点击页面下方的创建按钮,将cpolar云端的空白数据隧道与本地的Emby server页面连接起来,即创建了可以在公共互联网访问本地Emby server的数据隧道。
我们可以在隧道管理项下的隧道列表页面中,对这条数据隧道进行管理,包括开启、关闭或删除这条隧道,也可以点击“编辑”按钮,最这条数据隧道的信息进行修改。
1. 为参数起别名: 当方法参数有多个时,MyBatis 无法通过参数名来区分它们。通过 @Param 注解为参数起别名,可以在 SQL 语句中引用这个别名,使得 MyBatis 能够正确地匹配参数。
2. 解决方法参数为基本类型时的问题: 当方法只有一个参数且为基本类型时,MyBatis 默认将这个参数命名为 arg0,arg1,以此类推。为了更好地书写 SQL 语句,可以使用 @Param 注解指定参数名。
最近项目需要对接天目慧眼系统(基于海康威视智能应用平台),获取几个监控点的摄像头并展示在前端,这里用到的api就两个:/api/resource/v1/cameras分页获取监控点资源、/api/video/v1/cameras/previewURLs获取监控点预览取流URL。
首先,我们需要获取摄像头IP和端口号,还有AK/SK(AK(Access Key ID):访问密钥ID。与私有访问密钥关联的唯一标识符;访问密钥ID和私有访问密钥一起使用,对请求进行加密签名。SK(Secret Access Key):与访问密钥ID结合使用的密钥,对请求进行加密签名,可标识发送方,并防止请求被修改。)
其次,使用官方提供的OpenAPI接口测试工具(见下图中5)测试所需接口是否正常返回,正常的话继续使用官方提供的H5player(见下图中4)验证上一步返回的监控点预览取流URL是否可以预览。这里我研究了很久,想仅通过前端拼接请求头等信息直接获取监控点预览取流URL,但最后人工客服说了目前只能保证postman能调通接口,不能保证通过此方式请求到接口,还是得通过后端集成官方提供的OpenAPI 安全认证库 (见下图中6),然后前端调用后端接口获取相应信息。
视频流协议类型有4种:rtsp-rtsp协议、rtmp-rtmp协议、hls-HLS协议、ws-Websocket协议。我最后采用的是ws,没有采用hls是因为获取的监控点预览取流URL是http的,好像有跨域问题,懒得再设置了。
最后将H5player引入到Vue项目中,接入视频流进行预览。我们先把H5player文件夹中的h5player.min.js和Decoder.js放到vue项目对应路径下;再把<script src="./h5player.min.js"></script>、<script src="./Decoder.js"></script>两个标签引入index.html中;接着在页面中加入<div id="H5Video"></div>;
接着像下方一样写方法即可。需要注意的是:流媒体播放时必传入的参数名称需要为“playURL”,我在代码里给它赋值监控点预览取流url了。不这样设置可能会导致报错和无法播放。
//下方为海康视频播放器所需变量 const { JSPlugin } = window; var curIndex = 0; // 当前窗口下标 var myPlugin = new JSPlugin({ szId: "H5Video", //需要英文字母开头 必填 szBasePath: "@/utils/h5player.min.js", // 必填,引用H5player.min.js的js相对路径 // 当容器div#play_window有固定宽高时,可不传iWidth和iHeight,窗口大小将自适应容器宽高 iWidth: 600, iHeight: 400, // 分屏播放,默认最大分屏4*4 openDebug: true, // 分屏播放 iMaxSplit: 4, iCurrentSplit: 1, // 设置样式 oStyle: { border: "#FFF", borderSelect: "#FFCC00", background: "#000", }, }); initPlugin(); // 事件初始化 function initPlugin() { myPlugin.
原因:头文件缺少
解决办法:在头文件处加 #include<iosteam>
原因:头文件缺少
解决办法:在头文件处加 #include<stdlib.h>
列表作为python中序列的一种,是最常用的也是最常见的之一,其应用价值也非常的大,本节小编就给大家讲解列表中几种常用的元素删除方法,其在数据分析中也有一定的应用。
首先是pop方法,它可以根据指定位置(索引)删除元素,若不传值则默认删除最后一个元素,它也可以被认为是一种间接的删除方法
#随机创建一个列表 list1=[2,1,4,6,7,8,'a','b'] #删除最后一个元素,即'b' list1.pop() print(list1) #在上面基础上删除索引为0的元素,即2 list1.pop(0) print(list1) 其次是直接删除法,那就是remove方法,可以直接删除元素,当然这种方法的前提是已知要删除的元素是什么,并且若一个列表中有很多个一样的元素,它只能删除最前面的那个。
#随机创建一个列表 list1=[2,1,4,6,7,8,'a','b'] #删除元素为2的元素 list1.remove(2) print(list1) 再者就是直接将列表中的元素全部删除(清空),可以使用clear方法,当然最简单莫过于直接赋值为空列表了。
#随机创建一个列表 list1=[2,1,4,6,7,8,'a','b'] #将列表元素全部删除 list1.clear() print(list1) #随机创建一个列表 list2=[2,1,4,6,7,8,'a','b'] #直接赋值为空列表,与上面方法等效 list2=[] print(list2) 最后是批量删除,使用del方法。
#随机创建一个列表 list1=[2,1,4,6,7,8,'a','b'] #通过索引删除值,删除索引为0,1,2的元素,不包括右端值 del list1[0:3] print(list1)
在生成的Android文件的build.gradle中修改下ndk配置: ndk { //设置支持的SO库架构 //正式打包的时候改成这个,我估计我们打包的时候这个架构其实写错了 //abiFilters "armeabi-v7a" //运行debug安装的时候需要对应CPU架构的'arm64-v8a'的so,不然会找不到libflutter.so //其实CPU的架构是'arm64-v8a',加上了直接在AS的Run就可以安装到机器上 abiFilters "armeabi-v7a", 'arm64-v8a' }
JavaSE学习笔记 Day5 [上一篇](https://blog.csdn.net/CHiN_951/article/details/134584212?spm=1001.2014.3001.5502)
四、流程控制语句 ··· 4.3.8break和continue break:中断,中断当前的循环结构(switch中是中断当前的switch结构)
continue:继续,中断当前继续下次
// break和continue public static void main(String[] args) { for(int i = 1;i<=10;i++) { if(i == 7) { // 只要在循环之内,就是中断当前的循环 break; } System.out.println(i); } System.out.println("--------------------------------------"); for(int i = 1;i<=10;i++) { if(i == 7) { // 中断当前,继续下次 continue; } System.out.println(i); } } 4.3.9循环嵌套 多个循环嵌套在一起
执行规则:外层执行一次,每层执行一遍
public class Demo07 { /* 打印图形: ***** ***** ***** ***** ***** */ public static void main(String[] args) { // 1.
JS四舍五入保留两位小数-CSDN博客
function getMonthStartAndEnd(dateString) { const date = dateString ? new Date(dateString) : new Date(); const year = date.getFullYear(); const month = date.getMonth() + 1; // const firstDay = new Date(year, month - 1, 1); const lastDay = new Date(year, month, 0); const formattedFirstDay = `${year}-${month.toString().padStart(2, '0')}-01`; const formattedLastDay = `${year}-${month.toString().padStart(2, '0')}-${lastDay.getDate()}`; return { firstDay: formattedFirstDay, lastDay: formattedLastDay }; } console.log(getMonthStartAndEnd('2023-11-15')); // { "firstDay": "2023-11-01", "lastDay": "2023-11-30" } 没有传入参数,默认为当天日期。
首先根据传入的日期字符串(或者当前日期)创建一个 Date 对象。然后通过 Date 对象的方法获取年份和月份,并计算出该月的最后一天的 Date 对象。第一天都是1号,不用额外计算。
1. 自己写接口实现相关功能 下面是一个简单的C语言字符串拼接函数,使用指针来操作:
#include <stdio.h> #include <stdlib.h> #include <string.h> char* string_concat(const char* str1, const char* str2) { char* result = malloc(strlen(str1) + strlen(str2) + 1); // 为合并后的字符串分配内存,+1 是为了 '\0' if (result == NULL) { printf("Memory allocation failed\n"); exit(EXIT_FAILURE); } strcpy(result, str1); // 把第一个字符串复制到结果中 strcat(result, str2); // 把第二个字符串追加到结果中 return result; // 返回合并后的字符串 } int main() { const char* str1 = "Hello, "; const char* str2 = "World!"; char* concatenated = string_concat(str1, str2); printf("