Python从0到100(七十二):Python OpenCV-OpenCV实现手势音量控制(文末送书)
前言:
零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能相关知识,成为学习学习和学业的先行者!
欢迎大家订阅专栏:零基础学Python:Python从0到100最新最全教程!
今天来学习一下如何使用OpenCV实现手势音量控制,欢迎大家一起前来探讨学习~
一、需要的库及功能介绍
本次实验需要使用OpenCV和mediapipe库进行手势识别,并利用手势距离控制电脑音量。
导入库:
- cv2:OpenCV库,用于读取摄像头视频流和图像处理。
- mediapipe:mediapipe库,用于手部关键点检测和手势识别。
- ctypes和comtypes:用于与操作系统的音频接口进行交互。
- pycaw:pycaw库,用于控制电脑音量。
功能:
- 初始化mediapipe和音量控制模块,获取音量范围。
- 打开摄像头,读取视频流。
- 对每一帧图像进行处理:
- 转换图像为RGB格式。
- 使用mediapipe检测手部关键点。
- 如果检测到手部关键点:
- 在图像中标注手指关键点和手势连线。
- 解析手指关键点坐标。
- 根据拇指和食指指尖的坐标,计算手势距离。
- 将手势距离转换为音量大小,并控制电脑音量。
- 显示处理后的图像。
- 循环执行前述步骤,直到手动停止程序或关闭摄像头。
注意事项:
- 在运行代码之前,需要安装相关库(opencv、mediapipe、pycaw)。
- 需要连接音频设备并使其可访问。
- 检测到多个手部时,只处理第一个检测到的手部。
- 检测到手指关键点时,将索引指为0的关键点作为拇指的指尖,索引指为1的关键点作为食指的指尖。
cv2.VideoCapture()函数参数问题
这并没有错。但在树莓派上调用时需要更改参数,改为:
cap = cv2.VideoCapture(1)
调用电脑摄像头时:
电脑在用cv2.VideoCapture(0)
时,程序结束后会有报错:
[ WARN:0] SourceReaderCB::~SourceReaderCB terminating async callback
需要改为:
cv2.VideoCapture(0,cv2.CAP_DSHOW)
二、导入所需要的模块
# 导入OpenCV
import cv2
# 导入mediapipe
import mediapipe as mp
# 导入电脑音量控制模块
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume# 导入其他依赖包
import time
import math
import numpy as np
三、初始化 HandControlVolume 类
class HandControlVolume:def __init__(self):"""初始化 HandControlVolume 类的实例初始化 mediapipe 对象,用于手部关键点检测和手势识别。获取电脑音量接口,并获取音量范围。"""# 初始化 medialpipeself.mp_drawing = mp.solutions.drawing_utilsself.mp_drawing_styles = mp.solutions.drawing_stylesself.mp_hands = mp.solutions.hands# 获取电脑音量范围devices = AudioUtilities.GetSpeakers()interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)self.volume = cast(interface, POINTER(IAudioEndpointVolume))self.volume.SetMute(0, None)self.volume_range = self.volume.GetVolumeRange()
- 初始化 mediapipe 对象,用于手部关键点检测和手势识别。
- 获取电脑音量接口,并获取音量范围。
四、主函数
1.计算刷新率
-
初始化刷新率的计算,记录当前时间作为初始时间。
-
使用
OpenCV
打开视频流,此处读取摄像头设备,默认使用设备ID为0。 -
设置视频流的分辨率为指定的
resize_w和resize_h
大小,并将图像resize为该尺寸。 -
在使用hands对象之前,使用
with
语句创建一个上下文环境,设置手部检测和追踪的相关参数,包括最小检测置信度、最小追踪置信度和最大手的数量。 -
进入循环,判断视频流是否打开。使用
cap.read()
函数从视频流中读取一帧图像,返回的success
表示是否读取成功,image
则是读取到的图像。 -
对读取到的图像进行
resize
,将其调整为指定的大小。如果读取失败,则打印提示信息并继续下一次循环。
# 主函数def recognize(self):# 计算刷新率fpsTime = time.time()# OpenCV读取视频流cap = cv2.VideoCapture(0)# 视频分辨率resize_w = 640resize_h = 480# 画面显示初始化参数rect_height = 0rect_percent_text = 0with self.mp_hands.Hands(min_detection_confidence=0.7,min_tracking_confidence=0.5,max_num_hands=2) as hands:while cap.isOpened():success, image = cap.read()image = cv2.resize(image, (resize_w, resize_h))if not success:print("空帧.")continue
2.提高性能
-
将图像的可写标志image.flags.writeable设置为False,以便进行内存优化。
-
将图像从BGR格式转换为RGB格式,这是因为MediaPipe模型处理的输入要求为RGB格式。
-
对图像进行水平翻转,即镜像操作,以使图像更符合常见的镜像显示。
-
使用MediaPipe模型对图像进行处理,得到结果。
-
将图像的可写标志image.flags.writeable设置为True,以重新启用对图像的写入操作。
-
将图像从RGB格式转换回BGR格式,以便后续的显示和处理。
这些优化操作旨在提高程序的性能和效率。其中,将图像的可写标志设置为False可以减少不必要的内存拷贝,转换图像的格式和镜像操作则是为了符合MediaPipe模型的输入要求和更好地进行手势识别。最后,将图像转换回BGR格式是为了与OpenCV的显示函数兼容。
# 提高性能image.flags.writeable = False# 转为RGBimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 镜像image = cv2.flip(image, 1)# mediapipe模型处理results = hands.process(image)image.flags.writeable = Trueimage = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
3.判断是否有手掌
-
判断
results.multi_hand_landmarks
是否存在,即是否检测到手掌。如果存在,则继续执行下面的代码。 -
遍历
results.multi_hand_landmarks
中的每个hand_landmarks,即遍历每个检测到的手掌。 -
使用
self.mp_drawing.draw_landmarks
函数将检测到的手掌标注在图像上,包括手指的关键点和手指之间的连接线。
# 判断是否有手掌if results.multi_hand_landmarks:# 遍历每个手掌for hand_landmarks in results.multi_hand_landmarks:# 在画面标注手指self.mp_drawing.draw_landmarks(image,hand_landmarks,self.mp_hands.HAND_CONNECTIONS,self.mp_drawing_styles.get_default_hand_landmarks_style(),self.mp_drawing_styles.get_default_hand_connections_style())
4.解析手指,存入各个手指坐标
首先解析手指的坐标,并存入landmark_list列表中。然后,根据手指的坐标计算出大拇指和食指的指尖坐标,以及两者的中间点坐标。接下来,绘制了大拇指、食指和两者之间的连线,并使用勾股定理计算了两个指尖之间的长度。
-
创建一个空的landmark_list列表用于存储手指坐标。
-
遍历手部关键点的每个元素,将每个关键点的id、x、y和z坐标存储在一个列表中,然后将该列表添加到landmark_list中。
-
判断landmark_list是否不为空,如果不为空,继续执行下面的代码。
-
从landmark_list中获取大拇指指尖坐标的列表项,然后计算出在图像上的像素坐标。
-
从landmark_list中获取食指指尖坐标的列表项,然后计算出在图像上的像素坐标。
-
计算大拇指指尖和食指指尖的中间点坐标。
-
绘制大拇指和食指的指尖点,以及中间点。
-
绘制大拇指和食指之间的连线。
-
使用勾股定理计算大拇指指尖和食指指尖之间的长度,保存在line_len中。
# 解析手指,存入各个手指坐标landmark_list = []for landmark_id, finger_axis in enumerate(hand_landmarks.landmark):landmark_list.append([landmark_id, finger_axis.x, finger_axis.y,finger_axis.z])if landmark_list:# 获取大拇指指尖坐标thumb_finger_tip = landmark_list[4]thumb_finger_tip_x = math.ceil(thumb_finger_tip[1] * resize_w)thumb_finger_tip_y = math.ceil(thumb_finger_tip[2] * resize_h)# 获取食指指尖坐标index_finger_tip = landmark_list[8]index_finger_tip_x = math.ceil(index_finger_tip[1] * resize_w)index_finger_tip_y = math.ceil(index_finger_tip[2] * resize_h)# 中间点finger_middle_point = (thumb_finger_tip_x + index_finger_tip_x) // 2, (thumb_finger_tip_y + index_finger_tip_y) // 2# print(thumb_finger_tip_x)thumb_finger_point = (thumb_finger_tip_x, thumb_finger_tip_y)index_finger_point = (index_finger_tip_x, index_finger_tip_y)# 画指尖2点image = cv2.circle(image, thumb_finger_point, 10, (255, 0, 255), -1)image = cv2.circle(image, index_finger_point, 10, (255, 0, 255), -1)image = cv2.circle(image, finger_middle_point, 10, (255, 0, 255), -1)# 画2点连线image = cv2.line(image, thumb_finger_point, index_finger_point, (255, 0, 255), 5)# 勾股定理计算长度line_len = math.hypot((index_finger_tip_x - thumb_finger_tip_x),(index_finger_tip_y - thumb_finger_tip_y))
5.获取电脑最大最小音量
实现获取电脑的最大和最小音量,并将指尖的长度映射到音量范围和矩形显示上,然后将映射后的音量值设置为电脑的音量。具体过程如下:
-
self.volume_range[0]和self.volume_range[1]
分别获取电脑的最小音量和最大音量。 -
np.interp函数
将指尖的长度line_len映射到从50到300的范围,再映射到最小音量和最大音量的范围,得到音量值vol。 -
np.interp函数
将指尖的长度line_len映射到从50到300的范围,再映射到从0到200的范围,得到矩形的高度rect_height。 -
np.interp函数
将指尖的长度line_len映射到从50到300的范围,再映射到从0到100的范围,得到矩形百分比显示的数值rect_percent_text。 -
self.volume.SetMasterVolumeLevel方法
将音量值vol设置为电脑的音量。
# 获取电脑最大最小音量min_volume = self.volume_range[0]max_volume = self.volume_range[1]# 将指尖长度映射到音量上vol = np.interp(line_len, [50, 300], [min_volume, max_volume])# 将指尖长度映射到矩形显示上rect_height = np.interp(line_len, [50, 300], [0, 200])rect_percent_text = np.interp(line_len, [50, 300], [0, 100])# 设置电脑音量self.volume.SetMasterVolumeLevel(vol, None)
6.显示矩形
cv2.putText函数
来在图像上显示矩形框的百分比值;
cv2.rectangle函数
来绘制矩形框并填充颜色;
cv2.putText函数
来在图像上显示当前帧的刷新率FPS;
cv2.imshow函数
来显示处理后的图像;
cv2.waitKey函数
等待按键输入,当按下ESC键或关闭窗口时退出程序;
HandControlVolume
类的recognize方法调用了手势识别的功能。
# 显示矩形cv2.putText(image, str(math.ceil(rect_percent_text)) + "%", (10, 350),cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)image = cv2.rectangle(image, (30, 100), (70, 300), (255, 0, 0), 3)image = cv2.rectangle(image, (30, math.ceil(300 - rect_height)), (70, 300), (255, 0, 0), -1)# 显示刷新率FPScTime = time.time()fps_text = 1 / (cTime - fpsTime)fpsTime = cTimecv2.putText(image, "FPS: " + str(int(fps_text)), (10, 70),cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)# 显示画面cv2.imshow('MediaPipe Hands', image)if cv2.waitKey(5) & 0xFF == 27 or cv2.getWindowProperty('MediaPipe Hands', cv2.WND_PROP_VISIBLE) < 1:breakcap.release()# 开始程序
control = HandControlVolume()
control.recognize()
五、实战演示
通过演示我们可以发现,食指与大拇指之间在屏幕中的的距离越远,那么我们的音量会越大,反之越小,实现了通过手势对音量的控制。
六、源码分享
import cv2
import mediapipe as mp
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import time
import math
import numpy as npclass HandControlVolume:def __init__(self):# 初始化medialpipeself.mp_drawing = mp.solutions.drawing_utilsself.mp_drawing_styles = mp.solutions.drawing_stylesself.mp_hands = mp.solutions.hands# 获取电脑音量范围devices = AudioUtilities.GetSpeakers()interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)self.volume = cast(interface, POINTER(IAudioEndpointVolume))self.volume.SetMute(0, None)self.volume_range = self.volume.GetVolumeRange()# 主函数def recognize(self):# 计算刷新率fpsTime = time.time()# OpenCV读取视频流cap = cv2.VideoCapture(0)# 视频分辨率resize_w = 640resize_h = 480# 画面显示初始化参数rect_height = 0rect_percent_text = 0with self.mp_hands.Hands(min_detection_confidence=0.7,min_tracking_confidence=0.5,max_num_hands=2) as hands:while cap.isOpened():success, image = cap.read()image = cv2.resize(image, (resize_w, resize_h))if not success:print("空帧.")continue# 提高性能image.flags.writeable = False# 转为RGBimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 镜像image = cv2.flip(image, 1)# mediapipe模型处理results = hands.process(image)image.flags.writeable = Trueimage = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)# 判断是否有手掌if results.multi_hand_landmarks:# 遍历每个手掌for hand_landmarks in results.multi_hand_landmarks:# 在画面标注手指self.mp_drawing.draw_landmarks(image,hand_landmarks,self.mp_hands.HAND_CONNECTIONS,self.mp_drawing_styles.get_default_hand_landmarks_style(),self.mp_drawing_styles.get_default_hand_connections_style())# 解析手指,存入各个手指坐标landmark_list = []for landmark_id, finger_axis in enumerate(hand_landmarks.landmark):landmark_list.append([landmark_id, finger_axis.x, finger_axis.y,finger_axis.z])if landmark_list:# 获取大拇指指尖坐标thumb_finger_tip = landmark_list[4]thumb_finger_tip_x = math.ceil(thumb_finger_tip[1] * resize_w)thumb_finger_tip_y = math.ceil(thumb_finger_tip[2] * resize_h)# 获取食指指尖坐标index_finger_tip = landmark_list[8]index_finger_tip_x = math.ceil(index_finger_tip[1] * resize_w)index_finger_tip_y = math.ceil(index_finger_tip[2] * resize_h)# 中间点finger_middle_point = (thumb_finger_tip_x + index_finger_tip_x) // 2, (thumb_finger_tip_y + index_finger_tip_y) // 2# print(thumb_finger_tip_x)thumb_finger_point = (thumb_finger_tip_x, thumb_finger_tip_y)index_finger_point = (index_finger_tip_x, index_finger_tip_y)# 画指尖2点image = cv2.circle(image, thumb_finger_point, 10, (255, 0, 255), -1)image = cv2.circle(image, index_finger_point, 10, (255, 0, 255), -1)image = cv2.circle(image, finger_middle_point, 10, (255, 0, 255), -1)# 画2点连线image = cv2.line(image, thumb_finger_point, index_finger_point, (255, 0, 255), 5)# 勾股定理计算长度line_len = math.hypot((index_finger_tip_x - thumb_finger_tip_x),(index_finger_tip_y - thumb_finger_tip_y))# 获取电脑最大最小音量min_volume = self.volume_range[0]max_volume = self.volume_range[1]# 将指尖长度映射到音量上vol = np.interp(line_len, [50, 300], [min_volume, max_volume])# 将指尖长度映射到矩形显示上rect_height = np.interp(line_len, [50, 300], [0, 200])rect_percent_text = np.interp(line_len, [50, 300], [0, 100])# 设置电脑音量self.volume.SetMasterVolumeLevel(vol, None)# 显示矩形cv2.putText(image, str(math.ceil(rect_percent_text)) + "%", (10, 350),cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)image = cv2.rectangle(image, (30, 100), (70, 300), (255, 0, 0), 3)image = cv2.rectangle(image, (30, math.ceil(300 - rect_height)), (70, 300), (255, 0, 0), -1)# 显示刷新率FPScTime = time.time()fps_text = 1 / (cTime - fpsTime)fpsTime = cTimecv2.putText(image, "FPS: " + str(int(fps_text)), (10, 70),cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)# 显示画面cv2.imshow('xyp', image)if cv2.waitKey(5) & 0xFF == 27 or cv2.getWindowProperty('MediaPipe Hands', cv2.WND_PROP_VISIBLE) < 1:breakcap.release()
control = HandControlVolume()
control.recognize()
文末送书
Dream送书活动——第四十五期
《AI全能助手:ChatGPT工作效率提升技巧与案例》免费包邮送三本! 参与方式:
1.点赞收藏文章
2.在评论区留言:人生苦短,我用Python!(多可评论三条)
3.随机抽取4位免费送出!
4.截止时间: 2024-11-19
本期推荐:
AI全能助手:ChatGPT工作效率提升技巧与案例
京东:https://item.jd.com/14628194.html
13个知识模块+60个实操场景+AI工具使用方法,多场景落地新手辅助入门,轻松调教出24小时工作助手,让一人胜过一个团队。
关键点:
13个知识模块+60个实操场景:办公技能、求职面试、人际关系、文案写作、演讲提升、活动策划、电商营销、团队管理、实体创业、教育培训、金融行业、亲子教育、文创文旅
等领域皆有涉猎。多场景落地新手辅助入门:以职场演讲为例,本书从开头、结尾、金句、声音优化技巧、文案迭代等多个角度进行深入讲解,力求帮助读者透彻掌握这项技能。AI工具使用方法详解:详细介绍ChatGPT和文心一言等多种AI辅助工具的使用技巧,并做了演示帮助读者理解。形成完整认知体系:对AI给出的回答做了客观中肯的点评,力求给读者提供独特的认知与思考视角,帮助读者形成一套完整的认知与思考逻辑。
内容简介:
本书结合作者的职场工作经验和AI使用经验,讲解了AI工具在不同工作场景中的使用方法和技巧,能帮助读者快速提升工作效率。全书共设置了13个知识模块,每个知识模块都设置了场景模拟与实操案例。真正做到了让读者看得懂,学得会,用得上。全书语言通俗易懂,案例来自实际工作,并有详细的思路点评,能够帮助读者轻松入门并建立系统认知,吃透AI运用的底层逻辑,真正拥有自己的AI全能助手。本书适合想要提升职场办公技能与效率的人士阅读,同样适合作为学校、企业和教育机构的培训教材。
作者简介:
本书结合作者的职场工作经验和 AI 使用经验,讲解了 AI 工具在不同工作场景中的使用方法和技巧,能帮助读者快速提升工作效率。全书共设置了13个知识模块,每个知识模块都设置了场景模拟与实操案例。真正做到了让读者看得懂,学得会,用得上。
全书语言通俗易懂,案例来自实际工作,并有详细的思路点评,能够帮助读者轻松入门并建立系统认知,吃透 AI 运用的底层逻辑,真正拥有自己的 AI 全能助手。本书适合想要提升职场办公技能与效率的人士阅读,同样适合作为学校、企业和教育机构的培训教材。
相关文章:

