文本文件操作
文件读取处理
-
使用 read()
python# 使用 'read' 方法读取文件的所有内容 with open('resources/training_log.txt', 'r') as file: content = file.read() print(content) # 报错处理版本 # 使用 'read' 方法读取文件的所有内容 # 使用 'utf-8' 编码方式打开文件 with open('resources/training_log.txt', 'r', encoding='utf-8') as file: content = file.read() print(content) 运行效果: 俺啥都奥多拉拉飞机 秦时明月汉时关, 万里长征人未还。 但使龙城飞将在, 不教胡马度阴山。
-
使用readline() 逐行读取文件
arduino# 使用 'readline' 方法逐行读取文件 with open('resources/training_log.txt', 'r') as file: line = file.readline() print(line) while line: print(line, end='') line = file.readline() 运行效果: 俺啥都奥多拉拉飞机 俺啥都奥多拉拉飞机 秦时明月汉时关, 万里长征人未还。 但使龙城飞将在, 不教胡马度阴山。
-
使用 readlines 读取多行信息,会将所有信息拼接成一个列表
lua# 使用 'readlines' 方法读取文件的所有行 with open('resources/training_log.txt', 'r') as file: lines = file.readlines() print(lines) for line in lines: print(line, end='') 运行效果: ['俺啥都奥多拉拉飞机\n', '秦时明月汉时关,\n', '万里长征人未还。\n', '但使龙城飞将在,\n', '不 教胡马度阴山。'] 俺啥都奥多拉拉飞机 秦时明月汉时关, 万里长征人未还。 但使龙城飞将在, 不教胡马度阴山。
文件写入处理
-
使用 write() 方法写入文件
python# 使用 'write' 方法写入文件 with open('resources/example_1.txt', 'w') as file: file.write("Hello, World!") 运行效果: resources目录下多了一个example_1.txt文件,内容为 "Hello, World!"
-
使用 'writelines' 方法写入多行文件
lua# 使用 'writelines' 方法写入多行文件 lines = ["Hello, World!", "Welcome to Python programming."] with open('resources/example_2.txt', 'w') as file: file.writelines(line + '\n' for line in lines) 运行效果: resources目录下多了一个example_2.txt文件,内容为 Hello, World! Welcome to Python programming.
综合案例:日志文件读写
写一段代码,模拟生成 accurary 逐步上升、loss 逐步下降的训练日志,并将日志信息记录到 training_log.txt 中
python
import random
# 定义训练轮数、准确率和损失
epoch = 100
accuracy = 0.5
loss = 0.9
# 打开文件并写入表头
with open('training_log.txt', 'w') as f:
# 第一行内容
f.write('Epoch\tAccuracy\tLoss\n')
# 循环训练
for epoch_i in range(1, epoch+1):
# 随机更新准确率和损失
# random.uniform 随机数,参数为随机数范围
accuracy += random.uniform(0, 0.005)
loss -= random.uniform(0, 0.005)
# 确保准确率在0到1之间,损失在0到1之间
accuracy = min(1, accuracy)
loss = max(0, loss)
# 将训练信息写入文件
# :.3f 保留小数点后三位
f.write(f'{epoch_i}\t{accuracy:.3f}\t{loss:.3f}\n')
# 打印当前训练信息
print(f'Epoch:{epoch_i}, Accuracy:{accuracy}, Loss:{loss}')
运行结果:
Epoch:1, Accuracy:0.501179283434492, Loss:0.8968876573254405
Epoch:2, Accuracy:0.5012701446173562, Loss:0.892587190207276
Epoch:3, Accuracy:0.5015028116406762, Loss:0.8908834919247945
Epoch:4, Accuracy:0.5058295280112071, Loss:0.8885752496845984
Epoch:5, Accuracy:0.5107747387348778, Loss:0.8875305056385812
Epoch:6, Accuracy:0.5134465523544417, Loss:0.8859972537197854
Epoch:7, Accuracy:0.5146851947399464, Loss:0.8814020451165393
Epoch:8, Accuracy:0.5154084829391488, Loss:0.8766349678804274
Epoch:9, Accuracy:0.518524659425188, Loss:0.8735754670347503
Epoch:10, Accuracy:0.5200278427804359, Loss:0.8711413616408478
生成 training_log.txt 文件内容为
Epoch Accuracy Loss
1 0.501 0.897
2 0.501 0.893
3 0.502 0.891
4 0.506 0.889
5 0.511 0.888
6 0.513 0.886
7 0.515 0.881
8 0.515 0.877
9 0.519 0.874
10 0.520 0.871
pandas 表格数据处理
- 安装 pandas
bash
pip install pandas
# 清华源来安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas
- 安装 openpyxl
bash
pip install openpyxl
# 清华源来安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openpyxl
pandas表格读取与数据处理
-
读取 csv 表格文件
pythonimport pandas as pd data_loc = r'./resources/yolov5s.csv' data = pd.read_csv(data_loc) print(data) 运行结果: epoch train/box_loss ... x/lr1 x/lr2 0 0 0.103060 ... 0.000900 0.091900 1 1 0.076159 ... 0.001810 0.083710 2 2 0.066722 ... 0.002718 0.075518 3 3 0.062263 ... 0.003623 0.067323 4 4 0.057136 ... 0.004524 0.059124 .. ... ... ... ... ... 95 95 0.026012 ... 0.001080 0.001080 96 96 0.026545 ... 0.001055 0.001055 97 97 0.026161 ... 0.001035 0.001035 98 98 0.026270 ... 0.001020 0.001020 99 99 0.025782 ... 0.001009 0.001009
-
读取 excel 表格
yamlimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) print(data) 运行结果: 顾客编号 大类编码 大类名称 中类编码 中类名称 小类编码 ... 商品类型 单位 销售数量 销售金额 商品单价 是否促销 0 0.0 12.0 蔬果 1201.0 蔬菜 120109.0 ... 生鲜 个 8.000 4.00 2.00 否 1 1.0 20.0 粮油 2014.0 酱菜类 201401.0 ... 一般商品 袋 6.000 3.00 0.50 否 2 2.0 15.0 日配 1505.0 冷藏乳品 150502.0 ... 一般商品 袋 1.000 2.40 2.40 否 3 3.0 15.0 日配 1503.0 冷藏料理 150305.0 ... 一般商品 袋 1.000 6.50 8.30 否 4 4.0 15.0 日配 1505.0 冷藏乳品 150502.0 ... 一般商品 袋 1.000 11.90 11.90 否 ... ... ... ... ... ... ... ... ... .. ... ... ... ... 42811 1605.0 12.0 蔬果 1201.0 蔬菜 120106.0 ... 生鲜 千克 0.217 3.91 18.00 否 42812 1572.0 12.0 蔬果 1201.0 蔬菜 120102.0 ... 生鲜 千克 0.440 0.86 1.96 否 42813 1170.0 30.0 洗化 3016.0 纸制品 301603.0 ... 一般商品 提 1.000 12.90 14.50 是 42814 2605.0 12.0 蔬果 1201.0 蔬菜 120101.0 ... 生鲜 千克 0.718 1.84 2.56 否 42815 2610.0 23.0 酒饮 2317.0 进口饮料 231702.0 ... 联营商品 罐 1.000 8.00 8.00 否
-
读取 excel 表格 数据,输出头几行信息
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) headInfo = data.head() print(headInfo) 运行结果: 顾客编号 大类编码 大类名称 中类编码 中类名称 小类编码 小类名称 销售日期 销售月份 商品编码 规格型号 商品类型 单位 销售数量 销售金额 商品单价 是否促销 0 0.0 12.0 蔬果 1201.0 蔬菜 120109.0 其它蔬菜 20150101.0 201501.0 DW-1201090311 生鲜 个 8.0 4.0 2.0 否 1 1.0 20.0 粮油 2014.0 酱菜类 201401.0 榨菜 20150101.0 201501.0 DW-2014010019 60g 一般商品 袋 6.0 3.0 0.5 否 2 2.0 15.0 日配 1505.0 冷藏乳品 150502.0 冷藏加味酸乳 20150101.0 201501.0 DW-1505020011 150g 一般商品 袋 1.0 2.4 2.4 否 3 3.0 15.0 日配 1503.0 冷藏料理 150305.0 冷藏面食类 20150101.0 201501.0 DW-1503050035 500g 一般商品 袋 1.0 6.5 8.3 否 4 4.0 15.0 日配 1505.0 冷藏乳品 150502.0 冷藏加味酸乳 20150101.0 201501.0 DW-1505020020 100g*8 一般商品 袋 1.0 11.9 11.9 否
注:head 传入数字几,就表示输出前几行信息
-
读取 excel 表格 数据,输出尾几行信息
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) tailInfo = data.tail() print(tailInfo) 运行结果: 顾客编号 大类编码 大类名称 中类编码 中类名称 小类编码 小类名称 销售日期 销售月份 商品编码 规格型号 商品类型 单 位 销售数量 销售金额 商品单价 是否促销 42811 1605.0 12.0 蔬果 1201.0 蔬菜 120106.0 菌菇类 20150430.0 201504.0 DW-1201060002 散称 生鲜 千克 0.217 3.91 18.00 否 42812 1572.0 12.0 蔬果 1201.0 蔬菜 120102.0 根茎 20150430.0 201504.0 DW-1201020040 散称 生鲜 千克 0.440 0.86 1.96 否 42813 1170.0 30.0 洗化 3016.0 纸制品 301603.0 无芯纸 20150430.0 201504.0 DW-3016030007 10卷 一般商品 提 1.000 12.90 14.50 是 42814 2605.0 12.0 蔬果 1201.0 蔬菜 120101.0 叶菜 20150430.0 201504.0 DW-1201010023 散称 生鲜 千克 0.718 1.84 2.56 否 42815 2610.0 23.0 酒饮 2317.0 进口饮料 231702.0 进口果汁 20150430.0 201504.0 DW-2317020131 490ml 联营商品 罐 1.000 8.00 8.00 否
-
读取 excel 表格 数据,定位第一行
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) data_0 = data.loc[0] print(data_0) 运行结果: 顾客编号 0.0 大类编码 12.0 大类名称 蔬果 中类编码 1201.0 中类名称 蔬菜 小类编码 120109.0 小类名称 其它蔬菜 销售日期 20150101.0 销售月份 201501.0 商品编码 DW-1201090311 规格型号 商品类型 生鲜 单位 个 销售数量 8.0 销售金额 4.0 商品单价 2.0 是否促销 否 Name: 0, dtype: object
-
读取 excel 表格 数据,定位指定列
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) # 读"大类编码"列的全部值 data_1 = data.loc[:,"大类编码"] print(data_1) 运行结果: 0 12.0 1 20.0 2 15.0 3 15.0 4 15.0 ... 42811 12.0 42812 12.0 42813 30.0 42814 12.0 42815 23.0 Name: 大类编码, Length: 42816, dtype: float64
-
读取 excel 表格 数据,定位指定元素
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) # 读取第一行,"大类编码"列对应的值 data_2 = data.loc[1,"大类编码"] print(data_2) 运行结果: 20.0
-
读取 excel 表格 数据,对行和列进行切片
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) # 读取第一行到第三行,"大类编码"列到"中类名称"列这个区域内的值 data_3 = data.loc[1:3,"大类编码":"中类名称"] print(data_3) 运行结果: 大类编码 大类名称 中类编码 中类名称 1 20.0 粮油 2014.0 酱菜类 2 15.0 日配 1505.0 冷藏乳品 3 15.0 日配 1503.0 冷藏料理
-
读取 excel 表格 数据,提取符合要求的元素
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) # 读取"销售数量"列中大于10的值 data_4 = data.loc[data["销售数量"]>10] print(data_4) 运行结果: 顾客编号 大类编码 大类名称 中类编码 中类名称 小类编码 小类名称 ... 规格型号 商品类型 单位 销售数量 销售金额 商品单价 是否促销 22 19.0 15.0 日配 1518.0 常温乳品 151805.0 利乐枕纯奶 ... 240ml 一般商品 袋 16.0 33.9 2.7 是 51 33.0 15.0 日配 1518.0 常温乳品 151805.0 利乐枕纯奶 ... 240ml 一般商品 袋 16.0 43.2 2.7 否 437 116.0 15.0 日配 1518.0 常温乳品 151813.0 利乐砖乳酸菌 ... 205g 一般商品 盒 12.0 49.0 5.5 是 478 66.0 15.0 日配 1518.0 常温乳品 151807.0 利乐枕营养奶 ... 240ml 一般商品 袋 16.0 44.8 2.8 否 488 86.0 20.0 粮油 2015.0 罐头 201501.0 八宝粥 ... 360g 一般商品 个 12.0 38.4 3.2 否... ... ... ... ... ... ... ... ... ... ... .. ... ... ... ... 42444 2601.0 15.0 日配 1518.0 常温乳品 151806.0 利乐枕加味奶 ... 230ml 一般商品 袋 16.0 29.9 2.8 是 42500 1973.0 15.0 日配 1518.0 常温乳品 151813.0 利乐砖乳酸菌 ... 200ml 一般商品 盒 12.0 58.9 5.3 是 42509 1631.0 15.0 日配 1521.0 蛋类 152101.0 新鲜蛋品 ... 散称 一般商品 kg 10.1 141.4 14.0 否 42746 421.0 15.0 日配 1505.0 冷藏乳品 150502.0 冷藏加味酸乳 ... 150g 一般商品 袋 15.0 26.9 2.4 是 42757 74.0 15.0 日配 1518.0 常温乳品 151803.0 利乐砖营养奶 ... 250ml 一般商品 盒 24.0 79.2 3.3 否
-
读取 excel 表格 数据,提取符合要求的元素(切片)
pythonimport pandas as pd data_loc = r'./resources/销售数据.xlsx' data = pd.read_excel(data_loc) # 读取"销售数量"列中大于10,"小类编码"列到"小类名称"列这个区域内的值 data_5 = data.loc[data["销售数量"]>10,["小类编码","小类名称"]] print(data_5) 运行结果: 小类编码 小类名称 22 151805.0 利乐枕纯奶 51 151805.0 利乐枕纯奶 437 151813.0 利乐砖乳酸菌 478 151807.0 利乐枕营养奶 488 201501.0 八宝粥 ... ... ... 42444 151806.0 利乐枕加味奶 42500 151813.0 利乐砖乳酸菌 42509 152101.0 新鲜蛋品 42746 150502.0 冷藏加味酸乳 42757 151803.0 利乐砖营养奶 [682 rows x 2 columns]
-
读取 excel 表格 数据,数据分组和排序
python# 导入 Pandas 库并将其重命名为 pd import pandas as pd # 定义销售数据文件路径 data_loc = r'./resources/销售数据.xlsx' # 使用 Pandas 读取 Excel 文件中的数据,并存储在名为 data 的 DataFrame 中 data = pd.read_excel(data_loc) # 按商品类型分组,并计算每个商品类型的销售金额总和 data_extract = data.groupby('商品类型')['销售金额'].sum() # 重置索引,将分组后的结果重新设置为 DataFrame,以便后续操作 data_extract = data_extract.reset_index() # 打印分组后的结果,包括商品类型和对应的销售金额总和 print(data_extract) 运行结果: 商品类型 销售金额 0 一般商品 336529.74 1 生鲜 111808.70 2 联营商品 5873.81
-
读取 excel 表格 数据,将处理好的数据保存成 excel
python# 导入 Pandas 库并将其重命名为 pd import pandas as pd # 定义销售数据文件路径 data_loc = r'./resources/销售数据.xlsx' # 使用 Pandas 读取 Excel 文件中的数据,并存储在名为 data 的 DataFrame 中 data = pd.read_excel(data_loc) # 按商品类型分组,并计算每个商品类型的销售金额总和 data_extract = data.groupby('商品类型')['销售金额'].sum() # 重置索引,将分组后的结果重新设置为 DataFrame,以便后续操作 data_extract = data_extract.reset_index() data_extract.to_csv("处理好的表格.csv",index=False) data_extract.to_excel("处理好的表格.xlsx",index=False)
注:
- 表格中有中文一定要加 "encoding='gbk'",实测不加貌似也行
- to_excel 不支持传入 "encoding='gbk'"
- 不保存表格左边的序号列加 "index=False"
Matplotlib 常用画图处理
-
安装 matplotlib
bashpip install matplotlib # 清华源来安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib
-
numpy
arduinopip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy
-
kiwisolver
arduinopip install -i https://pypi.tuna.tsinghua.edu.cn/simple kiwisolver
绘制折线图
-
曲线图
pythonimport numpy as np import matplotlib.pyplot as plt # 创建一个x值的数组,从-2π到2π,步长为0.01 x = np.arange(-2 * np.pi, 2 * np.pi, 0.01) # 计算每个x值对应的sin(x)值 y = np.sin(x) # 使用matplotlib来绘制图像 plt.figure() # 创建一个新的图像窗口 plt.plot(x, y) # 绘制折线图 plt.title('sin(x)') # 设置图像的标题 plt.xlabel('x') # 设置x轴的标签 plt.ylabel('sin(x)') # 设置y轴的标签 plt.grid(True) # 显示网格 plt.show() # 显示图像
-
单折线图
pythonimport pandas as pd import matplotlib.pyplot as plt # 导入数据集 data_loc = r'resources/yolov5s.csv' data = pd.read_csv(data_loc, index_col=0) # 提取训练框损失数据 train_bbox_loss = data[' train/box_loss'] # 创建 x 轴数据 x_list = [i for i in range(len(train_bbox_loss))] # 绘制损失曲线图 plt.plot(x_list, train_bbox_loss) plt.xlabel('Epoch') # 设置 x 轴标签 plt.ylabel('Loss') # 设置 y 轴标签 plt.title('YOLOv5s') # 设置图表标题 plt.show() # 显示图表
-
多折线图
iniimport pandas as pd import matplotlib.pyplot as plt # 定义文件路径 file_1_loc = 'resources/yolov5l.csv' file_2_loc = 'resources/yolov5m.csv' file_3_loc = 'resources/yolov5s.csv' # 读取数据文件 file_1 = pd.read_csv(file_1_loc) file_2 = pd.read_csv(file_2_loc) file_3 = pd.read_csv(file_3_loc) # 提取训练框损失数据 file_1_train_box_loss = file_1[' train/box_loss'] file_2_train_box_loss = file_2[' train/box_loss'] file_3_train_box_loss = file_3[' train/box_loss'] # 创建 x 轴数据 x_list = [i for i in range(len(file_1_train_box_loss))] # 绘制损失曲线 plt.plot(x_list, file_1_train_box_loss) plt.plot(x_list, file_2_train_box_loss) plt.plot(x_list, file_3_train_box_loss) # 设置 x 轴标签 plt.xlabel("Epoch") # 设置 y 轴标签 plt.ylabel("Loss") # 设置图表标题 plt.title("Train box_loss") # 添加网格线 plt.grid() # 添加图例 plt.legend(['yolov5l', 'yolov5m', 'yolov5s']) # 显示图表 plt.show()
绘制散点图
ini
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
num_points = 100
x = np.random.rand(num_points) # x坐标
y = np.random.rand(num_points) # y坐标
colors = np.random.rand(num_points) # 每个点的颜色
sizes = 1000 * np.random.rand(num_points) # 每个点的大小
alphas = np.random.rand(num_points) # 每个点的透明度
# 创建散点图
plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')
# 显示颜色条
plt.colorbar()
# 显示图像
plt.show()
绘制柱状图
ini
import matplotlib.pyplot as plt
import numpy as np
# 数据
labels = ['A', 'B', 'C', 'D', 'E']
values = [3, 7, 2, 5, 8]
# 设置标签的位置
x = np.arange(len(labels))
# 绘制柱状图
plt.bar(x, values, color='blue', align='center', alpha=0.7)
# 设置图表的标题和轴标签
plt.title('Simple Bar Chart')
plt.xlabel('Labels')
plt.ylabel('Values')
# 设置x轴的标签
plt.xticks(x, labels)
# 显示图像
plt.show()
绘制饼状图
ini
import matplotlib.pyplot as plt
# 数据
sizes = [15, 30, 45, 10] # 各部分的大小
labels = ['A', 'B', 'C', 'D'] # 各部分的标签
colors = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue'] # 各部分的颜色
explode = (0.1, 0, 0, 0) # 突出显示第一个部分,这里的值表示从圆心移出的距离,相对于半径的比例
# 绘制扇形图
plt.pie(
sizes, # 数据大小
explode=explode, # 突出显示的部分
labels=labels, # 标签
colors=colors, # 颜色
autopct='%1.1f%%', # 设置百分比显示格式,'%1.1f%%'表示小数点后1位
shadow=True, # 是否显示阴影
startangle=140 # 起始角度,以逆时针为正方向,从x轴正方向逆时针旋转的角度
)
# 设置为等比例,这样扇形图就是一个圆
plt.axis('equal')
# 显示图像
plt.show()
OpenCV 影像数据处理
-
作用:用于处理图片及视频文件
-
安装 opencv-python
inipip install -i https://pypi.tuna.tsinghua.edu.cn/simpleopencv-python==4.5.36
图像数据处理
-
加载图片和展示图片
pythonimport cv2 img_path = r'resources/food.png' # 以彩色模式读取图片 image_color = cv2.imread(img_path) # 以灰度模式读取图片 image_gray = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # 显示图片 cv2.imshow('Color Image', image_color) # cv2.imshow('Grayscale Image', image_gray) # 等待用户按键,然后关闭窗口 cv2.waitKey(0) cv2.destroyAllWindows()
注意:
- imread第二个参数不加会默认以彩色模式展示图片
-
图片缩放
iniimport cv2 # 读取图片 image = cv2.imread('resources/food.png') # 检查图片是否正确加载 if image is None: print("Error: Could not load image.") exit() # 打印图片的形状,即高度、宽度和通道数 print(image.shape) # 获取图片的原始尺寸 original_height, original_width = image.shape[:2] # 计算新的尺寸(这里将原始尺寸缩小一半) new_width = int(original_width / 2) new_height = int(original_height / 2) # 使用cv2.resize进行图片缩放,参数包括原始图片、目标大小、插值方法 # 第一个参数是原始图像,第二个参数是目标尺寸,第三个参数是插值方法 # 插值方法决定了如何计算新像素值,常见的插值方法包括INTER_LINEAR和INTER_AREA等 # 这里使用的是INTER_AREA,适合缩小图像 resized_image = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA) # 显示原始图片和缩放后的图片 cv2.imshow('Original Image', image) cv2.imshow('Resized Image', resized_image) # 等待用户按键,然后关闭窗口 cv2.waitKey(0) cv2.destroyAllWindows()
-
图片翻转
iniimport cv2 # 读取图片 image = cv2.imread('resources/food.png') # 使用cv2.rotate()函数旋转图片 # cv2.ROTATE_90_CLOCKWISE表示顺时针旋转90度 rotated_90 = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE) # cv2.ROTATE_180表示顺时针旋转180度 rotated_180 = cv2.rotate(image, cv2.ROTATE_180) # cv2.ROTATE_90_COUNTERCLOCKWISE表示顺时针旋转270度 rotated_270 = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE) # 显示原始图片以及旋转后的图片 cv2.imshow('original', image) cv2.imshow('90 degree', rotated_90) cv2.imshow('180 degree', rotated_180) cv2.imshow('270 degree', rotated_270) # 等待用户按键,然后关闭窗口 cv2.waitKey(0)
-
图片保存
pythonimport cv2 # 读取图像 image = cv2.imread('resources/food.png') # 如果图像不为空,则保存图像 if image is not None: cv2.imwrite('output_image.png', image) else: print("无法读取图像")
视频数据处理
-
视频读取
iniimport cv2 # 创建一个 VideoCapture 对象,参数 0 表示使用默认的摄像头, 也可以传入一个视频文件的路径 cap = cv2.VideoCapture(0) # resources/piano.mp4 while True: # 读取一帧 ret, frame = cap.read() # 如果读取成功,显示这一帧 if ret: cv2.imshow('Frame', frame) # 按 'q' 键退出循环 # waitKey 设置每一帧画面的时间间隔,单位毫秒 if cv2.waitKey(15) & 0xFF == ord('q'): break # 释放资源并关闭窗口 cap.release() cv2.destroyAllWindows()
-
视频数据保存
iniimport cv2 # 定义视频捕获对象,参数为摄像头设备索引,通常 0 表示默认摄像头 cap = cv2.VideoCapture(0) # 检查摄像头是否成功打开 if not cap.isOpened(): print("Error: Could not open camera.") exit() # 获取摄像头的帧宽度和帧高度 frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 定义视频编码器和输出文件,fourcc 参数用于指定视频编码器 fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用 MP4 编码器 # 创建一个 VideoWriter 对象,用于将捕获到的视频帧写入到名为 'output.mp4' 的文件中 # 参数 'output.mp4' 指定了输出视频文件的名称,它将保存在当前工作目录下 # 参数 fourcc 指定了视频编码器的四字符代码,这里使用 MPEG-4 编码器 ('mp4v') # 参数 20.0 指定了输出视频的帧率,即每秒播放的帧数,这里设置为 20 帧每秒 # 参数 (frame_width, frame_height) 指定了输出视频的帧大小,即摄像头捕获到的帧的宽度和高度 out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (frame_width, frame_height)) # 进入视频捕获循环 while True: # 读取摄像头的帧 ret, frame = cap.read() # 如果无法读取帧,则退出循环 if not ret: print("Failed to grab frame.") break # 将当前帧写入输出视频文件 out.write(frame) # 显示当前帧 cv2.imshow('frame', frame) # 检测按键,如果是 'q' 键则退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cap.release() out.release() cv2.destroyAllWindows()
综合案例:视频处理
用 OpenCV 打开一段视频,将每一帧画面压缩成 540p,对画面进行垂直翻转,转为黑白,然后添加高斯噪音,把处理好的每一帧画面保存成一个mp4文件
ini
import cv2
import numpy as np
def add_gaussian_noise(image):
# 获取图像的行数和列数
row, col = image.shape
# 设置高斯噪声的均值和标准差
mean = 0
sigma = 15
# 生成均值为mean、标准差为sigma的高斯分布噪声
gauss = np.random.normal(mean, sigma, (row, col))
# 将噪声叠加到原始图像上
noisy = image + gauss
# 将叠加后的图像像素值限制在0到255之间
noisy_img = np.clip(noisy, 0, 255)
# 将数据类型转换为无符号8位整数,即图像的像素值范围为0到255
return noisy_img.astype(np.uint8)
# 输入和输出视频文件名
input_video = 'resources/outdoor.mp4'
output_video = 'resources/output.mp4'
# 打开输入视频
cap = cv2.VideoCapture(input_video)
# 获取视频的帧率和帧大小
fps = int(cap.get(cv2.CAP_PROP_FPS))
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 计算新的帧大小 (540p)
new_height = 540
new_width = int((new_height / frame_height) * frame_width)
# 创建视频写入对象
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video, fourcc, fps, (new_width, new_height), isColor=False)
while True:
# 读取视频的一帧
ret, frame = cap.read()
# 如果无法读取帧(到达视频末尾),则退出循环
if not ret:
break
# 调整帧大小为新的帧大小
frame = cv2.resize(frame, (new_width, new_height))
# 将彩色图像转换为灰度图像
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 垂直翻转图像
frame = cv2.flip(frame, 1)
# 添加高斯噪声
frame = add_gaussian_noise(frame)
# 将处理后的帧写入输出视频
out.write(frame)
# 释放资源
cap.release()
out.release()
# 关闭所有窗口
cv2.destroyAllWindows()
pickle 文件处理:数据序列化处理
pickle 文件是一种特殊的文件格式,用于在 Python 中序列化(serialization)和反序列化(deserialization)Python 对象。序列化是将对象转换为字节流的过程,而反序列化则是从字节流中重新构造对象的过程。
pickle 模块提供了一个功能强大的序列化和反序列化工具,可以将几乎所有 Python 对象转换为字节流,然后存储到文件中,也可以从文件中加载这些字节流并重新构造出原始对象。
pickle 文件的扩展名通常是 .pkl,.pickle 或者其他类似的扩展名。这些文件可以包含任意 Python 对象的序列化表示,例如字典、列表、类实例等等。pickle 文件在数据持久化、数据传输和对象传递等场景中非常有用,可以轻松地保存和恢复 Python 对象的状态和数据。
pickle 文件操作
-
保存数据
pythonimport pickle # 示例数据 data = { 'name': 'John', 'age': 30, 'is_student': False, 'grades': [85, 90, 78, 92] } # 使用 pickle 保存数据 with open('data.pkl', 'wb') as file: pickle.dump(data, file) 运行效果: 生成 data.pkl 文件
-
加载数据
pythonimport pickle # 使用 pickle 加载数据 with open('data.pkl', 'rb') as file: loaded_data = pickle.load(file) 运行效果: {'name': 'John', 'age': 30, 'is_student': False, 'grades': [85, 90, 78, 92]}
综合案例:pickle实战,数据序列化
当训练人工智能算法时,往往需要很长时间,当训练中断时,如果能提前做好权重保存功能,能很快恢复上次进度,以继续进行训练
python
import pickle
import time
import os
import numpy as np
# 模拟耗时的权重计算过程
def calculate_weights():
print("开始计算权重...")
time.sleep(5) # 模拟耗时操作
weights = np.random.rand(10, 10) # 随机生成权重
print("权重计算完成.")
return weights
# 保存权重和epoch到文件
def save_weights(weights, epoch, filename='weights.pkl'):
data = {'weights': weights, 'epoch': epoch}
with open(filename, 'wb') as f:
pickle.dump(data, f)
print(f"权重和epoch已保存到{filename}.")
# 从文件加载权重和epoch
def load_weights(filename='weights.pkl'):
with open(filename, 'rb') as f:
data = pickle.load(f)
print(f"权重和epoch已从{filename}加载.")
return data['weights'], data['epoch']
# 主程序
def main():
weights_file = 'weights.pkl'
total_epochs = 100 # 假设我们总共需要训练100个epochs
# 如果权重文件存在,则加载权重和epoch
if os.path.exists(weights_file):
weights, start_epoch = load_weights(weights_file)
else:
# 否则,从第一个epoch开始,并计算权重
weights = calculate_weights()
start_epoch = 0
# 继续训练剩余的epochs
for epoch in range(start_epoch, total_epochs):
print(f"开始训练epoch {epoch}...")
# 这里进行实际的训练代码...
time.sleep(1) # 模拟训练过程
print(f"完成训练epoch {epoch}.")
# 每个epoch结束后保存权重和epoch信息
save_weights(weights, epoch, weights_file)
if __name__ == '__main__':
main()
运行结果:
权重和epoch已保存到weights.pkl.
开始训练epoch 72...
完成训练epoch 72.
权重和epoch已保存到weights.pkl.
开始训练epoch 73...
权重和epoch已从weights.pkl加载.
开始训练epoch 72...
完成训练epoch 72.
权重和epoch已保存到weights.pkl.
开始训练epoch 73...
完成训练epoch 73.
权重和epoch已保存到weights.pkl.
PyQt 安装与构建用户界面
在Python中使用PyQt可以快速搭建自己的应用,使得软件有可视化结果
PyQt 安装与运行
-
安装 PyQt
arduinopip install pyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple
-
继续安装 QtDesigner
arduinopip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple --user
Python GUI 快速入门
- 点击PyCharm 的 File -> Settings -> Tools -> External tools 打开外部工具页面
- 点击 + 号进入外部工具页面
- 在"Name"处输入命名,这个名称随便取,只要自己清楚就行
- 在python安装目录下的Libsite-packagespyqt5_tools文件夹里找到安装的designer.exe所在的路径
PyQt 制作界面实战,图片展示功能
python
from QtTest import Ui_MainWindow
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QFileDialog
# 用于显示图片
from PyQt5 import_ QtGui
class CamShow(QMainWindow,Ui_MainWindow):
def __init__(self,parent=None):
super(CamShow,self).__init__(parent)
self.setupUi(self)
# 信号与槽
self.OpenFileBtn.clicked.connect(self.loadImage)
# 定义按钮点击函数
def loadImage(self):
print("按钮被按下了")
# 文件访问功能
self.fname, _ = QFileDialog.getOpenFileName(self, caption: '选择图片', directory: '.', filter: '图像文件(*.jpg *.png)')
print(self.fname)
# 显示图片
pix = QtGui.QPixmap(self.fname).scaled(self.ImgeLabel.width(), self.ImgeLabel.height())
self.ImgeLabel.setPixmap(pix)
if __name__ == '__main__':
app = QApplication(sys.argv)
ui=CamShow()
ui.show()
sys.exit(app.exec_())
优化 PyQt 构建用户界面应用程序
PyQt 制作界面优化
- 调节界面大小:手动调节即可,然后重新执行.ui和mian.py
PyQt 制作界面代码完善
python
from QtTest import Ui_MainWindow
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox
# 用于显示图片
from PyQt5 import QtGui
class CamShow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(CamShow, self).__init__(parent)
self.setupUi(self)
# 信号与槽
self.OpenFileBtn.clicked.connect(self.loadImage)
# 打开文件点击实现
self.actionOpen.triggered.connect(self.loadImage)
# 点击退出实现
self.actionexit.triggered.connect(self.exit)
# 点击关于按钮
self.actionabout.triggered.connect(self.about)
# 定义按钮点击函数
def loadImage(self):
# 更新infolabel展示内容
self.infolabel.setText("打开文件按钮被按下了")
# 文件访问功能
self.fname, _ = QFileDialog.getOpenFileName(self, caption='选择图片', directory='.', filter='图像文件(*.jpg *.png)')
print(self.fname)
# 显示图片
pix = QtGui.QPixmap(self.fname).scaled(self.ImgeLabel.width(), self.ImgeLabel.height())
self.ImgeLabel.setPixmap(pix)
# 定义退出程序功能
def exit(self):
sys.exit(app.exec_())
# 关于按钮
def about(self):
self.infolabel.setText("帮助按钮被按下了")
QMessageBox.information(self, title='软件说明', text='该软件由xxx制作而成,软件版本为1.0')
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = CamShow()
ui.show()
sys.exit(app.exec_())