当前位置: 首页 > news >正文

Python玩转视频剪辑 - Opencv、Moviepy(附完整案例)

1. 准备工作

1.1 安装Opencv-python、Moviepy

pip install opencv-python
pip install moviepy

1.2 视频剪辑目标

如图,作者从b站下载了两个视频(仅做代码测试用,不作转载等任何商业用途),一个是刘初寻的疏远(以下简称视频一)、一个是有名的敢杀我的马(以下简称视频二),两个视频都有明显的水印,本文主要工作是去除整个视频的水印,并把两个视频拼接起来成为一个完整的视频。

2. 去除水印

2.1 截取视频的一帧图片

我们知道视频都是由若干张图片组合而成,帧率代表1s有几张图片,比如120帧的8s视频则有960张图片,我们利用cv2.VideoCapture函数来获取视频的一帧图片(注:为了获取水印模版,建议获取水印比较明显、周围像素变化不大的图片,以便水印的提取):

def Get_Video_Image(filedir, savedir = None, second = None):"""截取视频一帧图片函数:  filedir: 视频原文件路径   savedir: 剪辑视频文件保存路径, 若不保存则返回图片  second: 截取第几秒的图片  """cap = cv2.VideoCapture(filedir)  # 打开视频文件frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)  # 获得视频文件的帧数fps = cap.get(cv2.CAP_PROP_FPS)  # 获得视频文件的帧率width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # 获得视频文件的帧宽height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)  # 获得视频文件的帧高second = 0 if second is None else secondfor pos in tqdm(range(int(second*fps))):ret, frame = cap.read()  # 捕获一帧图像cap.release()if savedir is not None:cv2.imwrite(savedir, frame)return frame
INPUT_DIR1 = "C:/Users/user/Desktop/bilibili_video/疏远.mp4"
OUTPUT_DIR1 = "C:/Users/user/Desktop/bilibili_video/capture1.jpg"INPUT_DIR2 = "C:/Users/user/Desktop/bilibili_video/敢杀我的马.mp4"
OUTPUT_DIR2 = "C:/Users/user/Desktop/bilibili_video/capture2.jpg"Get_Video_Image(INPUT_DIR1, OUTPUT_DIR1, 4) # 截取第4s的图片
Get_Video_Image(INPUT_DIR2, OUTPUT_DIR2, 8) # 截取第8s的图片

如代码,我们截取了视频一第4s的图片和视频二第8s的图片,效果如下:

2.2 获取水印的位置范围

为了方便水印的提取,我们需要获取水印的位置。以下程序运行后用鼠标点击我们想要获取坐标的区域,即可获得其像素点坐标。结束方式:敲击键盘“q”,回车。代码改编自:https://blog.csdn.net/People1007/article/details/122420735

def ON_EVENT_LBUTTONDOWN(event, x, y, flags, param):img = param["image"] # 传进图片参数if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)print(x, y)cv2.circle(img, (x, y), 2, (0, 0, 255))cv2.putText(img, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0,0,255)) # 把坐标画在图片上cv2.imshow("image", img)def Get_Position(filedir):"""获取图片位置函数:  filedir: 视频原文件路径 """img = cv2.imread(filedir)cv2.namedWindow("image", cv2.WINDOW_NORMAL)cv2.setMouseCallback("image", ON_EVENT_LBUTTONDOWN, {"image": img})while(1):cv2.imshow("image", img)key = cv2.waitKey(2) & 0xFFif key == ord('q'): # 按q则退出图片展示breakcv2.destroyAllWindows()
Get_Position(OUTPUT_DIR1) # 得到水印的位置(行列)
Get_Position(OUTPUT_DIR2) # 得到水印的位置(行列)

运行程序效果图如下:

如图,视频一水印行像素点从23到70,列像素点从974到1259(范围需要完全覆盖住水印)

视频二有两个水印:

水印一:行像素点从115到178,列像素点从135到369

水印二:行像素点从25到91,像素点从1676到1902

2.3 获取水印模版

本文获取水印模板的方法是在水印范围内,对比水印与周围像素点的差异,进而把水印的像素点提取出来(水印位置多扩大点没事,尽量覆盖,要让字体尽量粗,不然会有水印边缘留存)。比如图片一通过观察发现水印的R像素大于60,图片二发现水印的RGB像素大于195:

