Python自动化(6)——图像模块

本文所述的方法都是基于前几章的后台点击,因此同样需要绑定窗口句柄。

Python自动化(6)——图像模块

识色

定点比色

def cv2CompareColorOneMatch(self, x, y, hexColor, _similar=0, border=None):startX = 0startY = 0similar = _similar + self.colorOffsetif border:startX = border[0]startY = border[1]color = self.Hex2RGB(hexColor)screenQImg = self.screen.captureScreen(None, border)if int(x)-startX <= 0:print('cv2CompareColorOneMatch error x: '+str(x)+', startX: '+str(startX))if int(y)-startY <= 0:print('cv2CompareColorOneMatch error y: '+str(y)+', startY: '+str(startY))res = QColor(screenQImg.pixel(int(x)-startX, int(y)-startY)).getRgb()print('cv2CompareColorOneMatch x: '+str(x)+', y: '+str(y)+', re: '+str(res))if abs(res[0] - color[0]) < similar and abs(res[1] - color[1]) < similar and abs(res[2] - color[2]) < similar:return Trueelse:return False

参数:
前两个传输是绑定的窗口的x,y坐标
hexColor:16进制的色值(传字符串,例如:“#fffbeb”)
_similar:色值偏移值,默认为0,一般会传3~5
border:截图范围,默认截全屏。截图截少一点,(理论上)性能好一点,使用时一般只会截那个点周围的十来个像素
返回值:如果截图判断的点与传进来的色值相减,RGB每个值都在色值偏移范围内,返回True,否则返回False
其中,self.Hex2RGB是将16进制色值转换为RGB值的方法,可以在最下面的全部代码看到。
self.colorOffset是全局变量,用于设置全局的色值偏差。因为某些屏幕会有色差,所以需要这个设置

定点比色的核心代码是通过QImage类的pixel方法获取到对应的像素点数据,然后转换为QColor对象,再通过QColor对象的getRgb方法获取到对应像素点的RGB色值,然后再与传进来的参数对比,得出结果。

多点比色

def cv2CompareColorMoreMatch(self, lists, _similar=0, border=None, screenQImg=None, isIgnoreBorder=False):if screenQImg == None:screenQImg = self.screen.captureScreen(None, border)startX = 0startY = 0similar = _similar + self.colorOffsetif not isIgnoreBorder and border:startX = border[0]startY = border[1]# print('cv2CompareColorMoreMatch')for x, y, hexColor in lists:color = self.Hex2RGB(hexColor)if int(x)-startX <= 0:print('cv2CompareColorOneMatch error x: '+str(x)+', startX: '+str(startX))if int(y)-startY <= 0:print('cv2CompareColorOneMatch error y: '+str(y)+', startY: '+str(startY))res = QColor(screenQImg.pixel(int(x)-startX, int(y)-startY)).getRgb()if abs(res[0] - color[0]) > similar or abs(res[1] - color[1]) > similar or abs(res[2] - color[2]) > similar:return Falsereturn True

参数:
lists:需要比较色值点的列表,例如:[[998,262,’#fffbeb’], [999,329,’#fffbeb’]]
_similar:色值偏移值,同定点比色
border:截图范围,默认截全屏。同定点比色
screenQImg:截的图片,格式是QImage,默认为空,为空时会根据border截图
isIgnoreBorder:是否忽略截图范围,默认为false。当已有一张全屏图的时候,可以用此参数。例如:graph.cv2CompareColorMoreMatch(pointList,5,border,screenshot,screenshot!=None)
这样就是如果有全屏图就忽略border,否则根据border来截图

多点比色实际上只是支持了多个点对比,核心代码同定点比色。

找色

单点找色

def cv2FindColor(self, hexColor, border=None):color = list(self.Hex2RGB(hexColor))screenImg = self.screen.captureScreen(None, border)array = numpy.array(Image.fromqimage(screenImg))res = numpy.argwhere(numpy.all(array == color, axis=2)).tolist()print('cv2FindColor res: '+str(res))return res

参数:
hexColor:字符串,16进制色值(带#号)
border:截屏范围,默认为全屏
返回值:返回全部色值相同位置的数组

单点找色的核心逻辑,其实就是先将QImage转换为PIL库的Iamge对象,然后通过numpy库的array方法将Image转换为数组以便进行数值操作。
接着使用numpy.all方法比较numpy数组中的每个像素值与指定的RGB色值,返回一个bool数组,表示哪些像素匹配指定颜色。
最后使用numpy.argwhere方法,返回bool数组中值为True的索引,然后通过tolist方法将numpy数组转换为python列表。

一般来说,这个方法比较少用,限制比较多

多点找色

def cv2FindColors(self, hexColorListStr, border=None):screenImg = self.screen.captureScreen(None, border)array = numpy.array(Image.fromqimage(screenImg))startX = 0startY = 0w = Noneh = Noneif border == None:left, top, right, bottom = win32gui.GetWindowRect(self.hwnd)w = right-lefth = bottom-topelse:startX = border[0]startY = border[1]w = border[2]-border[0]h = border[3]-border[1]rgby = []ps = []a = 0firstXY = []res = numpy.empty([0, 2])hexColorStr = hexColorListStr.split(',')for i in hexColorStr:rgb_y = i[-13:]r = int(rgb_y[0:2], 16)g = int(rgb_y[2:4], 16)b = int(rgb_y[4:6], 16)y = int(rgb_y[-2:])rgby.append([r,g,b,y])for i in range(1, len(hexColorStr)):ps.append([int(hexColorStr[i].split('|')[0]), int(hexColorStr[i].split('|')[1])])for i in rgby:result = numpy.logical_and(abs(array[:, :, 0:1] - i[0]) < i[3], abs(array[:, :, 1:2] - i[1]) < i[3], abs(array[:, :, 2:3] - i[2]) < i[3])results = numpy.argwhere(numpy.all(result == True, axis=2)).tolist()if a == 0:firstXY = copy.deepcopy(results)else:nextnextXY = copy.deepcopy(results)for index in nextnextXY:index[0] = int(index[0]) - ps[a - 1][1]index[1] = int(index[1]) - ps[a - 1][0]q = set([tuple(t) for t in firstXY])w = set([tuple(t) for t in nextnextXY])matched = numpy.array(list(q.intersection(w)))if len(matched)==0:return -1,-1res = numpy.append(res, matched, axis=0)a += 1res = res.tolist()for i in res:if res.count(i) == len(hexColorStr) - 1:print('cv2FindColors res: '+str(res))return i[1] + startX, i[0] + startYprint('cv2FindColors not find')return -1,-1

多点找色其实就是大漠插件里的多点找色实现的,其核心还是上述的找色逻辑,这里不再赘述。

识图

单模版匹配

def cv2OneMatchFindImage(self, rect, temp, qimg=None, similar=0.85):img = Noneif qimg:img = cv2.cvtColor(numpy.asarray(Image.fromqimage(qimg)),cv2.COLOR_RGB2BGR)else:img = cv2.cvtColor(numpy.asarray(Image.fromqimage(self.screen.captureScreen(None,rect))),cv2.COLOR_RGB2BGR)template = cv2.cvtColor(numpy.asarray(temp),cv2.COLOR_RGB2BGR)h, w = template.shape[:2]# 匹配模板res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)if max_val >= similar:# 计算矩形左边top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)# 返回rect数组,参数分别是topLeft,topRight,bottomLeft,bottomRight,中心点x,中心点yrect = (top_left[0], top_left[1], top_left[0]+w, top_left[1]+h, int(int(2*top_left[0]+w)/2), int(int(2*top_left[1]+h)/2))print('cv2OneMatchFindImage rect: '+str(rect))print('cv2OneMatchFindImage max_val: '+str(max_val))return rectelse:return None

参数:
rect:截图范围,为空截全屏
temp:被查找的图片,小图,PIL库的Image对象
qimg:大图,在这张图上找temp那张图,QImage对象
similar:相似度,默认0.85

模板匹配实际上就是在一张大图中找小图。其核心是基于OpenCV库的cv2.matchTemplate方法。
首先,将两张图片的颜色空间都从RGB转换为BGR,OpenCV使用BGR作为默认颜色空间,然后获取模板图像的高度h和宽度w。
然后通过cv2.matchTemplate方法进行模板匹配,在大图中寻找小图temp的位置,并返回一个二维数组,表示每个位置的匹配结果(此方法有多个不同的匹配方式,试了一下大差不差吧,没有什么最准的)。接着通过cv2.minMaxLoc方法找到最小值和最大值及其对应的位置:
min_val:最小匹配值
max_val:最大匹配值
min_loc:最小值的位置
max_loc:最大值的位置
如果匹配结果的最大匹配值满足相似度要求,则计算顶点和中心点的位置并返回。否则返回空(None)。

注意:单模板匹配只会返回最匹配的一个结果,多模板匹配会返回全部满足相似度要求的结果。

另外,这里要说明一下模板匹配的实现以及问题:
实际使用的情况中,会有时候得不到正确的结果。因此研究了一下内部逻辑,这里简单说一下。
首先看一下OpenCV文档:https://docs.opencv.org/3.4/de/da9/tutorial_template_matching.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(文档是英文,这里为了方便翻译为中文截图)
匹配方法有6种:
TM_SQDIFF:平方差匹配法
TM_SQDIFF_NORMED:归一化平方差匹配法
TM_CCORR:相关匹配法
TM_CCORR_NORMED:归一化相关匹配法
TM_CCOEFF:系数匹配法
TM_CCOEFF_NORMED:归一化相关系数匹配法
这里以TM_CCOEFF_NORMED归一化相关系数匹配法为例,公式计算过程详解:
假设有一张大图:
在这里插入图片描述
以及一张小图:
在这里插入图片描述
然后写一个简单的代码进行目标匹配并显示结果
代码:

import cv2
import numpy as np
import matplotlib.pyplot as pltdef match_and_display(image_path, template_path, method, similarity_threshold=0.9):img = cv2.imread(image_path, cv2.IMREAD_COLOR)img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)h, w = template.shaperes = cv2.matchTemplate(img_gray, template, method)loc = np.where(res >= similarity_threshold)# 在目标图像上绘制匹配区域的矩形框for pt in zip(*loc[::-1]):top_left = ptbottom_right = (pt[0] + w, pt[1] + h)cv2.rectangle(img, top_left, bottom_right, (0, 255, 0), 2)# 使用 Matplotlib 显示结果图像plt.figure(figsize=(6, 6))plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))plt.title('Matched Results')plt.axis('off')plt.show()

示例调用

image_path = './source.png'
template_path = './temp.png'
method = cv2.TM_CCOEFF_NORMED
match_and_display(image_path, template_path, method, similarity_threshold=0.95)

结果:
TM_SQDIFF(平方差匹配法):
在这里插入图片描述
TM_SQDIFF_NORMED(归一化平方差匹配法):
在这里插入图片描述
TM_CCORR(相关匹配法):
在这里插入图片描述
TM_CCORR_NORMED(归一化相关匹配法):
在这里插入图片描述
TM_CCOEFF:系数匹配法):
在这里插入图片描述
TM_CCOEFF_NORMED:归一化相关系数匹配法)
在这里插入图片描述
从结果可以看到,很多结果都把大图中两个相似的点都识别出来了,甚至还有的匹配方法识别失败了,TM_CCOEFF_NORMED匹配方法看起来是对了,不过当我把相似度降低到0.9时,一样会把大图中左上角的也匹配进结果中:
在这里插入图片描述
从官方文档可以知道,cv2进行模板匹配时,是以模板大小的搜索框依次遍历整张大图的。假设小图宽高为(w,h),大图宽高为(W,H),那么遍历时就绪遍历(W-w+1)次,每列需要遍历(H-h+1)次。
以下列的矩阵为例:
在这里插入图片描述
假设小图的矩阵为:
在这里插入图片描述
根据公式:
在这里插入图片描述
对比公式得出,完全匹配会得到1,完全负相关匹配会得到-1,完全不匹配会得到0
假设匹配的是第一个点,首先两边同时减去各自的均值,得到公式中的T ‘和I’:
在这里插入图片描述 =》 在这里插入图片描述
在这里插入图片描述
=》 在这里插入图片描述
然后求两个矩阵的内积,以及两个矩阵内元素平方和的平方的乘积再开根号:

在这里插入图片描述
result = 6/7.7459 = 0.7746
类似的,我们可以得出,当模板匹配到下面两个矩阵的时候,得出的值也是很接近1的
在这里插入图片描述 =》在这里插入图片描述 =》 在这里插入图片描述
result = 1(完全匹配)
在这里插入图片描述 =》在这里插入图片描述=》在这里插入图片描述
result = -5/5 = -1(完全不匹配)

那么,为什么上述的结果中,当相似度设置为0.9时,会把完全负相关的那一块也匹配到呢。
经过我的计算,当矩阵为
0 0
4 3 时,得到的结果:
在这里插入图片描述
result = 6.5/7.9843 = 0.8140
从结果可以看出,完全负相关周围的矩阵,其实还是有可能匹配到相似度比较高的结果,因此,cv2的模板匹配是有可能不准的。
不过,一般来说,只要取最匹配的值,一般来说结果还是可靠的。
但是,通过这次的探究,使用模板匹配时建议设置的值不低于0.65,这个是我认为比较安全的值,因为按照模板匹配的算法,可能不相关的矩阵也能算出来有0.5的相似度甚至更高,总之使用时不建议相似度设置得太低

多模板匹配

def cv2MoreMatch(self, imagePath, tempImgPath, similar=0.9):img = cv2.imread(imagePath)img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)template = cv2.imread(tempImgPath, 0)h, w = template.shape[:2]res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)# numpy.where返回的坐标值(x,y)是(h,w),注意h,w的顺序loc = numpy.where(res >= similar)rects = []for pt in zip(*loc[::-1]):top_left = ptbottom_right = (pt[0] + w, pt[1] + h)# 返回rect数组,参数分别是topLeft,topRight,bottomLeft,bottomRight,中心点x,中心点yrect = (top_left[0], top_left[1], top_left[0]+w, top_left[1]+h, int(int(2*top_left[0]+w)/2), int(int(2*top_left[1]+h)/2))rects.append(rect)print('cv2MoreMatch rect: '+str(rect))return rects