Python从0到100(七十二):Python OpenCV-OpenCV实现手势音量控制(文末送书)
前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…...

【云原生开发】K8S多集群管理系统成果展示
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
spring boot项目打成war包部署
1.修改pom.xml 在 pom.xml 里设置 <packaging>war</packaging>2.移除嵌入式tomcat插件 在 pom.xml 里找到spring-boot-starter-web依赖,在其中添加如下代码, <dependency><groupId>org.springframework.boot</groupId>&l…...

网络学习第四篇
引言: 我们在第三篇的时候出现了错误,我们要就行排错,那么我们要知道一下怎么配置静态路由实现ping通,这样子我们才知道下一跳到底是什么,为什么这样子做。 实验目的 理解和掌握静态路由的基本概念和配置方法。 实…...

【资料】网络安全风险评估报告,风险管理报告,网络安全风险管理计划,网络安全网络安全能力验证报(Word原件)
一、概述 1.1工作方法 1.2评估依据 1.3评估范围 1.4评估方法 1.5基本信息 二、资产分析 2.1 信息资产识别概述 2.2 信息资产识别 三、评估说明 3.1无线网络安全检查项目评估 3.2无线网络与系统安全评估 3.3 ip管理与补丁管理 3.4防火墙 四、威胁细类分析 4.1威胁…...