image = cv2.imread(OUTPUT_DIR1)
image_new = image.copy() # 复制一张相同规格的图片
image_new.fill(255) # 空白图片
for row in range(23, 70): # 水印行从23到70for col in range(974, 1259): # 水印列从974到1259if image[row][col][0] > 60: # 通过观察发现水印的R像素大于60, 水印位置多扩大点没事, 尽量覆盖image_new[row][col] = np.array([0, 0, 0])
cv2.imwrite(MASK_DIR1, image_new)image = cv2.imread(OUTPUT_DIR2)
image_new = image.copy() # 复制一张相同规格的图片
image_new.fill(255) # 空白图片
for row in range(115, 178): # 水印行从115到178for col in range(135, 369): # 水印列从135到369if image[row][col][0] > 195 and image[row][col][1] > 195 and image[row][col][2] > 195: # 通过观察发现水印的RGB像素大于195, 水印位置多扩大点没事, 尽量覆盖image_new[row][col] = np.array([0, 0, 0])
for row in range(25, 91): # 水印行从25到91for col in range(1676, 1902): # 水印列从1676到1902if image[row][col][0] > 195 and image[row][col][1] > 195 and image[row][col][2] > 195: # 通过观察发现水印的RGB像素大于195, 水印位置多扩大点没事, 尽量覆盖image_new[row][col] = np.array([0, 0, 0])
cv2.imwrite(MASK_DIR2, image_new)

提取的水印模版如下:

2.4 去除水印

2.4.1 水印用相邻像素点填充

如果直接把含有水印的区域用同种颜色覆盖,那么会显得非常突兀,一种自适应的办法就是用相邻的像素点来填充水印所在的像素点(之前确定水印位置的好处还在于可以加速,填充水印时只扫描该部分区域,不然全图扫描太慢了):

def ImageWaterCancel(mask: np.array, image: np.array, mask_ranges = None) -> np.array:"""除水印函数:  mask: 水印图片对象  image: 原图片对象  mask_ranges: 三维数组, 多个水印对应范围, 加速用, 若不传入则全图扫描  """new_image = image # 创建一张一样的图像用于保存cur_ele = np.array([255, 255, 255]) # 初始默认用空白元素填充if mask_ranges is None:mask_range = [[[0, image.shape[0]], [0, image.shape[1]]]]for mask_range in mask_ranges:cur_ele = np.array([255, 255, 255])for row in range(mask_range[0][0], mask_range[0][1]):for col in range(mask_range[1][0], mask_range[1][1]):if not (mask[row, col] == np.array([255, 255, 255])).all():new_image[row, col] = cur_ele # 用最近非水印的元素填充else:new_image[row, col] = image[row, col]cur_ele = image[row, col]return new_image
PATH = "C:/Users/user/Desktop/bilibili_video"
MASK_DIR1, MASK_DIR2 = os.path.join(PATH, "mask1.jpg"), os.path.join(PATH, "mask2.jpg")  
TEST_DIR1, TEST_DIR2 = os.path.join(PATH, "test1.jpg"), os.path.join(PATH, "test2.jpg")
mask1, mask2 = cv2.imread(MASK_DIR1), cv2.imread(MASK_DIR2)
image1, image2 = cv2.imread(TEST_DIR1), cv2.imread(TEST_DIR2)image1 = ImageWaterCancel(mask1, image1, [[[24, 65], [975, 1264]]]) # 对应水印位置
image2 = ImageWaterCancel(mask2, image2, [[[115, 178], [135, 369]], [[25, 91], [1676, 1902]]])cv2.imwrite("test1_cancel.jpg", image1)
cv2.imwrite("test2_cancel.jpg", image2)

让我们来看看去除水印的效果:

图片一填充水印前:

填充水印后:

图片二填充水印前:

填充水印后:

可以看出,水印确实不怎么认得出来了,但还是有一点小痕迹,像打了马赛克一样,为了进一步增强去除水印的效果,下面介绍一种图像平滑的方法。

2.4.2 图像平滑

图像平滑是一种区域增强的算法,通过减少图像像素点和周围像素点的差,来使得图像平滑。常见的平滑算法有邻域平均法、中值滤波、边界保持类滤波等,详细可见:https://blog.csdn.net/zaishuiyifangxym/article/details/89788020