多模板匹配的参数其实与单模板匹配相同,也是传入大图、小图以及相似度。
不同的是多模板匹配使用了numpy.where方法筛选出符合相似度的结果,并返回的是一个数组。

前台找图

def pyAutoGUIMatch(self, imagePath, rect=None, similar=0.9, grayscale=False):rectInWindow = Noneif rect == None:left, top, right, bottom = win32gui.GetWindowRect(self.hwnd)rectInWindow = (left, top, right-left, bottom-top)print('rectInWindow: '+str(rectInWindow))else:rectInWindow = (rect[0], rect[1], rect[2]-rect[0], rect[3]-rect[1])pos = pyautogui.locateOnScreen(imagePath, region=rectInWindow, confidence=similar, grayscale=grayscale)print('pyAutoGUIMatch pos: '+str(pos))return pos

前台找图是通过pyautogui.locateOnScreen方法实现的,需要注意的是,如果自己的电脑连接了多个屏幕时,此方法无法在第二个屏幕上截图,如果传入的x1值大于屏幕的宽度,会导致报错needle dimension(s) exceed the haystack image or region dimensions

完整代码

#! /usr/bin env python3
# -*- coding:utf-8 -*-
# 图形处理模块import numpy
import cv2
import pyautogui
import win32gui
from Screen import Screen
from PyQt5.QtGui import QColor
from PIL import Image
import copyclass Graph():def __init__(self):self.screen = Screen()self.colorOffset = 0print('Graph init')def bind(self, hwnd):self.hwnd = hwndself.screen.bind(hwnd)def setColorOffset(self, colorOffset):self.colorOffset = colorOffset# 图形处理方法1——使用cv2(默认)  ############################################# 单个模板匹配def cv2OneMatch(self, imagePath, tempImgPath):img = cv2.imread(imagePath)template = cv2.imread(tempImgPath)h, w = template.shape[:2]# 匹配模板res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)# 计算矩形左边top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)# 返回rect数组,参数分别是topLeft,topRight,bottomLeft,bottomRight,中心点x,中心点yrect = (top_left[0], top_left[1], top_left[0]+w, top_left[1]+h, int(int(2*top_left[0]+w)/2), int(int(2*top_left[1]+h)/2))print('cv2OneMatch rect: '+str(rect))return rect# 单个模板匹配# @rect 需要被截图的范围(left, right, top, bottom),为空则全窗口截图# @temp 小图,PIL.Image格式# @qimg def cv2OneMatchFindImage(self, rect, temp, qimg=None, similar=0.85):img = Noneif qimg:img = cv2.cvtColor(numpy.asarray(Image.fromqimage(qimg)),cv2.COLOR_RGB2BGR)else:img = cv2.cvtColor(numpy.asarray(Image.fromqimage(self.screen.captureScreen(None,rect))),cv2.COLOR_RGB2BGR)template = cv2.cvtColor(numpy.asarray(temp),cv2.COLOR_RGB2BGR)h, w = template.shape[:2]# 匹配模板res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)if max_val >= similar:# 计算矩形左边top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)# 返回rect数组,参数分别是topLeft,topRight,bottomLeft,bottomRight,中心点x,中心点yrect = (top_left[0], top_left[1], top_left[0]+w, top_left[1]+h, int(int(2*top_left[0]+w)/2), int(int(2*top_left[1]+h)/2))print('cv2OneMatchFindImage rect: '+str(rect))print('cv2OneMatchFindImage max_val: '+str(max_val))return rectelse:return None# 多个模板匹配def cv2MoreMatch(self, imagePath, tempImgPath, similar=0.9):img = cv2.imread(imagePath)img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)template = cv2.imread(tempImgPath, 0)h, w = template.shape[:2]res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)# numpy.where返回的坐标值(x,y)是(h,w),注意h,w的顺序loc = numpy.where(res >= similar)rects = []for pt in zip(*loc[::-1]):top_left = ptbottom_right = (pt[0] + w, pt[1] + h)# 返回rect数组,参数分别是topLeft,topRight,bottomLeft,bottomRight,中心点x,中心点yrect = (top_left[0], top_left[1], top_left[0]+w, top_left[1]+h, int(int(2*top_left[0]+w)/2), int(int(2*top_left[1]+h)/2))rects.append(rect)print('cv2MoreMatch rect: '+str(rect))return rectsdef Hex2RGB(self, hex):r = int(hex[1:3], 16)g = int(hex[3:5], 16)b = int(hex[5:7], 16)return r, g, b# 定点比色def cv2CompareColorOneMatch(self, x, y, hexColor, _similar=0, border=None):startX = 0startY = 0similar = _similar + self.colorOffsetif border:startX = border[0]startY = border[1]color = self.Hex2RGB(hexColor)screenQImg = self.screen.captureScreen(None, border)if int(x)-startX <= 0:print('cv2CompareColorOneMatch error x: '+str(x)+', startX: '+str(startX))if int(y)-startY <= 0:print('cv2CompareColorOneMatch error y: '+str(y)+', startY: '+str(startY))res = QColor(screenQImg.pixel(int(x)-startX, int(y)-startY)).getRgb()print('cv2CompareColorOneMatch x: '+str(x)+', y: '+str(y)+', re: '+str(res))if abs(res[0] - color[0]) < similar and abs(res[1] - color[1]) < similar and abs(res[2] - color[2]) < similar:return Trueelse:return False# 多点比色def cv2CompareColorMoreMatch(self, lists, _similar=0, border=None, screenQImg=None, isIgnoreBorder=False):if screenQImg == None:screenQImg = self.screen.captureScreen(None, border)startX = 0startY = 0similar = _similar + self.colorOffsetif not isIgnoreBorder and border:startX = border[0]startY = border[1]# print('cv2CompareColorMoreMatch')for x, y, hexColor in lists:color = self.Hex2RGB(hexColor)if int(x)