Django基础用法+Demo演示
Django快速上手 参考: Django快速上手 再写几个页面 编辑demo1/urls.py, 添加URL和视图函数映射 urlpatterns [path(index/, views.index),path(user/list/, views.user_list),path(user/add/, views.user_add), ]编辑app01/views.py,添加几个函数 from djang…...

【webrtc】 RTP 中的 MID(Media Stream Identifier)
RTP 中的 MID(Media Stream Identifier) RID及其与MID的区别 cname与mid的对比【webrtc】CNAME 是rtprtcp中的Canonical Name(规范化名称) 同样都是RTP头部扩展: 基于mediasoup的最新的代码,学习,发现mid在创建RtpSendStream时是必须传递的参数: 例如 D:\XTRANS\soup\…...
React 中 为什么多个 JSX 标签需要被一个父元素包裹?
为什么多个 JSX 标签需要被一个父元素包裹? JSX 虽然看起来很像 HTML,但在底层其实被转化为了 JavaScript 对象,你不能在一个函数中返回多个对象,除非用一个数组把他们包装起来。这就是为什么多个 JSX 标签必须要用一个父元素或者…...

记录日志中logback和log4j2不能共存的问题
本文章记录设置两个日志时候,控制台直接报错 标黄处就是错误原因:1. SLF4J(W):类路径包含多个SLF4J提供程序。 SLF4J(W):找到提供程序[org.apache.logging.slf4j. net]。 SLF4J(W):找到提供程序[ch.qos.log .classi…...
第5章: 图像变换与仿射操作
图像变换和仿射操作是图像处理中常用的技术,通过旋转、缩放、平移、剪裁等操作,可以实现多种视觉效果以及数据增强。 1.1 图像旋转 1.1.1 基础旋转操作 使用 rotate() 方法可以对图像进行旋转操作,指定旋转的角度(以度为单位&am…...

【计算机网络】【网络层】【习题】
计算机网络-传输层-习题 文章目录 13. 图 4-69 给出了距离-向量协议工作过程,表(a)是路由表 R1 初始的路由表,表(b)是相邻路由器 R2 传送来的路由表。请写出 R1 更新后的路由表(c)。…...
Scala的不可变Map常用操作
//类型:不可变,可变 //操作:添加元素,删除元素,查询元素,删除元素,遍历 object map {def main(args: Array[String]): Unit {//不可变Mapval map1 Map("鄂"->"湖北省"…...
nginx配置负载均衡详解
在现代的 web 应用中,负载均衡是确保高可用性、可扩展性和稳定性的关键技术之一。Nginx 是一个非常流行的反向代理服务器和负载均衡器,它支持多种负载均衡策略,能够帮助将客户端的请求分发到多个后端服务器,以提高系统的整体性能和…...
传奇996_19——龙岭总结
功能: 切割 切割属性: 即人物属性,可以设置临时属性或者永久属性,龙岭使用的是临时属性,所谓临时就是存在有效期,龙岭设置的有效期是123456789秒,即1428.89802天。 龙岭写法(倒叙…...

el-table 行列文字悬浮超出屏幕宽度不换行的问题
修改前的效果 修改后的效果 ui框架 element-plus 在网上找了很多例子都没找到合适的 然后这个东西鼠标挪走就不显示 控制台也不好调试 看了一下El-table的源码 他这个悬浮文字用的el-prpper 包着的 所以直接改 .el-table .el-propper 设置为max-width:1000px 就可以了 吐槽一…...

鸿蒙HarmonyOS 网络请求获取数据Http
注意的是;要为接口返回值指定类型 ,以及定义接口数据类型 index.ets import { http } from kit.NetworkKit;interface createAtType {date: number,}interface dataListType {createAt: createAtType;imgUrl: }Component export default struct TabBar {State dat…...

MySQL技巧之跨服务器数据查询:高级篇-先调用A数据库的MySql存储过程再复制到B数据库的表中
MySQL技巧之跨服务器数据查询:高级篇-先调用A数据库的MySql存储过程再复制到B数据库的表中 基础篇已经描述:借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的…...

JavaScript逆向爬虫教程-------基础篇之JavaScript密码学以及CryptoJS各种常用算法的实现
目录 一、密码学介绍 1.1 为什么要学密码学?1.2 密码学里面学哪一些 二、字符编码三、位运算四、Hex 编码与 Base64 编码 4.1 Hex 编码4.2 Base64 编码 五、消息摘要算法 5.1 简介5.2 JS中的MD5、SHA、HMAC、SM3 六、对称加密算法 6.1 介绍6.2 加密模式和填充方式6.3 CryptoJ…...

【分布式】万字图文解析——深入七大分布式事务解决方案
分布式事务 分布式事务是指跨多个独立服务或系统的事务管理,以确保这些服务中的数据变更要么全部成功,要么全部回滚,从而保证数据的一致性。在微服务架构和分布式系统中,由于业务逻辑往往会跨多个服务,传统的单体事务…...
apache2配置多站点
环境 ubuntu 14.04 apache2 Server version: Apache/2.4.7 (Ubuntu) Server built: Apr 3 2019 18:04:25 步骤 修改/etc/apache2/sites-enabled/000-default.conf 增加VirtualHost段,指定不同的ServerName、DocumentRoot等参数 <VirtualHost *:80>…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...