def ImageBlur(image: np.array, mask_ranges = None, blur = "median", ksize = 5, sigmax = 0):"""滤波函数: 支持均值滤波、中值滤波、高斯滤波  image: 图片, np.array  mask_ranges: 三维数组, 水印对应范围, 加速用, 若不传入则全图滤波  ksize: 卷积核的大小, 默认为5  sigmax: 只在高斯滤波用, 表示X方向方差  """  if mask_ranges is None:mask_ranges = [[[0, image.shape[0]], [0, image.shape[1]]]]for mask_range in mask_ranges:row_s, row_e, col_s, col_e = mask_range[0][0], mask_range[0][1], mask_range[1][0], mask_range[1][1]if blur == "median":image[row_s: row_e, col_s: col_e, :] = cv2.medianBlur(image[row_s: row_e, col_s: col_e, :], ksize) # 中值滤波elif blur == "gauss":image[row_s: row_e, col_s: col_e, :] = cv2.GaussianBlur(image[row_s: row_e, col_s: col_e, :], (ksize, ksize), sigmax) # 高斯滤波else:image[row_s: row_e, col_s: col_e, :] = cv2.medianBlur(image[row_s: row_e, col_s: col_e, :], (ksize, ksize)) # 均值滤波return image
image1 = ImageBlur(image1, [[[24, 65], [975, 1264]]], "median", 11)
image2 = ImageBlur(image2, [[[115, 178], [135, 369]], [[25, 91], [1676, 1902]]], "median", 11)
cv2.imwrite("test1_cancel_blur.jpg", image1)
cv2.imwrite("test2_cancel_blur.jpg", image2)

图像平滑效果图如下:

看图可见,是不是水印只剩下一点点痕迹了(完美去除很难),这才是我们想要的去除水印的效果。

2.4.3 全视频除水印

我们知道视频都是由若干张图片组合而成,视频除水印等价于对每张图片进行除水印:

def CaptureVideo(filedir, savedir, cut_time = None, resolution = None, maskdir = None, mask_ranges = None, blur = None, ksize = 5):""" 剪辑视频函数:  filedir: 视频原文件路径  savedir: 剪辑视频文件保存路径   cut_time: 剪辑视频起始、结束时间    resolution: 自定义分辨率[width, height]  maskdir: 水印图片位置   mask_ranges: 三维数组, 水印对应范围, 加速用, 若不传入则全图扫描  blur: 滤波函数, 若不传入则不进行图片平滑处理  ksize: 卷积核的大小, 默认为5   注: 该函数生成的视频无音频, 需要再拼接音频, 此处cut_time剪切视频只是为了测试用, 建议不要在这里剪视频片段然后用moviepy合并音频(因为有一些视频帧率不为整数, 在剪切视频和合并音频可能会对不上), 直接用moviepy剪切视频然后合并音频最合适"""cap = cv2.VideoCapture(filedir) # 读取视频文件frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)  # 获得视频文件的帧数fps = cap.get(cv2.CAP_PROP_FPS)  # 获得视频文件的帧率if resolution is None: # 自定义分辨率width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # 获得视频文件的帧宽height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)  # 获得视频文件的帧高else:width = resolution[0]height = resolution[1]if maskdir is not None: # 去除水印mask = cv2.imread(maskdir)# 创建保存视频文件类对象fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 定义视频文件类型out = cv2.VideoWriter(savedir, fourcc, fps, (int(width), int(height))) # 剪辑视频对象if cut_time is None:start = 0end = int(frames)else:start = int(cut_time[0] * fps)end = int(cut_time[1] * fps)cap.set(cv2.CAP_PROP_POS_FRAMES, start * fps)for pos in tqdm(range(start, end)):ret, frame = cap.read()  # 捕获一帧图像if maskdir is not None: # 除水印frame = ImageWaterCancel(mask, frame, mask_ranges) if blur is not None:frame = ImageBlur(frame, mask_ranges, blur, ksize)if resolution is not None:frame = cv2.resize(frame, resolution) # 改变分辨率out.write(frame)  # 保存帧cap.release() # 释放视频对象out.release()
INPUT_DIR1, OUTPUT_DIR1 = os.path.join(PATH, "疏远.mp4"), os.path.join(PATH, "疏远_剪辑.mp4")
MASK_DIR1 = os.path.join(PATH, "mask1.jpg") # 只含有水印的图片
INPUT_DIR2, OUTPUT_DIR2 = os.path.join(PATH, "敢杀我的马.mp4"), os.path.join(PATH, "敢杀我的马_剪辑.mp4")
MASK_DIR2 = os.path.join(PATH, "mask2.jpg") # 只含有水印的图片
# 视频剪辑、除水印、拼接
CaptureVideo(INPUT_DIR1, OUTPUT_DIR1, resolution = [1280, 720], maskdir = MASK_DIR1, mask_ranges = [[[24, 65], [975, 1264]]], blur = "median", ksize = 11)
CaptureVideo(INPUT_DIR2, OUTPUT_DIR2, resolution = [1280, 720], maskdir = MASK_DIR2, mask_ranges = [[[115, 178], [135, 369]], [[25, 91], [1676, 1902]]], blur = "median", ksize = 11)