完整自动化工程代码:https://gitee.com/chj-self/PythonRobotization

大佬们找到问题欢迎拍砖~

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

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

相关文章

基于Java协同过滤算法的电影推荐系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

Kotlin 中的解构

解构声明是 Kotlin 语言的一个特性&#xff0c;它允许我们从一个数据结构中提取多个变量&#xff0c;这样可以让我们的代码更加简洁易读&#xff0c;同时也提高了代码的可维护性。 在 Kotlin 中&#xff0c;解构可以用于多种数据类型&#xff0c;例如&#xff0c;列表&#xf…

几何内核开发-实现自己的NURBS曲线生成API

我去年有一篇帖子&#xff0c;介绍了NURBS曲线生成与显示的实现代码。 https://blog.csdn.net/stonewu/article/details/133387469?spm1001.2014.3001.5501文章浏览阅读323次&#xff0c;点赞4次&#xff0c;收藏2次。搞3D几何内核算法研究&#xff0c;必须学习NURBS样条曲线…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-25使用块的网络VGG

25使用块的网络VGG import torch from torch import nn import liliPytorch as lp import matplotlib.pyplot as plt# 定义VGG块 # num_convs: 卷积层的数量 # in_channels: 输入通道的数量 # out_channels: 输出通道的数量 def vgg_block(num_convs, in_channels, out_channel…

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 &#x1f4da; 前言 &#x1f4d1;摘要 &#x1f4d1;系统流程 &#x1f4da; 系统架构设计 &#x1f4da; 数据库设计 &#x1f4da; 系统功能的具体实现 &#x1f4ac; 系统登录注册 系统登录 登录界面 用户添加 &#x1f4ac; 抗疫列表展示模块 区域信息管理 …

