1.环境配置安装
Python+Anaconda+PyCharm
1.1Anaconda
是一个开源的Python发行版本。其包含了720多个数据科学相关的开源包,在数据可视化、机器学习、深度学习等多方面都有涉及。不仅可以做数据分析,甚至可以用在大数据和人工智能领域。因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和 Python)。
Anaconda通过管理工具包、开发环境、Python版本,大大简化了工作流程。不仅可以方便地安装、更新、卸载工具包,而且安装时能自动安装相应的依赖包,同时还能使用不同的虚拟环境隔离不同要求的项目。
也就是说,Anaconda自带很多Python包,有了Anaconda就不用再对这些包进行安装了。而且在PyCharm中可以查看这些包,如果需要的包在系统中不存在,也可以很省心的进行包的在线下载,省事省力省心~~
Anaconda介绍、安装及使用教程 - 简书 (jianshu.com)
1.2为什么要用虚拟环境
在实际项目开发中,我们通常会根据自己的需求去下载各种相应的框架库,如Scrapy、Beautiful Soup等,但是可能每个项目使用的框架库并不一样,或使用框架的版本不一样,这样需要我们根据需求不断的更新或卸载相应的库。直接怼我们的Python环境操作会让我们的开发环境和项目造成很多不必要的麻烦,管理也相当混乱。如一下场景:
场景1:项目A需要某个框架1.0版本,项目B需要这个库的2.0版本。如果没有安装虚拟环境,那么当你使用这两个项目时,你就需要 来回 的卸载安装了,这样很容易就给你的项目带来莫名的错误;
这几个在官网下载就行了,按照网上的教程。自己在下载的过程中 Anaconda下载有些问题。下载之后用不起来。需要更新。
中间等待时间比较长
Anaconda打开之后无法显示界面,再打开显示There is an instance of anaconda navigator already running
1.3创建虚拟环境
图形界面:记住路径 C:\ProgramData\Anaconda3\envs
命令行使用 cmd
1、conda -V检验是否安装以及当前conda的版本。
2、conda常用的命令。
1)conda list 查看安装了哪些包。
2)conda env list 或 conda info -e 查看当前存在哪些虚拟环境
3)conda update conda 检查更新当前conda
3、python --version可以检查当前python的版本。
4、删除虚拟环境。 使用命令conda remove -n your_env_name(虚拟环境名称) --all, 即可删除。
5、删除环境中的某个包。使用命令conda remove --name your_env_name package_name 即可。
1.4导包
1.使用文件批量导包
python 在虚拟环境中安装项目依赖requirements.txt
创建环境 conda create -n Python3.6 python=3.6
查看环境 conda env list
1)激活环境,即进入环境 activate Python3.6
2)进入requirements.txt文件所在目录 (DataAnalysis)C:\Users\86137>cdC:\Users\86137\Desktop\Pythonlearn\requirements\DataAnalysis
3)安装 (DataAnalysis) C:\Users\86137\Desktop\Pythonlearn\requirements\DataAnalysis>pip install -r requirements.txt
4)检验pip list
如果报错可以自己检查那个没装上,自己装。
项目导出requirements.txt
pip freeze > requirements.txt
2.在Anaconda里一个个自己安装,注意版本
意外:
Ta-Lib库安装pip失效,可以在pycharm里安装
Python Extension Packages for Windows - Christoph Gohlke (uci.edu)
1.5PyCharm切换管理虚拟环境
Pycharm使用Anaconda管理虚拟环境Python版本
2.Jupyter上手
2.1在pycharm里就可以新建文件
2.2快捷键和cell操作
在网页上有用
编辑模式命令模式
2.3 Jupyter支持markdown
3.Numpy
数组矩阵操作
Numerical(数值计算)+ Python
核心数据结构: ndarray
n-任意
d-数组
array-数组
4.1 ndarray 和 list 效率对比
import numpy as np
import time
import random
py_list=[]
for i in range(10000000):
py_list.append(random.Random())
ndarray_list=np.array(py_list)
# 原生求和
t1=time.time()
a=sum(py_list)
t2=time.time()
d1=t2-t1
# ndarray 求和
t3=time.time()
b=np.sum(ndarray_list)
t4=time.time()
d2=t4-t3
print(d1)
print(d2)
4.2 Numpy的优势
1.存储风格:
ndarray:只能存储相同地方数据类型,这样就可以连续存储
list:可以存储不同类型的数据
2.并行化运算
ndarray支持向量化运算
3.底层语言
底层是c语言实现
4.3ndarray常用属性
shape 形状
返回一个元组,元组元素个数对应维度数,每个数代表对应维度上的元素个数
score.shape #(8,5)8行5列
ndim 维度
score.ndim # 2
size 元素个数
score.size # 40
dtype 类型
score.dtype # 返回元素类型
score.itemsize # 返回元素所在字节大小
创建指定类型
# 创建数组的时候指定类型
np.array([1.1, 2.2, 3.3], dtype="float32")
4.4 基本操作
ndarray.方法()
np.函数名()
4.4.1 生成数组
01数组
np.zeros([3,4])# 三行四列
np.ones((2,3))
从现有数组生成
score
data1 = np.array(score) #深拷贝
data2 = np.asarray(score) #浅拷贝,,原数组改变也随之改变
data3 = np.copy(score) #深拷贝
生成固定范围的数组
np.linspace(0,10,100) [0,10]之间等距的一百的元素
np.arrange(a,b,c) [a,b) 步长为c
生成随机数组
np.random 模块
均匀分布 落在每个点可能性相同
data4=np.random.uniform(-1,1,100) #前两个是范围,后一个是尺寸szie
print(data4)
正态分布
两个参数,均值(对称轴)和标准差(集中度,标准差越小集中度越大)
标准正态分布 均值为0 标准差为1
data5= np.random.normal(1.75,1,100000) # 参数顺序 均值,标准差,数量
import matplotlib.pyplot as plt
plt.hist(data5,1000)
plt.show()
4.4.2 索引切片与形状修改
a1 = np.array([ [[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
a1[1, 0, 2] = 100000
a1
形状修改:
ndarray.reshape()只是修改形状,返回新的ndarray
ndarray.resize() 没有返回值,对原始的ndarray进行修改
stock_change.reshape((10, 8))
stock_change.resize((10, 8))
stock_change.T
上两个效果一样
ndarray.T转置,行列转换
ndarray**序列化到本地**
ndarray.tostring() d得到base类型
stock_change.tostring()
数组去重:
np.unique(数组名)
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
np.unique(temp)
# array([1, 2, 3, 4, 5, 6])
4.5 ndarray运算
4.5.1逻辑运算
# 逻辑判断, 如果涨跌幅大于0.5就标记为True 否则为False
stock_change > 0.5
array([[ True, False, False, False, False, True, False, False, True,
False],
[False, False, False, True, True, False, True, True, False,
False],
[False, False, True, False, False, True, False, False, False,
False],
[False, False, True, False, False, False, False, True, False,
False],
[False, False, False, True, True, False, False, False, False,
True],
[False, False, False, False, True, False, False, False, False,
False],
[False, True, False, True, True, False, True, False, False,
True],
[False, True, False, False, False, False, False, False, True,
False]])
布尔索引
stock_change[stock_change > 0.5] = 1.1
通判函数
np.all(布尔值)
全是true返回true
np.any(布尔值)
全是false才是false
# 判断stock_change[0:2, 0:5]是否全是上涨的
stock_change[0:2, 0:5] > 0
np.all(stock_change[0:2, 0:5] > 0)
>>>False
np.where(三元运算符)
np.where(布尔值,true位置的值,false位置的值)
复合逻辑
# 判断前四个股票前四天的涨跌幅 大于0.5并且小于1的,换为1,否则为0
# 判断前四个股票前四天的涨跌幅 大于0.5或者小于-0.5的,换为1,否则为0
# (temp > 0.5) and (temp < 1)
np.logical_and(temp > 0.5, temp < 1)
np.logical_or(temp > 0.5,temp < 1)
4.5.1逻辑运算
统计指标函数
max,min,mean,median,var,std
指定轴
根据形状判断 shape(4,4)索引 0 ,1 ,2
temp.max(axis=0),按列,第一维度
temp.max(axis=1)按行,第二维度
返回最大值最小值索引
np.argmax()
np.argmin(temp,axis=)
4.5.2数组运算
数组与数的运算
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
arr / 10
# array([[0.1, 0.2, 0.3, 0.2, 0.1, 0.4],
# [0.5, 0.6, 0.1, 0.2, 0.3, 0.1]])
数组与数组运算
广播机制
如果满足以下条件之一,那么数组被称为可广播的。
- 数组拥有相同形状。数组拥有相同的维数,且某一个或多个维度长度为 1 。数组拥有极少的维度,可以在其前面追加长度为 1 的维度,使上述条件成立
矩阵运算
二维数组进行存储
两种方法:
ndarray的二维数组
matrix
# ndarray存储矩阵
data = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
# matrix存储矩阵
data_mat = np.mat([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
type(data_mat)
# numpy.matrixlib.defmatrix.matrix
矩阵乘法 np.dot np.matmul
形状:(m,n)*(n,l)=(m,l)
行向量x列向量=数
列向量x行向量=行向量
# 用np.array存储
weights_mat = np.mat([[0.3], [0.7]])
np.matmul(data, weights)
np.dot(data, weights)
data@weights
# 结果
array([[84.2],
[80.6],
[80.1],
[90. ],
[83.2],
[87.6],
[79.4],
[93.4]])
# matrix存储矩阵
data_mat * weights_mat
matrix([[84.2],
[80.6],
[80.1],
[90. ],
[83.2],
[87.6],
[79.4],
[93.4]])
4.6 数组合并和分割
# -*- coding: utf-8 -*-
import numpy as np
arr1 = np.array([[[1, 2], [3, 4]],[[5, 6], [7, 8]]])
arr2 = np.array([[[9, 10], [11, 12]],[[13, 14], [15, 16]]])
"""级联拼接"""
arr = np.concatenate((arr1, arr2)) #默认在第0维上进行数组的连接
arr_1 = np.concatenate((arr1, arr2), axis=1) #axis指定拼接的维度,axis=1表示在第1维上对数组进行拼接
arr_2 = np.concatenate((arr1, arr2), axis=2) #axis指定拼接的维度,axis=2表示在第2维上对数组进行拼接
"""堆栈拼接"""
arr_3 = np.stack((arr1, arr2)) #默认在第0维上进行数组的连接
arr_4 = np.stack((arr1, arr2),axis=1) #在第1维上进行数组的连接
arr_5 = np.stack((arr1, arr2),axis=2) #在第2维上进行数组的连接
arr_6 = np.stack((arr1, arr2),axis=3) #在第3维上进行数组的连接
"""其他方法"""
arr_7 = np.hstack((arr1, arr2)) #按行堆叠,相当于级联axis=1的方法
arr_8 = np.vstack((arr1, arr2)) #按列堆叠,相当于级联axis=0的方法
arr_9 = np.dstack((arr1, arr2)) #按深度堆叠,相当于级联axis=2的方法
print("原始数组:")
print(arr1)
print("数组类型:",arr1.shape)
print()
print(arr2)
print("数组类型:",arr2.shape)
print("--------------------------------")
print()
print("使用concatenate函数连接")
print()
print("默认在第0维上进行数组的连接")
print(arr)
print("数组类型:",arr.shape)
print("--------------------------------")
print()
print("--------------------------------")
print()
print("在第1维上进行数组的连接")
print(arr_1)
print("数组类型:",arr_1.shape)
print("--------------------------------")
print()
print("在第2维上进行数组的连接")
print(arr_2)
print("数组类型:",arr_2.shape)
print("--------------------------------")
print()
print("使用stack函数连接")
print()
print("默认在第0维上进行数组的连接")
print(arr_3)
print("数组类型:",arr_3.shape)
print("--------------------------------")
print()
print("在第1维上进行数组的连接")
print(arr_4)
print("数组类型:",arr_4.shape)
print("--------------------------------")
print()
print("在第2维上进行数组的连接")
print(arr_5)
print("数组类型:",arr_5.shape)
print("--------------------------------")
print()
print("在第3维上进行数组的连接")
print(arr_6)
print("数组类型:",arr_6.shape)
print("--------------------------------")
print()
print("按行堆叠")
print(arr_7)
print("数组类型:",arr_7.shape)
print("--------------------------------")
print()
print("按列堆叠")
print(arr_8)
print("数组类型:",arr_8.shape)
print("--------------------------------")
print()
print("按高(深)堆叠")
print(arr_9)
print("数组类型:",arr_9.shape)
print("--------------------------------")
print()
原始数组:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
数组类型: (2, 2, 2)
[[[ 9 10]
[11 12]]
[[13 14]
[15 16]]]
数组类型: (2, 2, 2)
--------------------------------
使用concatenate函数连接
默认在第0维上进行数组的连接
[[[ 1 2]
[ 3 4]]
[[ 5 6]
[ 7 8]]
[[ 9 10]
[11 12]]
[[13 14]
[15 16]]]
数组类型: (4, 2, 2)
--------------------------------
--------------------------------
在第1维上进行数组的连接
[[[ 1 2]
[ 3 4]
[ 9 10]
[11 12]]
[[ 5 6]
[ 7 8]
[13 14]
[15 16]]]
数组类型: (2, 4, 2)
--------------------------------
在第2维上进行数组的连接
[[[ 1 2 9 10]
[ 3 4 11 12]]
[[ 5 6 13 14]
[ 7 8 15 16]]]
数组类型: (2, 2, 4)
--------------------------------
使用stack函数连接
默认在第0维上进行数组的连接
[[[[ 1 2]
[ 3 4]]
[[ 5 6]
[ 7 8]]]
[[[ 9 10]
[11 12]]
[[13 14]
[15 16]]]]
数组类型: (2, 2, 2, 2)
--------------------------------
在第1维上进行数组的连接
[[[[ 1 2]
[ 3 4]]
[[ 9 10]
[11 12]]]
[[[ 5 6]
[ 7 8]]
[[13 14]
[15 16]]]]
数组类型: (2, 2, 2, 2)
--------------------------------
在第2维上进行数组的连接
[[[[ 1 2]
[ 9 10]]
[[ 3 4]
[11 12]]]
[[[ 5 6]
[13 14]]
[[ 7 8]
[15 16]]]]
数组类型: (2, 2, 2, 2)
--------------------------------
在第3维上进行数组的连接
[[[[ 1 9]
[ 2 10]]
[[ 3 11]
[ 4 12]]]
[[[ 5 13]
[ 6 14]]
[[ 7 15]
[ 8 16]]]]
数组类型: (2, 2, 2, 2)
--------------------------------
按行堆叠
[[[ 1 2]
[ 3 4]
[ 9 10]
[11 12]]
[[ 5 6]
[ 7 8]
[13 14]
[15 16]]]
数组类型: (2, 4, 2)
--------------------------------
按列堆叠
[[[ 1 2]
[ 3 4]]
[[ 5 6]
[ 7 8]]
[[ 9 10]
[11 12]]
[[13 14]
[15 16]]]
数组类型: (4, 2, 2)
--------------------------------
按高(深)堆叠
[[[ 1 2 9 10]
[ 3 4 11 12]]
[[ 5 6 13 14]
[ 7 8 15 16]]]
数组类型: (2, 2, 4)
--------------------------------
Process finished with exit code 0
4.7 IO操作
Numpy读取数据
参数说明,第一个参数是路径,第二是数据分隔符
data = np.genfromtxt(“test.csv”, delimiter=",")
字符串会读取成nan,
数据读取的缺失值处理:
直接删掉,数据比较大的
数据较少 插补法,用行货列的均值代表
def fill_nan_by_column_mean(t):
for i in range(t.shape[1]):
# 计算nan的个数
nan_num = np.count_nonzero(t[:, i][t[:, i] != t[:, i]])
if nan_num > 0:
now_col = t[:, i]
# 求和
now_col_not_nan = now_col[np.isnan(now_col) == False].sum()
# 和/个数
now_col_mean = now_col_not_nan / (t.shape[0] - nan_num)
# 赋值给now_col
now_col[np.isnan(now_col)] = now_col_mean
# 赋值给t,即更新t的当前列
t[:, i] = now_col
return t
5.PIL 图像处理
(1条消息) PIL 库的使用入门_门下平章的博客-CSDN博客
5.1读取查看文件
# 文件路径
DATADIR = '/home/aistudio/work/palm/PALM-Training400/PALM-Training400'
# 文件名
file1 = 'N0012.jpg'
# 读取文件
img1 = Image.open(os.path.join(DATADIR,file1))
print(img1)
# <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=2124x2056 at 0x7FCD3988BFD0>
6.os库 文件操作
DATADIR = '/home/aistudio/work/palm/PALM-Training400/PALM-Training400'
file1 = 'N0012.jpg'
# 拼接路径
os.path.join(DATADIR,file1)
TRAINDIR = '/home/aistudio/work/insects/train'
files=os.path.join(TRAINDIR,'annotations','xmls')
# files /home/aistudio/work/insects/train/annotations/xmls
filenames = os.lisdir(os.path.join(datadir,'annotations','xmls'))
# 文件下的文件名,作为列表返回
['59.xml', '721.xml', '2058.xml', '376.xml', '1041.xml', '1737.xml', '1953.xml', '1973.xml', '110.xml', '864.xml', '889.xml', '1219.xml', '1103.xml', '732.xml', '623.xml', '1650.xml', '1919.xml', '1751.xml', '767.xml', '1721.xml', '1636.xml', '488.xml', '271.xml', '372.xml', '1638.xml', '404.xml', '295.xml', '1685.xml', '2093.xml', '1610.xml', '396.xml', '68.xml', '679.xml', '1727.xml', '1981.xml', '1834.xml', '1151.xml', '1634.xml', '412.xml', '661.xml', '2015.xml', '1110.xml', '66.xml', '573.xml', '451.xml', '2032.xml', '168.xml', '700.xml', '2220.xml', '1047.xml', '2216.xml', '1891.xml', '874.xml', '2060.xml', '2165.xml', '1615.xml', '892.xml', '1149.xml', '1923.xml', '1215.xml',]
7.random 随机库
# 打乱列表原有数据顺序
random.shuffle(filenames)
8.opencv
8.0 处理图片
# cv2.imread返回类型是array
img = cv2.imread(filepath)
# 修改尺寸 对array进行操作
img = cv2.resize(img,(224,224))
8.1摄像头操作
8.1.1打开摄像头
# -*- coding utf-8 -*-
'''
author :sjk
time :2021.08.15
'''
import cv2
import numpy as np
def video_demo():
capture = cv2.VideoCapture(0) # 0为电脑内置摄像头
while (True):
ret, frame = capture.read() # 摄像头读取,ret为是否成功打开摄像头,true,false。 frame为视频的每一帧图像
frame = cv2.flip(frame, 1) # 摄像头是和人对立的,将图像左右调换回来正常显示。
cv2.imshow("video", frame)
# cv2.waitKey()是一个键盘绑定函数。它的时间量度是毫秒ms。函数会等待(n)里面的n毫秒,看是否有键盘输入。
# 若有键盘输入,则返回按键的ASCII值。没有键盘输入,则返回-1.一般设置为0,他将无线等待键盘的输入。
c = cv2.waitKey(50)
# ESC键
if c == 27:
break
video_demo()
# cv2.destroyAllWindows() 用来删除窗口的,()里不指定任何参数,则删除所有窗口,删除特定的窗口,往()输入特定的窗口值。
cv2.destroyAllWindows()
8.1.2摄像头截图保存
# -*- coding utf-8 -*-
'''
author :sjk
time :2021.08.15
'''
import cv2
# , cv2.CAP_DSHOW
cap = cv2.VideoCapture(0) # 打开摄像头
while (1):
# get a frame
ret, frame = cap.read()
frame = cv2.flip(frame, 1) # 摄像头是和人对立的,将图像左右调换回来正常显示
# show a frame
cv2.imshow("capture", frame) # 生成摄像头窗口
if cv2.waitKey(1) & 0xFF == ord('q'): # 如果按下q 就截图保存并退出
cv2.imwrite("test.png", frame) # 保存路径
break
cap.release()
cv2.destroyAllWindows()
8.1.3摄像头截图保存
# -*- coding utf-8 -*-
'''
author :sjk
time :2021.08.15
'''
import cv2
def video_demo():
print('开始')
# , cv2.CAP_DSHOW
cap = cv2.VideoCapture(0) # 电脑自身摄像头
i = 0 # 定时装置初始值
photoname = 1 # 文件名序号初始值
while True:
i = i + 1
reg, frame = cap.read()
frame = cv2.flip(frame, 1) # 图片左右调换
cv2.imshow('window', frame)
if i == 50: # 定时装置,定时截屏,可以修改。
filename = str(photoname) + '.png' # filename为图像名字,将photoname作为编号命名保存的截图
cv2.imwrite('C:\\Users\\86137\\Desktop\\Pythonlearn\\pythonProject\\result\picture' + '\\' + filename, frame) # 截图 前面为放在桌面的路径 frame为此时的图像
print(filename + '保存成功') # 打印保存成功
i = 0 # 清零
photoname = photoname + 1
if photoname >= 20: # 最多截图20张 然后退出(如果调用photoname = 1 不用break为不断覆盖图片)
# photoname = 1
break
if cv2.waitKey(1) & 0xff == ord('q'):
break
# 释放资源
cap.release()
video_demo()
cv2.destroyAllWindows()
8.1.4摄像头截图保存
# -*- coding utf-8 -*-
'''
author :sjk
time :2021.08.15
'''
import cv2
# Create a VideoCapture object and read from input file
# If the input is the camera, pass 0 instead of the video file name
cap = cv2.VideoCapture(0) # 读取视频
# 判断视频是否读取成功
if (cap.isOpened() == False):
print("Error opening video stream or file")
# 获取帧
while (cap.isOpened()):
# Capture frame-by-frame
ret, frame = cap.read()
if ret == True:
# 在每一帧上画矩形,frame帧,(四个坐标参数),(颜色),宽度
cv2.rectangle(frame, (int(200), int(300)), (int(400), int(500)), (255, 255, 255), 4)
# 显示视频
cv2.imshow('Frame', frame)
# 刷新视频
cv2.waitKey(10)
# 按q退出
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# Break the loop
else:
break
8.2锚框及其标注
标注:
import cv2
fname = './data_set/face_detection/WIDER_test/images/1--Handshaking/1_Handshaking_Handshaking_1_9.jpg'
img = cv2.imread(fname)
# 画矩形框 距离靠左靠上的位置
pt1 = (651, 460) #左边,上边 #数1 , 数2
pt2 = (180+651, 462+227) #右边,下边 #数1+数3,数2+数4
cv2.rectangle(img, pt1, pt2, (0, 255, 0), 2)
a = 'people' #类别名称
b = 0.596 #置信度
font = cv2.FONT_HERSHEY_SIMPLEX # 定义字体
imgzi = cv2.putText(img, '{} {:.3f}'.format(a,b), (651, 460-15), font, 1, (0, 255, 255), 4)
# 图像, 文字内容, 坐标(右上角坐标),字体, 大小, 颜色, 字体厚度
cv2.imwrite('22.jpg', img)
锚框:
import cv2
# Create a VideoCapture object and read from input file
# If the input is the camera, pass 0 instead of the video file name
cap = cv2.VideoCapture('1.avi') #读取视频
# 判断视频是否读取成功
if (cap.isOpened()== False):
print("Error opening video stream or file")
#获取帧
while(cap.isOpened()):
# Capture frame-by-frame
ret, frame = cap.read()
if ret == True:
# 在每一帧上画矩形,frame帧,(四个坐标参数,分别为左,上,右下),(颜色),宽度
cv2.rectangle(frame, (int(200), int(300)), (int(400), int(500)), (255, 255, 255), 4)
# 显示视频
cv2.imshow('Frame',frame)
# 刷新视频
cv2.waitKey(10)
# 按q退出
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# Break the loop
else:
break
8.3 视频操作
1.视频读取,展示
import cv2
cap = cv2.VideoCapture("../opencv/test/test.mp4")
while 1:
ret, frame = cap.read()
cv2.imshow("capture", frame)
"""
cv2.WINDOW_NORMAL 和 0 是一样的,设置成normal之后,
拖动鼠标是可以改变窗口的大小的,不设置是改变不了窗口的大小的。
"""
cv2.namedWindow('capture', cv2.WINDOW_NORMAL)
# 设置窗口大小,但不改变图片本身大小
cv2.resizeWindow("capture", int(img_width*0.5),int(img_high*0.5))
# 在显示帧时,选择适当的cv2.waitKey()时间,
# 如果该值太小,视频会非常快,如果它太大,视频会很慢(这可以用来慢动作显示视频)。
# 正常情况下,25毫秒即可。
if cv2.waitKey(25) == 27:
print("exit")
break
cap.release()
cv2.destroyAllWindows()
2.获取视频相关属性
参数 propld 功能
cv2.CAP_PROP_POS_MSEC 0 视频文件的当前位置(以毫秒为单位)或视频捕获时间戳
cv2.CAP_PROP_POS_FRAMES 1 基于0的索引将被解码/捕获下一帧
cv2.CAP_PROP_POS_AVI_RATIO 2 视频文件的相对位置:0 - 视频的开始,1 - 视频的结束
cv2.CAP_PROP_FRAME_WIDTH 3 帧的宽度
cv2.CAP_PROP_FRAME_HEIGHT 4 帧的高度
cv2.CAP_PROP_FPS 5 帧速
cv2.CAP_PROP_FOURCC 6 4个字符表示的视频编码器格式
cv2.CAP_PROP_FRAME_COUNT 7 帧数
cv2.CAP_PROP_FORMAT 8 byretrieve()返回的Mat对象的格式
cv2.CAP_PROP_MODE 9 指示当前捕获模式的后端特定值
cv2.CAP_PROP_BRIGHTNESS 10 图像的亮度(仅适用于相机)
cv2.CAP_PROP_CONTRAST 11 图像对比度(仅适用于相机)
cv2.CAP_PROP_SATURATION 12 图像的饱和度(仅适用于相机)
cv2.CAP_PROP_HUE 13 图像的色相(仅适用于相机)
cv2.CAP_PROP_GAIN 14 图像的增益(仅适用于相机)
cv2.CAP_PROP_EXPOSURE 15 曝光(仅适用于相机)
cv2.CAP_PROP_CONVERT_RGB 16 表示图像是否应转换为RGB的布尔标志
cv2.CAP_PROP_WHITE_BALANCE 17 目前不支持
cv2.CAP_PROP_RECTIFICATION 18 立体摄像机的整流标志
import cv2
import numpy as np
cap = cv2.VideoCapture("../opencv/test/test.mp4")
# 原视频的宽高
img_high = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
img_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
# 原视频 编解码器四字符代码
fourcc=cap.get(cv2.CAP_PROP_FOURCC)
# 原视频帧数
fps=cap.get(cv2.CAP_PROP_FPS)
'''
创建一个VideoWriter对象,指定输出文件名(例如:output.avi)。
之后指定FourCC代码(FourCC是用于指定视频编解码器的4字节代码。可用代码列表)。
接下来传递每秒帧数(fps)和帧大小。
最后一个是isColor标志,如果它为True,编码器编码成彩色帧,否则编码成灰度框帧。
'''
out=cv2.VideoWriter('out.mp4',int(fourcc),int(fps),(int(img_width),int(img_high)))
# 获取尺寸
print(img_high)
print(img_width)
3.保存视频
[【Python+OpenCV入门学习】四、视频的读取、显示、保存](https://blog.csdn.net/qq_18995069/article/details/82772944?ops_request_misc=&request_id=&biz_id=102&utm_term=python opencv读取视频&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-82772944.pc_search_result_control_group&spm=1018.2226.3001.4187)
# -*- coding utf-8 -*-
"""
author :sjk
time :2021.09.01
"""
import cv2
import numpy as np
"""
Opencv是一帧一帧读取,处理完一帧就处理下一帧,中间是没有时间间隔的。首先要
cvGetCaptureProperty(capture, CV_CAP_PROP_FPS ); //读取视频的帧率
读取到帧率,再
int vfps = 1000 / fps; //计算每帧播放的时间
这样,如果你sleep(vfps)秒,大概就可以按帧率播放,但还是有点偏差
"""
cap = cv2.VideoCapture("../opencv/test/test.mp4")
img_high = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
img_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
# 编解码器,不同视频格式不同,这个是MP4的
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V')
# 原视频帧数
fps=cap.get(cv2.CAP_PROP_FPS)
'''
创建一个VideoWriter对象,指定输出文件名(例如:output.avi)。
之后指定FourCC代码(FourCC是用于指定视频编解码器的4字节代码。可用代码列表)。
接下来传递每秒帧数(fps)和帧大小。
最后一个是isColor标志,如果它为True,编码器编码成彩色帧,否则编码成灰度框帧。
'''
out=cv2.VideoWriter('out.mp4',fourcc,int(fps),(int(img_width),int(img_high)))
# 获取尺寸
print(img_high)
print(img_width)
while 1:
ret, frame = cap.read()
"""
cv2.WINDOW_NORMAL 和 0 是一样的,设置成normal之后,
拖动鼠标是可以改变窗口的大小的,不设置是改变不了窗口的大小的。
"""
cv2.namedWindow('capture', cv2.WINDOW_NORMAL)
cv2.resizeWindow("capture", int(img_width*0.5),int(img_high*0.5)) # 设置窗口大小
cv2.rectangle(frame, (int(400), int(400)), (int(300), int(300)), (0, 0, 255), 4)
cv2.imshow("capture", frame)
out.write(frame)
# esc 退出
'''
在显示帧时,选择适当的cv2.waitKey()时间,如果该值太小,视频会非常快,如果它太大,视频会很慢(这可以用来慢动作显示视频)。 正常情况下,25毫秒即可。
'''
if cv2.waitKey(25) == 27:
print("exit")
break
cap.release()
cv2.destroyAllWindows()
3.1 了解类VideoWriter
对于视频的保存,OpenCV提供了接口VideoWriter。要想编程实现保存视频,需要熟悉一下该类的构造函数和成员函数。
<VideoWriter object> = cv.VideoWriter( filename, fourcc, fps, frameSize[, isColor] )
参数:
filename:给要保存的视频起个名字
fourcc:指定视频编解码器的4字节代码
fps:帧率
frameSize:帧大小
isColor:如果为true,则视频为彩色,否则为灰度视频,默认为true
在此再介绍一下fourcc。它是用于压缩帧的4字符编解码器代码。如VideoWriter :: fourcc(‘P’,‘I’,‘M’,‘1’)是MPEG-1编解码器,VideoWriter :: fourcc(‘M’,‘J’,‘P’,'G ')是一个运动jpeg编解码器等。要想详细了解fourcc,可以百度搜索进行详细的学习。get()、set()、isOpened()、release()等和VideoCapture的成员函数类似,不坐赘述。介绍几个新的成员函数:
retval = cv2.VideoWriter_fourcc( c1, c2, c3, c4 )
功能:将4字符串接为fourcc代码。
None = cv.VideoWriter.write( image )
功能:将帧图像保存为视频文件。
3.2 编程实现保存视频
很多时候我们捕获视频,并对其进行帧处理,希望保存处理后的视频。要想保存视频,首先当然是进行捕获视频,代码和前面一样,本次实现保存相机中捕获的视频。将视频保存,思路是首先创建VideoWriter类对象,需要指定一些参数,在windows下fourcc取值为DIVX,帧率一般给20,帧大小一般给640*480,创建对象后,采用write()函数保存帧,保存完后记得关闭VideoWriter类对象。所以代码如下:
import cv2
cap = cv2.VideoCapture(0)#打开相机
#创建VideoWriter类对象
fourcc = cv2.VideoWriter_fourcc(*’XVID’)
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(True):
ret,frame = cap.read()#捕获一帧图像
out.write(frame)#保存帧
cv2.imshow('frame',frame)#显示帧
#判断按键,如果按键为q,退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()#关闭相机
out.release()
cv2.destroyAllWindows()#关闭窗口
9.cuda库安装,加速本地计算
装完就可以试试指令 nvcc -V,不一定需要配置环境变量
10.apex库
一定要先安装cuda,不然会报错😂
11.wget安装
下载网络资源的指令库
12.xml文件读取 xml库
Python xml.etree.ElementTree解析XML文件_
Python3 XML 解析 | 菜鸟教程 (runoob.com)
13.PyAutoGUI
获取处理,电脑屏幕的脚本库。
安装,完成后使用可能会报错
AttributeError: module 'pyscreeze' has no attribute 'locateOnWindow'
用pip 命令行命令:pip uninstall PyautoGUI
然后安装指定版本的pip install PyAutoGUI==0.9.45
pip uninstall PyScreeze
pip install PyScreeze==0.1.22
pip list
Package Version
----------- -------
install 1.3.4
MouseInfo 0.1.3
Pillow 8.3.1
pip 21.1.3
PyAutoGUI 0.9.45
PyGetWindow 0.0.9
PyMsgBox 1.0.7
pyperclip 1.8.2
PyRect 0.1.4
PyScreeze 0.1.22
PyTweening 1.0.3
setuptools 57.4.0
14.imgaug数据增强库
15 常见Linux命令
1.notebook中用shell执行系统命令
在notebook中:感叹号!用于执行来自操作系统的命令
Shell是一种与计算机进行文本交互的方式。
shell是外壳的意思,就是操作系统的外壳。我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包括ls、cd、pwd等等。总结来说,Shell是一个命令解释器,它通过接受用户输入的Shell命令来启动、暂停、停止程序的运行或对计算机进行控制。
shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。
一般来讲,当你正在使用Python编译器,需要用到命令行工具的时候,要在shell和IDLE之间进行切换。
但是,如果你用的是Jupyter,就完全不用这么麻烦了,你可以直接在命令之前放一个“!”,就能执行shell命令,完全不用切换来切换去,就能在Python里执行任何命令行。
2.常用命令
# 返回主文件夹
!ls /home
# 返回当前文件夹下的目录名
!ls ./
ls -l
# 查看文件
!pwd
#mv:移动文件与目录,或修改文件与目录的名称
!mv /home/aistudio/work/test_copy.txt(原路径) /home/aistudio/data(目的路径)
# rm :移除文件或目录
!rm /home/aistudio/data/test_copy.txt
3.gzip
linux压缩文件中最常见的后缀名即为.gz,gzip是用来压缩和解压.gz文件的命令。
常用参数:
-d或--decompress或--uncompress:解压文件;
-r或--recursive:递归压缩指定文件夹下的文件(该文件夹下的所有文件被压缩成单独的.gz文件);
-v或--verbose:显示指令执行过程。
注:gzip命令只能压缩单个文件,而不能把一个文件夹压缩成一个文件(与打包命令的区别)。
#会将文件压缩为文件 test.txt.gz,原来的文件则没有了,解压缩也一样
!gzip /home/aistudio/work/test.txt
# 解压
!gzip -d /home/aistudio/test.gz
4.tar
tar本身是一个打包命令,用来打包或者解包后缀名为.tar。配合参数可同时实现打包和压缩。
常用参数:
-c或--create:建立新的备份文件;
-x或--extract或--get:从备份文件中还原文件;
-v:显示指令执行过程;
-f或--file:指定备份文件;
-C:指定目的目录;
-z:通过gzip指令处理备份文件;
-j:通过bzip2指令处理备份文件。
最常用的是将tar命令与gzip命令组合起来,直接对文件夹先打包后压缩:
!tar -zcvf /home/aistudio/work/test.tar.gz /home/aistudio/work/test.txt
!tar -zxvf /home/aistudio/work/test.tar.gz
5. zip和unzip
zip命令和unzip命令用在在Linux上处理.zip的压缩文件。
常用参数
zip:
-v:显示指令执行过程;
-m:不保留原文件;
-r:递归处理。
unzip:
-v:显示指令执行过程;
-d:解压到指定目录。
# 压缩
!zip -r /home/aistudio/work/test.zip /home/aistudio/work/test.txt
# 解压 -d(指定目录,如果没有文件夹可以自动新建)
!unzip -d/home/aistudio/work/day1 /home/aistudio/work/day1资料.zip
6.tree 查看文件结构
(3条消息) Linux下tree的使用介绍_Less Is More-CSDN博客
其他
1.yield
首先,如果你还没有对yield有个初步分认识,那么你先把yield看做“return”,这个是直观的,它首先是个return,普通的return是什么意思,就是在程序中返回某个值,返回之后程序就不再往下运行了。看做return之后再把它看做一个是生成器(generator)的一部分(带yield的函数才是真正的迭代器)
一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行
。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值
。
yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。
2.生成器
生成器(generator)其实是一类特殊的迭代器。前面博客我们每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,python就搞了个生成器。所以说生成器(generator)其实是一类特殊的迭代器。
1.生成器的好处是可以一边循环一边进行计算,不用一下子就生成一个很大的集合,占用内存空间。生成器的使用节省内存空间。
每次调用 next(G) ,就计算出 G 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的异常。
.在 Python 中,使用了 yield 的函数都可被称为生成器(generator)。生成器是一个返回迭代器的函数,只能用于迭代操作。更简单点理解生成器就是一个迭代器。
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。简单来说:只要在def中有yield关键字的 就称为 生成器
3.迭代器
4.enumerate
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。