运行上述代码,可以得到疏远_剪辑.mp4、敢杀我的马_剪辑两个视频,此时视频已经完全除去水印,但是视频是没有声音的(因为cv2.VideoCapture只能读取图片)。

3. 视频拼接音频

3.1 视频拼接

def MergeVideos(filedirs: list, cut_time = None):"""视频拼接函数:  filedirs: 视频原文件路径, list  mask_ranges: 三维数组, 水印对应范围, 加速用, 若不传入则全图扫描  """    all_vedios = []for i in range(len(filedirs)):filedir = filedirs[i]if cut_time is None or cut_time[i] is None: # 如果不传入此参数或者改视频不剪切, 则直接加入all_vedios.append(VideoFileClip(filedir))else:all_vedios.append(VideoFileClip(filedir).subclip(cut_time[i][0], cut_time[i][1]))return concatenate_videoclips(all_vedios)
# 视频拼接
final_video = video_process.MergeVideos([OUTPUT_DIR1, OUTPUT_DIR2]) # 有声音的视频拼接完还是有声音, 无声音的视频拼完得拼接音频

作者运用Moviepy库,编写了一个视频拼接函数,有声音的视频拼接完有声音,无声音的视频拼完得拼接音频,同时支持剪辑视频,通过cut_time参数传入剪辑视频起始点。(注:视频必须分辨率相同才可以拼接,不然拼接的视频会出现画面雪花的迹象)

3.2 音频拼接

def MergeAudios(filedirs: list, cut_time = None):"""音频拼接函数:  filedirs: 音频原文件路径, list  cut_time: 二维数组, 剪辑音频起始、结束时间"""    all_audios = []for i in range(len(filedirs)):filedir = filedirs[i]if cut_time is None or cut_time[i] is None: # 如果不传入此参数或者该视频不剪切, 则直接加入all_audios.append(AudioFileClip(filedir))else:all_audios.append(AudioFileClip(filedir).subclip(cut_time[i][0], cut_time[i][1]))return concatenate_audioclips(all_audios)
# 音频拼接
final_audio = MergeAudios([INPUT_DIR1, INPUT_DIR2])

作者运用Moviepy库,编写了一个音频拼接函数,同时支持剪辑音频,通过cut_time参数传入剪辑视频起始点。

3.3 合并视频和音频

# 将音频剪辑与视频同步
synced_audio = final_audio.set_duration(final_video.duration)
# 合并视频和音频
final_clip = concatenate_videoclips([final_video.set_audio(synced_audio)])
# 输出合并后的视频
final_clip.write_videofile(os.path.join(PATH, "combined_video.mp4"))
# final_clip.write_videofile(os.path.join(PATH, "combined_video.wmv"), codec = "mpeg4") # 其它格式需要指定codec

将视频与音频合并后,就可以得到有声音的、去除水印的拼接视频啦!文章涉及的数据集和源代码可从Github下载:https://github.com/CNLCNL/VideoCapture,希望这些方法和技巧能对大家有所帮助,谢谢!

相关文章:

Python玩转视频剪辑 - Opencv、Moviepy(附完整案例)