Codeforces Round 954 (Div. 3) A B C D

A. X Axis time limit per test: 2 second memory limit per test: 256 megabytes input: standard input output: standard output You are given three points with integer coordinates x 1 x_1 x1​, x 2 x_2 x2​, and x 3 x_3 x3​ on the X X X axis ( 1 ≤ x i ≤ …

MyBatis 源码分析-- SQL请求执行流程( Mapper 接口方法的执行的过程)

前言 前面我们从源码层面梳理了 SqlSessionFactory、SqlSession 的创建过程及 Mapper 获取过程&#xff0c;本篇我们继续分析一下 Mapper 接口方法的执行的过程&#xff0c;也就是 SQL 的执行流程。 Mybatis 相关知识传送门 初识 MyBatis 【MyBatis 核心概念】 MyBatis 源码…

Anaconda3 常用命令及配置

1、Anaconda是什么? 2、conda常用命令 系统环境&#xff1a;windows10 Anaconda版本&#xff1a;Anaconda3-2024.02-1-Windows-x86_64 2.1、虚拟环境管理 1、查看虚拟环境 conda env list conda info -e 2、创建虚拟环境 # 创建名为 pyenv 的虚拟环境 conda create --na…

计算机软件著作权申请流程及费用_快速登记_经验分享收藏级教程

最近需要申请计算机软件著作权&#xff0c;申请流程走了一遍&#xff0c;整理了分享给大家。软件著作权申请流程及费用&#xff0c;软著快速登记、软著材料及问题解答FAQ&#xff0c;阿里云百科阿里云计算机软件著作权登记20天下证&#xff0c;那么如何申请阿里云软件著作权登记…

MTK7628+MT7612 加PA定频数据

1、硬件型号TR726A5G121-DPA PC9.02.0017。如下所示&#xff1a; 2、WIFI5.8 AC模式 42&#xff08;5120MHz&#xff09;信道&#xff0c;80带宽 3、WIFI5.8 AC模式 38&#xff08;5190MHz&#xff09;信道&#xff0c;40带宽 4、WIFI5.8 AC模式 36&#xff08;5180 MHz&…

股票分析学习

库&#xff1a; pandas to_datetime:它可以处理各种格式的日期和时间数据&#xff0c;并将其统一转换为 Pandas 可以理解和操作的内部日期时间格式。 matplotlib.pyplot 用户可以轻松地创建各种静态、动态、交互式和 3D 图形。 1. 绘制线图&#xff08;plot()&#xff09; …

FEP耐酸碱耐高温可定制滴瓶60ml透明四氟瓶F46滴加瓶

FEP滴瓶&#xff1a;又叫聚全氟乙丙烯滴瓶&#xff0c;特氟龙滴瓶。广泛应用于痕量分析、超痕量分析、ICP-MS分析、同位素分析等实验。 主要特性如下&#xff1a; 1.耐高低温&#xff1a;使用温度可达-200&#xff5e;205℃&#xff1b; 2.材质为高纯实验级进口TeflonFEP加工…

虚拟机链接不上usb

传输速度慢 记得换一个支持usb3.0的口和支持usb3.0的线

C语言从入门到进阶(15万字总结)

前言&#xff1a; 《C语言从入门到进阶》这本书可是作者呕心沥血之作&#xff0c;建议零售价1元&#xff0c;当然这里开个玩笑。 本篇博客可是作者之前写的所有C语言笔记博客的集结&#xff0c;本篇博客不止有知识点&#xff0c;还有一部分代码练习。 有人可能会问&#xff…

运维技术栈总结

文章目录 Linux CommandBasecd/lschmod/chown/chgrpvi/vimscptarsudf Installrpmyumdeb/apt Filtertailgrepawkfindnetstatechotelnetwhereistouch/mkdirgzip/rar/tar Statistics Linux MonitorCPUtophtopsar Memoryfreevmstat I/Oiostatpidstatiotop Networknetstatiftoptcpdu…

认识Retrieval Augmented Generation(RAG)

什么是RAG&#xff1f; Retrieval-Augmented Generation (RAG) 是一种结合信息检索和生成式AI技术的框架。它通过从外部数据源检索信息&#xff0c;增强语言模型&#xff08;如GPT-3&#xff09;的生成能力&#xff0c;从而提供更加准确和相关的回答。 RAG的组成部分 信息检…

用腾讯云语音合成(TTS)批量生成英语绘本的朗读音频

孩子进行英语启蒙&#xff0c;需要看很多英语绘本&#xff0c;而且要听配套的音频来练听力。但有些英语绘本是没有对应音频的&#xff0c;下面简单几步&#xff0c;就可以将任意英语绘本制作出对应的英语朗读音频。 先到电子书资源网站搜索这个绘本名称&#xff0c;如果有电子…

三.iOS核心动画 - 关于图层几何(frame,bounds,transform,position)

引言 关于UIView的布局有一个经常被问到的问题&#xff0c;frame和bounds有什么区别&#xff0c;同样CALayer也有frame和bounds这两个属性&#xff0c;还有一个与UIView的center对应的position属性&#xff0c;本篇博客我们就来详细的探讨一下图层中的frame和bounds到底有什么…

Python酷库之旅-第三方库openpyxl(07)

目录 一、 openpyxl库的由来 1、背景 2、起源 3、发展 4、特点 4-1、支持.xlsx格式 4-2、读写Excel文件 4-3、操作单元格 4-4、创建和修改工作表 4-5、样式设置 4-6、图表和公式 4-7、支持数字和日期格式 二、openpyxl库的优缺点 1、优点 1-1、支持现代Excel格式…

十大经典排序算法——选择排序和冒泡排序

一、选择排序 1.基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据全部排完。 2.直接选择排序 (1) 在元素集合arr[i] — arr[n - 1]中选择关键妈的最大&#xff08;小…