1. 准备工作 1.1 安装Opencv-python、Moviepy pip install opencv-python pip install moviepy 1.2 视频剪辑目标 如图,作者从b站下载了两个视频(仅做代码测试用,不作转载等任何商业用途),一个是刘初寻的疏远(以下简称视频一&a…...

Pulsar客户端如何控制内存使用

Pulsar客户端如何控制内存使用 一、使用场景 在实际应用中,Pulsar客户端的内存使用控制是一个重要的性能优化点。假设有一个搜索类业务需要记录用户搜索请求,以便后续分析搜索热点和优化搜索效果。以下是一个简化的代码示例: PulsarClient…...

接口测试总结(http与rpc)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传…...

Linux:进程概念(二.查看进程、父进程与子进程、进程状态详解)

目录 1. 查看进程 1.1 准备工作 1.2 指令:ps—显示当前系统中运行的进程信息 1.3 查看进程属性 1.4 通过 /proc 系统文件夹看进程 2. 父进程与子进程 2.1 介绍 2.2 getpid() \getppid() 2.3 fork()函数—通过系统调用创建进程 fork()函数疑问 3. 进程状态…...

ubuntu22.04 编译安装libvirt 10.x

环境安装 sudo apt-get update -y sudo apt-get install qemu-system-x86 bridge-utils libyajl-dev -y sudo apt-get install build-essential autoconf automake libtool -y sudo apt-get install libxml2-dev libxslt1-dev libgnutls28-dev libpciaccess-dev libnl-3-de…...

Ubuntu 下载安装 Consul1.17.1

下载 来到 Consul 的下载页面:https://developer.hashicorp.com/consul/install?product_intentconsul 上面标注的地方可以切换你想要的版本,复制下载链接,使用 wget 下载这个文件: wget https://releases.hashicorp.com/consu…...

怎么实现Redis的高可用?

大家好,我是锋哥。今天分享关于【怎么实现Redis的高可用?】面试题。希望对大家有帮助; 怎么实现Redis的高可用? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 为了实现 Redis 的高可用性,我们需要保证在发…...

Domain Adaptation(李宏毅)机器学习 2023 Spring HW11 (Boss Baseline)

1. 领域适配简介 领域适配是一种迁移学习方法,适用于源领域和目标领域数据分布不同但学习任务相同的情况。具体而言,我们在源领域(通常有大量标注数据)训练一个模型,并希望将其应用于目标领域(通常只有少量或没有标注数据)。然而,由于这两个领域的数据分布不同,模型在…...

Chatper 4: mplementing a GPT model from Scratch To Generate Text

4 Implementing a GPT model from Scratch To Generate Text 本章节包含 编写一个类似于GPT的大型语言模型(LLM),这个模型可以被训练来生成类似人类的文本。Normalizing layer activations to stabilize neural network training在深度神经网…...

websocket股票行情接口

股票行情区别 交易所出来的数据,不管通过什么渠道,延时一般都不会差太远,估计一般也就几十ms的差别。 但是如果是通过http轮询,不太可能几十ms全部轮询一次。所以,做量化的话,用http协议是最次的选择。 …...

一键部署Netdata系统无需公网IP轻松实现本地服务器的可视化监控

文章目录 前言1.关于Netdata2.本地部署Netdata3.使用Netdata4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Netdata公网地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。…...

概率图模型01

机器学习中,线性回归、树、集成和概率图都属于典型的统计学习方法,概率图模型会更深入地体现出‘统计’两字 概率图模型的常见算法 概率图模型中的图 概率图模型如图主要分为两种,即贝叶斯网络和马尔可夫网络,有向图与无向图&…...

oxml中创建CT_Document类

概述 本文基于python-docx源码,详细记录CT_Document类创建的过程,以此来加深对Python中元类、以及CT_Document元素类的认识。 元类简介 元类(MetaClass)是Python中的高级特性。元类是什么呢?Python是面向对象编程…...

YARN 集群

一、集群角色 1.1 概述 Apache Hadoop YARN是一个标准的Master/Slave集群(主从架构)。其中ResourceManager(RM) 为Master, NodeManager(NM) 为 Slave。常见的是一主多从集群,也可以…...

电机控制的数字化升级:基于DSP和FPGA的仿真与实现

数字信号处理器(DSP,Digital Signal Processor)在工业自动化领域的应用日益广泛。DSP是一种专门用于将模拟信号转换成数字信号并进行处理的技术,能够实现信号的数字滤波、重构、调制和解调等多项功能,确保信号处理的精…...

homework 2025.01.11 math 6

homework 2025.01.11 math 6 小学6年级数学...

【会话详解】

会话详解 概述 会话: 用户通过浏览器访问多个Web资源的过程,从打开浏览器开始访问特定网站,直到关闭浏览器的过程称为会话(Session)。会话管理是Web应用中跟踪和存储用户状态的重要机制。 有状态会话: …...

Unity 的 Vector3 与 Babylon.js 的 Vector3:使用上的异同

在 3D 开发中,向量是不可或缺的数学工具,用于表示位置、方向、速度等物理量。Unity 和 Babylon.js 都提供了 Vector3 类来处理三维向量,但它们在实现和使用上有一些异同。本文将详细对比 Unity 的 Vector3 和 Babylon.js 的 Vector…...

【2024年华为OD机试】(A卷,100分)- 单词倒序(Java JS PythonC/C++)

一、问题描述 题目描述 输入单行英文句子,里面包含英文字母,空格以及,.?三种标点符号,请将句子内每个单词进行倒序,并输出倒序后的语句。 输入描述 输入字符串S,S的长度 1 ≤ N ≤ 100 输出描述 输出倒序后的字…...

芯片:CPU和GPU有什么区别?

CPU(中央处理器)和GPU(图形处理单元)是计算机系统中两种非常重要的处理器,它们各自有不同的设计理念、架构特点以及应用领域。下面是它们之间的一些主要差异: 1. 设计目的与应用领域 CPU:设计…...

springboot整合mysql

1.首先在pom.xml中添加依赖&#xff1a; <!-- MySQL Driver --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- Druid连接池 -->…...

复合机器人助力手机壳cnc加工向自动化升级

在当今竞争激烈的制造业领域&#xff0c;如何提高生产效率、降低成本、提升产品质量&#xff0c;成为众多企业面临的关键挑战。尤其是在手机壳 CNC 加工这一细分行业&#xff0c;随着市场需求的持续增长&#xff0c;对生产效能的要求愈发严苛。而复合机器人的出现&#xff0c;正…...

深入浅出负载均衡:理解其原理并选择最适合你的实现方式

负载均衡是一种在多个计算资源&#xff08;如服务器、CPU核心、网络链接等&#xff09;之间分配工作负载的技术&#xff0c;旨在优化资源利用率、提高系统吞吐量和降低响应时间。负载均衡的实现方式多种多样&#xff0c;以下是几种常见的实现方式&#xff1a; 1. 硬件负载均衡&…...

征程 6X release版本内核模块安全加载

1.概述 征程 6X 系统在 release 编译时支持内核模块签名验证&#xff0c;仅加载使用正确密钥进行数字签名的内核模块。禁止加载未签名的内核模块或使用错误密钥签名的内核模块&#xff0c;客户需要替换成自己的 key 进行签名。 模块签名启用后&#xff0c;Linux 内核将仅加载…...

uni-app的学习

uni-app 有着跨平台支持、丰富的插件和生态系统、高性能、集成开发工具HBuilderX的配合使用。允许使用者仅通过一套代码发布到多平台使用。 uni-app官网 uni-app 是一个适合开发跨平台移动应用和小程序的框架&#xff0c;能够大幅提高开发效率。 一、了解 1.1 工具准备 从Git…...

国产信创实践(国能磐石服务器操作系统CEOS +东方通TongHttpServer)

替换介绍&#xff1a; 国能磐石服务器操作系统CEOS 对标 Linux 服务器操作系统&#xff08;Ubuntu, CentOS&#xff09; 东方通TongHttpServer 对标 Nginx 负载均衡Web服务器 第一步&#xff1a; 服务器安装CEOS映像文件&#xff0c;可直接安装&#xff0c;本文采用使用VMware …...

前端实时显示当前在线人数的实现

实时显示当前在线人数的实现 本文档提供了在网页上实时显示当前在线人数的多种实现方法&#xff0c;包括使用 WebSocket 实现实时更新和轮询方式实现非实时更新。 方法一&#xff1a;使用 WebSocket 实现实时更新 服务器端设置 通过 Node.js 和 WebSocket 库&#xff08;如 …...

为AI聊天工具添加一个知识系统 之27 支持边缘计算设备的资源存储库及管理器

本文问题 现在我们回到 ONE/TWO/TREE 的资源存储库 的设计--用来指导 足以 支持 本项目&#xff08;为AI聊天工具增加一套知识系统&#xff09;的 核心能力 “语言处理” 中 最高难度系数的“自然语言处理” 中最具挑战性的“含糊性” 问题的解决。--因为足以解决 自然语言中最…...

继续坚持与共勉

经过期末考试后&#xff0c;又要开始学习啦。 当时一直在刷算法题就很少写博客了&#xff0c;现在要继续坚持写博客&#xff0c;将每天对于题的感悟记录下来。 同时我将会在学习Linux操作系统&#xff0c;对于过去学习的内容进行回顾&#xff01;&#xff01; 在此&#xff…...

PHP的扩展Imagick的安装

windows下的安装 下载&#xff1a;Imagick扩展 PECL :: Package :: imagick 3.7.0 for Windows​​​​​​​ 下载&#xff1a;ghostscript&#xff08;PDF提取图片时用到&#xff0c;不处理PDF可以不安装&#xff09; Ghostscript : Downloads 安装扩展 Imagick解压后&…...

【2024年华为OD机试】 (A卷,100分)- 租车骑绿岛(Java JS PythonC/C++)

一、问题描述 题目描述 部门组织绿岛骑行团建活动。租用公共双人自行车&#xff0c;每辆自行车最多坐两人&#xff0c;最大载重 M。 给出部门每个人的体重&#xff0c;请问最多需要租用多少双人自行车。 输入描述 第一行两个数字 m、n&#xff0c;分别代表自行车限重&#…...

Solidity入门: 函数

函数 Solidity语言的函数非常灵活&#xff0c;可以进行各种复杂操作。在本教程中&#xff0c;我们将会概述函数的基础概念&#xff0c;并通过一些示例演示如何使用函数。 我们先看一下 Solidity 中函数的形式: function <function name>(<parameter types>) {in…...

1、docker概念和基本使用命令

docker概念 微服务&#xff1a;不再是以完整的物理机为基础的服务软件&#xff0c;而是借助于宿主机的性能。以小量的形式&#xff0c;单独部署的应用。 docker&#xff1a;是一个开源的应用容器引擎&#xff0c;基于go语言开发的&#xff0c;使用时apache2.0的协议。docker是…...

【Python】深入Python元类:动态生成类与对象的艺术

在Python中&#xff0c;元类&#xff08;Metaclass&#xff09;是一个强大且高级的特性&#xff0c;允许开发者在类创建时控制其行为与属性。通过元类&#xff0c;开发者可以动态生成类和对象&#xff0c;实现自定义的类行为&#xff0c;进而增强代码的灵活性和可扩展性。本文将…...

数字孪生可视化在各个行业的应用场景

数字孪生技术&#xff0c;作为新一代信息技术的集大成者&#xff0c;正在深刻改变着我们对物理世界的认知和管理方式。本文将探讨数字孪生可视化在不同行业的应用场景&#xff0c;以及它们如何赋能行业数字化转型。 1. 智慧城市与交通 在智慧城市领域&#xff0c;数字孪生技术…...

CES Asia 2025科技盛宴,AI智能体成焦点

2025第七届亚洲消费电子技术展&#xff08;CES Asia赛逸展&#xff09;将在北京拉开帷幕&#xff0c;AI智能体有望成为展会的核心亮点。 深圳市人工智能行业协会发文表示全力支持CES Asia 2025&#xff08;赛逸展&#xff09;&#xff0c;称其为人工智能领域的创新发展提供了强…...

【第04阶段-机器学习深度学习篇-1-深度学习基础-深度学习介绍】

1 深度学习概念 深度学习是基于机器学习延伸出来的一个新的领域&#xff0c;由以人大脑结构为启发的神经网络算法为起源加之模型结构深度的增加发展&#xff0c;并伴随大数据和计算能力的提高而产生的一系列新的算法。 2 深度学习发展 其概念由著名科学家Geoffrey Hinton等人…...

android framework.jar 在应用中使用

在开发APP中&#xff0c;有时会使用系统提供的framework.jar 来替代 android.jar, 在gradle中配置如下&#xff1a; 放置framework.jar 依赖配置 3 优先级配置 gradle.projectsEvaluated {tasks.withType(JavaCompile) {Set<File> fileSet options.bootstrapClasspat…...

带格式 pdf 翻译

支持 openAI 接口&#xff0c;国内 deepseek 接口兼容 openAI 接口&#xff0c; deepseek api 又非常便宜 https://pdf2zh.com/ https://github.com/Byaidu/PDFMathTranslate...

Flutter项目适配鸿蒙

Flutter项目适配鸿蒙 前言Flutter项目适配鸿蒙新工程直接支持ohos构建新项目编译运行 适配已有的Flutter项目 前言 目前市面上使用Flutter技术站的app不在少数&#xff0c;对于Flutter的项目&#xff0c;可能更多的是想直接兼容Harmonyos&#xff0c;而不是直接在重新开发一个…...

轻量自高斯注意力机制LSGAttention模型详解及代码复现

模型背景 近年来,卷积神经网络(CNN)在高光谱图像分类领域取得了显著进展。然而,CNN面临 长距离关系建模 和 计算成本 增加的挑战。为解决这些问题,研究人员提出了基于 轻量自高斯注意(Light Self-Gaussian-Attention, LSGA) 机制的视觉转换器(Vision Transformer, VIT),旨…...

vue事件对象$event

事件参数可以获取event对象和通过事件传递数据 获取 event 对象 <template><h1>Hello world</h1><button click"addCount">Add</button><p>{{ count }}</p> </template> <script>export default{data(){ret…...

PyCharm文档管理

背景&#xff1a;使用PyCharmgit做文档管理 需求&#xff1a;需要PyCharm自动识别docx/xslx/vsdx等文件类型&#xff0c;并在PyCharm内点击文档时唤起系统内关联应用(如word、excel、visio) 设置步骤&#xff1a; 1、file -》 settings -》file types 2、在Files opened i…...

Windows下调试Dify相关组件(2)--后端Api

1.部署依赖的服务&#xff08;代码最外层的docker目录&#xff09; 1.1 将middleware.env.example复制&#xff0c;并改名为middleware.env。 1.2 查看docker-compose.middleware.yaml&#xff0c;有5个服务 db&#xff1a;postgres数据库。 redis&#xff1a;redis缓存。 sa…...

Flask----前后端不分离-登录

文章目录 扩展模块flask-wtf 的简单使用定义用户数据模型flask-login完成用户登录 扩展模块 flask-sqlalchmy&#xff0c;连接数据库flask-login&#xff0c;处理用户的登录&#xff0c;认证flask-session&#xff0c;会话保持&#xff0c;默认对用户数据加密&#xff0c;存储…...

Group3r:一款针对活动目录组策略安全的漏洞检测工具

关于Group3r Group3r是一款针对活动目录组策略安全的漏洞检测工具&#xff0c;可以帮助广大安全研究人员迅速枚举目标AD组策略中的相关配置&#xff0c;并识别其中的潜在安全威胁。 Group3r专为红蓝队研究人员和渗透测试人员设计&#xff0c;该工具可以通过将 LDAP 与域控制器…...

ElasticSearch 认识和安装ES

文章目录 一、为什么学ElasticSearch?1.ElasticSearch 简介2.ElasticSearch 与传统数据库的对比3.ElasticSearch 应用场景4.ElasticSearch 技术特点5.ElasticSearch 市场表现6.ElasticSearch 的发展 二、认识和安装ES1.认识 Elasticsearch&#xff08;简称 ES&#xff09;2.El…...

CNN Test Data

由于数据量过大&#xff0c;打不开了 搞一组小的吧。收工睡觉 https://download.csdn.net/download/spencer_tseng/90256048...

git 转移文件夹

打开终端或命令行界面&#xff1a;首先&#xff0c;确保你的电脑上安装了 Git&#xff0c;并打开终端或命令行界面。 导航到你的仓库目录&#xff1a;使用 cd 命令来切换到包含你想要移动文件夹的仓库的目录。 cd /path/to/your/repository使用 git mv 命令移动文件夹&#x…...

计算机网络学习

网络安全&#xff1a;前端开发者必知&#xff1a;Web安全威胁——XSS与CSRF攻击及其防范-CSDN博客 三次握手四次挥手&#xff1a;前端网络---三次握手四次挥手_前端三次握手-CSDN博客 http协议和https协议的区别&#xff1a;前端网络---http协议和https协议的区别-CSDN博客 …...