0%

简介

  • list 列表 相关笔记

python3 list是什么

在Python中,list(列表)是一种有序、可变、可重复的数据结构,用于存储一组元素。列表是Python中最常用的数据结构之一,非常灵活和强大,它可以包含任意类型的元素,包括整数、浮点数、字符串、甚至其他列表等。

以下是关于Python列表的一些特点和用法:

  1. 有序性:列表中的元素是按照它们的插入顺序进行存储的,因此列表是有序的数据结构。

  2. 可变性:列表是可变的,这意味着您可以随时修改列表中的元素,例如添加、删除或更新元素。

  3. 可重复性:列表允许存储相同的元素,因此可以包含重复的值。

  4. 索引访问:您可以使用索引来访问列表中的元素。列表的索引是从0开始的,即第一个元素的索引是0,第二个元素的索引是1,依此类推。

  5. 列表推导式:列表推导式是一种简洁的方式来创建列表,它允许您使用一行代码生成一个新的列表,通常使用for循环和条件表达式来定义列表的内容。

  6. 多种方法和操作:Python提供了丰富的列表方法和操作,如添加元素、删除元素、查找元素、列表切片等,这使得对列表进行各种操作变得非常方便。

以下是一个简单的示例,演示了如何创建和操作列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建一个列表
my_list = [1, 2, 3, 4, 5]

# 添加元素
my_list.append(6)

# 删除元素
my_list.remove(3)

# 列表切片
subset = my_list[1:4]

# 使用列表推导式生成新列表
new_list = [x**2 for x in my_list]

# 打印列表内容
print(my_list) # 输出: [1, 2, 4, 5, 6]
print(subset) # 输出: [2, 4, 5]
print(new_list) # 输出: [1, 4, 16, 25, 36]

总之,Python中的列表是一种非常常用且功能丰富的数据结构,它提供了灵活的方法来存储和操作一组元素。

python3 list 常用操作

Python中的列表(list)是一种非常灵活和常用的数据结构,它提供了许多常用的操作,使得对列表进行处理变得非常方便。以下是一些常用的Python列表操作:

  1. 创建列表:使用方括号[]来创建一个列表,并在其中添加元素。
1
my_list = [1, 2, 3, 4, 5]
  1. 访问元素:使用索引来访问列表中的元素。列表的索引从0开始。
1
print(my_list[0])  # 输出: 1
  1. 切片:使用切片来获取列表的子列表。
1
2
subset = my_list[1:4]  # 获取索引1到索引3的元素
print(subset) # 输出: [2, 3, 4]
  1. 添加元素:使用append()方法向列表末尾添加一个元素。
1
2
my_list.append(6)
print(my_list) # 输出: [1, 2, 3, 4, 5, 6]
  1. 删除元素:使用remove()方法删除列表中的指定元素,使用del语句删除列表中指定索引处的元素。
1
2
3
4
5
my_list.remove(3)  # 删除元素3
print(my_list) # 输出: [1, 2, 4, 5, 6]

del my_list[0] # 删除索引为0的元素
print(my_list) # 输出: [2, 4, 5, 6]
  1. 列表长度:使用len()函数获取列表中元素的个数。
1
2
length = len(my_list)
print(length) # 输出: 4
  1. 查找元素:使用index()方法查找列表中某个元素的索引。
1
2
index = my_list.index(4)
print(index) # 输出: 1
  1. 反转列表:使用reverse()方法将列表中的元素反转。
1
2
my_list.reverse()
print(my_list) # 输出: [6, 5, 4, 2]
  1. 排序:使用sort()方法对列表中的元素进行排序。
1
2
my_list.sort()
print(my_list) # 输出: [2, 4, 5, 6]
  1. 复制列表:使用切片或copy()方法复制一个列表。
1
2
3
new_list = my_list[:]  # 使用切片复制列表
# 或者
new_list = my_list.copy() # 使用copy()方法复制列表

这些是Python中列表的一些常用操作。列表还有很多其他方法和功能,具体取决于您的需求和情况。

python3 list 常用技巧

在Python中,有许多技巧可以让您更有效地使用列表。以下是一些常用的Python列表技巧:

  1. 列表解析(List Comprehension):列表解析是一种简洁而强大的方式来创建新的列表,它允许您在单个表达式中对列表元素进行转换或过滤。
1
2
3
4
5
# 创建一个包含元素平方的新列表
squared_list = [x**2 for x in range(10)]

# 使用条件筛选元素
even_numbers = [x for x in range(10) if x % 2 == 0]
  1. 列表拼接:使用+运算符将两个列表拼接成一个新的列表。
1
2
3
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined_list = list1 + list2
  1. 列表切片赋值:使用切片来替换列表中的一部分元素。
1
2
my_list = [1, 2, 3, 4, 5]
my_list[1:3] = [6, 7]
  1. 使用zip()函数zip()函数可以将多个列表按照索引位置进行组合,生成一个元组列表。
1
2
3
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
combined_data = list(zip(names, ages))
  1. 翻转索引和值:使用字典的zip()dict()函数可以快速创建一个索引-值对调的字典。
1
2
my_dict = {'a': 1, 'b': 2, 'c': 3}
inverted_dict = dict(zip(my_dict.values(), my_dict.keys()))
  1. 获取唯一值:使用集合(set)可以快速获取列表中的唯一值。
1
2
my_list = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_values = list(set(my_list))
  1. 迭代时获取索引:使用enumerate()函数可以同时获取索引和值。
1
2
3
my_list = ['a', 'b', 'c']
for index, value in enumerate(my_list):
print(index, value)
  1. 将多维列表展平:使用列表解析可以快速将多维列表展平为一维列表。
1
2
nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened_list = [item for sublist in nested_list for item in sublist]

这些是Python中常用的一些列表技巧。它们可以帮助您更加高效地处理和操作列表数据。

简介

  • python 常用的编程技巧笔记

python3 numpy 轴角的轴向量和旋转向量形成一维向量并且只包含三个数

如果你想将轴向量和旋转角度组合成一个只包含三个数的一维向量,可以将轴向量的三个坐标和旋转角度的值合并在一起。这样,你将得到一个长度为3的一维向量,其中包含了轴向量和旋转角度的信息。

以下是一个使用NumPy的示例代码:

1
2
3
4
5
6
7
8
9
10
11
import numpy as np

# 定义轴向量和旋转角度
axis = np.array([1.0, 0.0, 0.0]) # 以 x 轴为例
angle = np.radians(45) # 旋转角度,这里将角度转换为弧度

# 将轴向量和旋转角度合并成一个只包含三个数的一维向量
combined_vector = np.concatenate([axis * angle])

# 输出组合后的一维向量
print("轴角一维向量:", combined_vector)

在这个例子中,我们使用np.concatenate将轴向量的三个坐标和旋转角度的值合并成了一个只包含三个数的一维向量。这种表示方式仅在某些特定情况下有效,因此在使用时,请确保你的应用能够正确理解和处理这种组合方式。如果你的应用需要更详细的轴角信息,建议使用长度为4的一维向量,其中包含轴向量的坐标和旋转角度。

python3 numpy 只包含三个数的轴角取模转为的轴向量和旋转向量

在轴角表示法中,通常轴向量是一个单位向量,其模(长度)为1。如果你有一个只包含三个数的轴角表示,表示的轴向量的模可能不为1。为了将其转为单位向量,你可以使用NumPy进行归一化操作。

以下是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np

# 定义只包含三个数的轴角表示
axis_angle_vector = np.array([1.5, 0.0, 0.0])

# 取模,得到旋转角度
angle = np.linalg.norm(axis_angle_vector)

# 归一化轴向量
axis_vector = axis_angle_vector / angle

# 输出归一化后的轴向量和旋转角度
print("归一化后的轴向量:", axis_vector)
print("旋转角度:", angle)

在这个例子中,np.linalg.norm(axis_angle_vector)用于计算轴角向量的模(长度),然后通过除以模的方式将轴向量归一化。最终,你得到了一个单位轴向量和对应的旋转角度。

请注意,这里假设输入的轴角向量是有效的,即不为零向量。在实际应用中,你可能需要添加一些额外的检查和处理,以确保计算的正确性。

python3 写入文件数据 立刻更新到文件中

在Python 3中,您可以使用write方法将数据写入文件,并立即将更改更新到文件中。默认情况下,write方法会将数据写入文件缓冲区,但这些数据不会立即写入磁盘。要立即更新文件并将数据写入磁盘,您可以执行以下操作:

  1. 打开文件:使用open函数以写入模式打开文件。
1
file = open('文件名.txt', 'w')
  1. 写入数据并刷新缓冲区:使用write方法将数据写入文件,然后使用flush方法刷新文件缓冲区,以确保数据立即写入磁盘。
1
2
3
data_to_write = "要写入的数据\n"
file.write(data_to_write)
file.flush()
  1. 关闭文件:最后,不要忘记关闭文件,以释放资源并确保数据被保存。
1
file.close()

完整的示例:

1
2
3
4
5
file = open('文件名.txt', 'w')
data_to_write = "要写入的数据\n"
file.write(data_to_write)
file.flush()
file.close()

这将立即将数据写入文件,并在flush之后立即更新到文件中。请注意,使用flush会导致额外的磁盘I/O,所以在需要时才使用它,以避免不必要的性能开销。

python3 向文件追加一行数据 详解

在Python 3中,要向文件追加一行数据,您可以使用内置的open函数以追加模式打开文件,并使用write方法将数据写入文件。以下是详细的步骤:

  1. 打开文件以进行追加操作:您可以使用open函数来打开文件,将文件名作为第一个参数传递给它,以及一个字符串参数,指示以追加模式打开文件。追加模式的标志是 'a'
1
2
with open('文件名.txt', 'a') as file:
# 在这里执行追加操作
  1. 将数据写入文件:在打开文件后,您可以使用write方法将数据追加到文件中。数据通常是一个字符串,但您可以将其他数据类型转换为字符串以写入文件。
1
2
3
with open('文件名.txt', 'a') as file:
data_to_append = "要追加的数据\n"
file.write(data_to_append)

请注意,您需要在数据后面加上换行符\n,以便将数据添加为新行。如果不加入\n,所有追加的数据都会写在同一行。

  1. 关闭文件(可选):虽然使用with语句可以自动关闭文件,但如果您不使用with语句,确保在操作完成后手动关闭文件,以释放资源并保存更改。

完整的示例:

1
2
3
with open('文件名.txt', 'a') as file:
data_to_append = "要追加的数据\n"
file.write(data_to_append)

这将在名为’文件名.txt’的文件中追加一行数据。如果文件不存在,将创建一个新文件。如果您希望在写入后立即查看文件内容,可以在write操作之后执行读取操作。

python3 列表 常用技巧 详解

Python 中的列表是一种非常常用的数据结构,可以存储多个值,并提供了许多功能丰富的操作。以下是一些 Python 3 中常用的列表技巧和操作的详细解释:

1. 列表的创建:

创建一个列表可以使用方括号 []list() 构造函数。

1
2
3
my_list = [1, 2, 3]
my_empty_list = []
another_list = list(range(5))

2. 访问列表元素:

您可以通过索引访问列表中的元素,索引从 0 开始。

1
2
3
my_list = [10, 20, 30, 40, 50]
print(my_list[0]) # 输出 10
print(my_list[2]) # 输出 30

3. 修改列表元素:

列表中的元素是可变的,可以通过索引来修改它们。

1
2
3
my_list = [10, 20, 30]
my_list[1] = 25 # 修改第二个元素为 25
print(my_list) # 输出 [10, 25, 30]

4. 添加元素:

您可以使用 append() 方法向列表末尾添加元素。

1
2
3
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) # 输出 [1, 2, 3, 4]

5. 删除元素:

使用 del 语句可以删除列表中的元素。

1
2
3
my_list = [1, 2, 3]
del my_list[1] # 删除第二个元素
print(my_list) # 输出 [1, 3]

6. 列表切片:

通过切片,您可以获取列表中的一部分。

1
2
3
my_list = [1, 2, 3, 4, 5]
sublist = my_list[1:4] # 获取索引 1 到 3 的元素
print(sublist) # 输出 [2, 3, 4]

7. 列表合并:

使用 + 运算符可以将两个列表合并成一个。

1
2
3
4
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined_list = list1 + list2
print(combined_list) # 输出 [1, 2, 3, 4, 5, 6]

8. 列表复制:

使用切片或 copy() 方法可以创建列表的副本。

1
2
original_list = [1, 2, 3]
copy_list = original_list[:] # 使用切片创建副本

9. 列表长度:

使用 len() 函数可以获取列表的长度。

1
2
3
my_list = [1, 2, 3, 4, 5]
length = len(my_list)
print(length) # 输出 5

10. 列表推导式:

列表推导式是一种快速创建列表的方式。

1
2
squared_numbers = [x ** 2 for x in range(5)]
print(squared_numbers) # 输出 [0, 1, 4, 9, 16]

11. 列表排序:

使用 sort() 方法可以对列表进行升序排序。

1
2
3
my_list = [3, 1, 2, 5, 4]
my_list.sort()
print(my_list) # 输出 [1, 2, 3, 4, 5]

12. 反转列表:

使用 reverse() 方法可以反转列表元素的顺序。

1
2
3
my_list = [1, 2, 3]
my_list.reverse()
print(my_list) # 输出 [3, 2, 1]

这些是 Python 3 中常用的列表技巧和操作。列表是一个非常灵活和强大的数据结构,可以用于各种任务,包括存储和处理数据。根据您的需求,您可以使用上述技巧来操作和处理列表。

“1.1 1.2 1.3” 正则表达式获取三个浮点数 python3

要从字符串中提取三个浮点数,您可以使用正则表达式匹配这些浮点数并提取它们。以下是如何在 Python 3 中使用 re 模块实现这个任务:

1
2
3
4
5
6
7
8
9
10
11
import re

text = "1.1 1.2 1.3 Some other text here."

# 定义匹配浮点数的正则表达式模式
pattern = r'\d+\.\d+'

# 使用 re.findall() 函数提取匹配的浮点数
matches = re.findall(pattern, text)

print("Matches:", matches)

上述代码首先定义了一个正则表达式模式 r'\d+\.\d+',该模式匹配一个或多个数字后跟一个小数点,然后是一个或多个数字。然后,使用 re.findall() 函数来查找并提取匹配的浮点数,并将结果存储在 matches 列表中。在这个示例中,matches 列表将包含提取的三个浮点数。

输出示例:

1
Matches: ['1.1', '1.2', '1.3']

python3 获取系统时间 秒数

要获取当前系统时间的秒数,你可以使用 time 模块的 time() 函数,它返回自 1970 年 1 月 1 日以来的秒数(称为时间戳)。以下是如何获取系统时间的秒数的示例:

1
2
3
4
5
6
7
import time

# 获取当前系统时间的秒数
current_time_seconds = time.time()

# 打印当前时间的秒数
print("当前系统时间的秒数:", current_time_seconds)

这段代码导入 time 模块,然后使用 time.time() 函数来获取当前系统时间的秒数,并将其存储在 current_time_seconds 变量中。最后,它打印出当前时间的秒数,这是一个浮点数,表示自 1970 年 1 月 1 日以来的秒数,通常被称为 Unix 时间戳。

python3 接收用户输入

在Python 3中,您可以使用input()函数来接收用户的输入。input()函数会等待用户输入文本,然后将用户输入的文本作为字符串返回。您可以将其存储在变量中以后使用或处理。

以下是一个简单的示例:

1
2
user_input = input("请输入一些文本: ")
print("您输入的文本是:", user_input)

运行这段代码时,程序会提示用户输入文本,然后将用户输入的文本打印出来。

请注意,input()函数接收的输入始终被视为字符串。如果您需要将输入解释为其他数据类型(例如整数或浮点数),则需要使用适当的类型转换函数,例如int()float()。例如:

1
2
3
4
5
6
user_input = input("请输入一个整数: ")
try:
user_input_as_int = int(user_input)
print("您输入的整数是:", user_input_as_int)
except ValueError:
print("无法将输入转换为整数。")

这段代码将尝试将用户输入转换为整数,如果用户输入的不是有效的整数,则会引发ValueError异常。

python3 main函数接收外部参数并解析解析

如果您想要编写一个Python脚本,使其接收外部参数并进行解析,通常的做法是使用sys.argv来访问命令行参数,然后使用argparse或其他方法来解析这些参数。以下是一个示例,演示如何在Python中完成这个任务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
import argparse

def main():
# 创建ArgumentParser对象
parser = argparse.ArgumentParser(description='一个命令行工具示例')

# 添加命令行参数
parser.add_argument('-f', '--file', required=True, help='指定文件名')
parser.add_argument('-n', '--number', type=int, default=1, help='指定一个整数(默认为1)')
parser.add_argument('--flag', action='store_true', help='设置此标志将为True,否则为False')

# 解析命令行参数
args = parser.parse_args()

# 访问解析后的参数
print('文件名:', args.file)
print('整数值:', args.number)
print('标志值:', args.flag)

if __name__ == '__main__':
main()

在这个示例中,我们定义了一个main()函数,它包含参数解析的代码。然后,我们使用if __name__ == '__main__':来确保只有在直接运行脚本时才会执行main()函数,而不是在作为模块导入时执行。

然后,您可以在命令行中运行脚本,并传递参数,就像之前的示例一样:

1
python my_script.py -f myfile.txt -n 5 --flag

这将调用main()函数,解析命令行参数并执行相关操作。

这是一个基本的示例,您可以根据自己的需求扩展main()函数和命令行参数。argparse可以帮助您更灵活地定义和解析参数。

python3 argparse 在python程序内部输出帮助信息

您可以在Python程序内部生成帮助信息,然后将其打印到控制台或保存到文件中,而不需要在命令行中使用-h--help选项。要在程序内部输出帮助信息,您可以使用argparseprint_help()方法。以下是一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import argparse

def main():
# 创建ArgumentParser对象
parser = argparse.ArgumentParser(description='一个命令行工具示例')

# 添加命令行参数
parser.add_argument('-f', '--file', required=True, help='指定文件名', default='default.txt')
parser.add_argument('-n', '--number', type=int, help='指定一个整数', default=1)
parser.add_argument('--flag', action='store_true', help='设置此标志将为True,否则为False', default=False)

# 解析命令行参数
args = parser.parse_args()

# 访问解析后的参数
print('文件名:', args.file)
print('整数值:', args.number)
print('标志值:', args.flag)

# 输出帮助信息
parser.print_help()

if __name__ == '__main__':
main()

在上述示例中,我们在main()函数中使用parser.print_help()来生成帮助信息并将其打印到控制台。当您运行脚本时,它将首先输出解析后的参数值,然后再打印帮助信息。

运行脚本:

1
python my_script.py

这将输出解析后的参数值,然后打印帮助信息,让用户了解如何正确使用脚本。

python3 OpenCV 矩形框的x,y,w,h 画在图像上

在 OpenCV 中,您可以使用 cv2.rectangle 函数来在图像上绘制一个矩形框,指定矩形的左上角坐标 (x, y) 和宽度 w 以及高度 h。以下是一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import cv2
import numpy as np

# 创建一个空白图像
image = np.zeros((400, 400, 3), dtype=np.uint8) # 创建一个 400x400 的黑色图像

# 定义矩形的左上角坐标 (x, y) 和宽度 (w)、高度 (h)
x, y, w, h = 100, 100, 200, 150

# 定义矩形的颜色 (BGR 格式)
color = (0, 255, 0) # 绿色

# 在图像上绘制矩形
cv2.rectangle(image, (x, y), (x + w, y + h), color, thickness=2)

# 显示图像
cv2.imshow('Rectangle', image)

# 等待按下任意键然后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述示例中,我们首先创建了一个空白的黑色图像,然后使用 cv2.rectangle 函数绘制一个绿色的矩形框,指定左上角坐标 (x, y) 和右下角坐标 (x + w, y + h),以及颜色和线条粗细。

您可以根据需要更改矩形的坐标、颜色和图像大小来适应您的需求。这只是一个基本示例,用于演示如何在 OpenCV 中绘制矩形。

python3 OpenCV 接收二进制数据 保存为图片

要使用 Python 3 和 OpenCV 接收二进制数据并将其保存为图像,您可以按照以下步骤进行操作:

  1. 导入必要的库:
1
2
import cv2
import numpy as np
  1. 接收二进制数据并将其转换为 NumPy 数组。假设您已经从某个地方(例如网络、文件等)接收到了二进制数据,您可以将其转换为 NumPy 数组:
1
2
3
4
5
6
# 假设 binary_data 是包含二进制图像数据的变量
# 请替换为您自己的方式来获取二进制数据
binary_data = b'\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49...'

# 将二进制数据转换为 NumPy 数组
image_data = np.frombuffer(binary_data, np.uint8)
  1. 解码图像数据为 OpenCV 图像对象:
1
2
# 解码二进制数据为图像对象
image = cv2.imdecode(image_data, cv2.IMREAD_COLOR)

上述代码假设您接收的二进制数据是JPEG格式的图像。如果数据是其他图像格式,您可能需要调整 cv2.imdecode 的参数。

  1. 保存图像到文件:
1
2
# 保存图像到文件
cv2.imwrite('output_image.jpg', image)

现在,您已经成功将接收的二进制数据保存为图像文件。请确保提供正确的图像文件路径和名称。

整个代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import cv2
import numpy as np

# 假设 binary_data 是包含二进制图像数据的变量
# 请替换为您自己的方式来获取二进制数据
binary_data = b'\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49...'

# 将二进制数据转换为 NumPy 数组
image_data = np.frombuffer(binary_data, np.uint8)

# 解码二进制数据为图像对象
image = cv2.imdecode(image_data, cv2.IMREAD_COLOR)

# 保存图像到文件
cv2.imwrite('output_image.jpg', image)

请注意,这只是一个简单的示例,假设您已经获取了包含二进制数据的变量。在实际应用中,您可能需要使用适当的方法来获取二进制数据,例如通过网络请求、文件读取等。

python3 将二进制数据写入文件 示例 详解

在Python 3中,将二进制数据写入文件是一种常见的操作,通常用于保存图像、音频、视频文件以及其他二进制数据。以下是一个示例,演示了如何将二进制数据写入文件以及相关的详细解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 要写入文件的二进制数据
binary_data = b'\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21'

# 打开文件以二进制写入模式('wb'表示二进制写入,如果文件不存在则创建,如果文件已存在则覆盖)
# 您可以指定文件路径和名称
file_path = "binary_data.bin"

# 使用with语句打开文件,以确保在完成写入后关闭文件
with open(file_path, 'wb') as file:
# 将二进制数据写入文件
file.write(binary_data)

# 文件现在已经写入,可以关闭

print(f"二进制数据已写入文件 {file_path}")

上述示例中的关键点包括:

  1. 定义要写入文件的二进制数据binary_data。这是一个包含十六进制值的字节序列,代表了字符串”Hello, World!”的ASCII编码。

  2. 使用open函数以二进制写入模式(’wb’)打开文件。在二进制写入模式下,文件以字节为单位进行写入,而不是以文本字符为单位。

  3. 使用with语句打开文件,以确保在完成写入后自动关闭文件。这有助于防止资源泄漏。

  4. 使用file.write()方法将二进制数据写入文件。

  5. 最后,关闭文件,以确保操作的安全性。

文件binary_data.bin现在包含了指定的二进制数据。您可以根据需要修改binary_data变量以及文件路径和名称来适应您的实际需求。这种方法适用于将任何二进制数据写入文件。

python3 base64 编解码 工具 详解

Base64 是一种二进制数据编码的方式,通常用于将二进制数据转换成可打印字符,以便在不损失数据的情况下进行传输和存储。Python 提供了内置的 base64 模块,可以用来进行 Base64 编码和解码操作。下面是关于 Python3 中 base64 模块的详细解释和示例:

Base64 编码

Base64 编码将二进制数据转换为可打印字符。可以使用 base64 模块的 b64encode 函数来执行编码操作。

1
2
3
4
5
6
7
8
9
10
11
12
import base64

# 要编码的二进制数据
binary_data = b'Hello, World!'

# 进行 Base64 编码
encoded_data = base64.b64encode(binary_data)

# 将编码后的数据转换为字符串
encoded_string = encoded_data.decode('utf-8')

print(encoded_string)

Base64 解码

Base64 解码将 Base64 编码的字符串重新转换回原始的二进制数据。可以使用 base64 模块的 b64decode 函数来执行解码操作。

1
2
3
4
5
6
7
8
9
10
import base64

# Base64 编码后的字符串
encoded_string = 'SGVsbG8sIFdvcmxkIQ=='

# 进行 Base64 解码
decoded_data = base64.b64decode(encoded_string)

# 打印解码后的二进制数据
print(decoded_data)

URL 安全的 Base64 编解码

有时候,Base64 编码后的字符串需要在 URL 中传输,但标准的 Base64 编码字符串中包含一些特殊字符(如+/)可能会引起问题。为了解决这个问题,可以使用 base64 模块的 urlsafe_b64encodeurlsafe_b64decode 函数,它们会将+/字符替换为-_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import base64

# 要编码的二进制数据
binary_data = b'Hello, World!'

# 进行 URL 安全的 Base64 编码
urlsafe_encoded_data = base64.urlsafe_b64encode(binary_data)

# 将编码后的数据转换为字符串
urlsafe_encoded_string = urlsafe_encoded_data.decode('utf-8')

print(urlsafe_encoded_string)

# 进行 URL 安全的 Base64 解码
decoded_data = base64.urlsafe_b64decode(urlsafe_encoded_string)

# 打印解码后的二进制数据
print(decoded_data)

这就是使用 Python3 中的 base64 模块进行 Base64 编码和解码的基本操作。请注意,在进行编码和解码操作时,要确保输入的数据类型是字节序列(bytes)。

python3 将字符串写入文件

要将字符串写入文件,您可以使用Python的内置文件操作功能。以下是一个简单的示例,演示如何将字符串写入文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 要写入的字符串
my_string = "这是要写入文件的字符串。"

# 打开文件以写入模式('w'表示写入,如果文件不存在则创建,如果文件已存在则覆盖)
# 您可以指定文件路径和名称
file_path = "my_file.txt"

# 使用with语句打开文件,以确保在完成写入后关闭文件
with open(file_path, 'w') as file:
# 将字符串写入文件
file.write(my_string)

# 文件现在已经写入,可以关闭

print(f"字符串已写入文件 {file_path}")

在这个示例中,我们首先定义要写入文件的字符串my_string,然后使用open函数打开文件以供写入(使用'w'模式)。然后,我们使用with语句来确保在完成写入后关闭文件,以避免资源泄漏。最后,我们使用file.write()方法将字符串写入文件,然后关闭文件。

注意:如果指定的文件路径已经存在一个文件,使用'w'模式会覆盖文件的内容。如果不想覆盖文件,可以使用'a'模式以附加方式写入。

python 将数据写入到文件

在 Python 中,可以使用内置的文件操作方法将数据写入文件。以下是常见的方式和示例:


基本写入

使用 open() 函数以写模式 (w) 打开文件,并使用 write() 方法写入数据。

1
2
3
4
5
6
# 写入文本数据
with open("example.txt", "w") as file:
file.write("Hello, World!\n")
file.write("This is a new line of text.\n")

print("Data has been written to example.txt.")

注意

  • 模式 "w" 会覆盖文件内容。如果文件不存在,会创建新文件。
  • 如果需要追加数据,请使用模式 "a"

写入多行数据

可以使用 writelines() 方法将一个字符串列表写入文件,每个字符串表示一行。

1
2
3
4
5
6
# 写入多行数据
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open("example.txt", "w") as file:
file.writelines(lines)

print("Multiple lines have been written to example.txt.")

追加写入

如果需要在现有文件末尾追加数据,可以使用模式 "a"

1
2
3
4
5
# 追加数据
with open("example.txt", "a") as file:
file.write("This line is appended.\n")

print("Data has been appended to example.txt.")

写入二进制数据

对于二进制数据(如图片或音频),使用模式 "wb"

1
2
3
4
5
6
# 写入二进制数据
binary_data = b"Hello, binary world!"
with open("example.bin", "wb") as file:
file.write(binary_data)

print("Binary data has been written to example.bin.")

错误处理

使用 try...except 块可以更安全地处理文件操作异常。

1
2
3
4
5
6
7
try:
with open("example.txt", "w") as file:
file.write("Safe write operation.")
except IOError as e:
print(f"An error occurred: {e}")
else:
print("Data successfully written.")

总结

  • 使用模式 "w" 写入新文件或覆盖文件。
  • 使用模式 "a" 追加内容。
  • 对于多行数据,writelines() 是便利的方法。
  • 使用二进制模式处理非文本文件。

如果有特定的需求(例如写入 JSON、CSV 或其他格式的数据),可以告诉我,我会提供相应的示例!

python3 启动新的线程

在 Python 3 中,您可以使用 threading 模块来启动新的线程。以下是一个简单的示例,演示如何创建和启动一个新线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading

# 定义一个简单的函数,作为新线程的任务
def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")

# 创建一个新线程并指定要运行的函数
new_thread = threading.Thread(target=print_numbers)

# 启动新线程
new_thread.start()

# 主线程继续执行其他任务
for letter in 'abcde':
print(f"Letter: {letter}")

在这个示例中,我们首先导入 threading 模块。然后,我们定义了一个名为 print_numbers 的函数,它将在新线程中运行,简单地打印数字 1 到 5。接下来,我们使用 threading.Thread 类创建一个新线程,将 print_numbers 函数作为目标(target)传递给新线程。最后,我们通过调用 start() 方法启动新线程,它将在后台运行。

主线程继续执行其他任务,因此您会看到数字和字母的输出交替出现,表明新线程和主线程在并发执行。

请注意,线程是轻量级的执行单元,可以同时运行多个线程,但需要谨慎处理线程之间的共享数据和同步问题,以避免竞争条件和其他线程相关的问题。在复杂的多线程应用程序中,确保线程安全性非常重要。如果需要更多的线程控制和同步,Python 3 还提供了 threading 模块中的各种工具。

python 解析JSON文件

在Python中解析JSON文件通常是一个非常常见的任务,你可以使用内置的json模块来完成这个任务。以下是一个基本的JSON文件解析示例:

假设你有一个名为data.json的JSON文件,内容如下:

1
2
3
4
5
{
"name": "John",
"age": 30,
"city": "New York"
}

你可以使用以下代码来解析这个JSON文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import json

# 打开JSON文件并读取数据
with open('data.json', 'r') as file:
data = json.load(file)

# 访问JSON中的数据
name = data['name']
age = data['age']
city = data['city']

# 打印解析后的数据
print(f"Name: {name}")
print(f"Age: {age}")
print(f"City: {city}")

运行这段代码将会读取data.json文件并将其解析为Python字典对象。然后你可以像访问字典一样访问其中的数据。

如果你要解析的JSON文件包含一个JSON数组,你可以使用json.load()来解析整个数组,然后在Python中进一步处理。例如:

假设你有一个名为data.json的JSON文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
[
{
"name": "John",
"age": 30,
"city": "New York"
},
{
"name": "Alice",
"age": 25,
"city": "Los Angeles"
}
]

你可以使用以下代码来解析包含多个对象的JSON数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import json

# 打开JSON文件并读取数据
with open('data.json', 'r') as file:
data = json.load(file)

# 遍历JSON数组中的对象
for person in data:
name = person['name']
age = person['age']
city = person['city']

print(f"Name: {name}")
print(f"Age: {age}")
print(f"City: {city}")

这将会遍历JSON数组中的每个对象,并分别访问它们的属性。

python3 发送网络请求

在Python 3中,你可以使用标准库中的requests模块来发送网络请求。以下是一些示例,展示如何发送不同类型的网络请求:

1. 发送HTTP GET请求:

1
2
3
4
5
6
7
8
9
10
11
import requests

# 发送GET请求
response = requests.get('https://www.example.com')

# 检查响应状态码
if response.status_code == 200:
print('请求成功')
print(response.text) # 打印响应内容
else:
print(f'请求失败,状态码:{response.status_code}')

上述代码发送一个HTTP GET请求到https://www.example.com,并打印响应内容。

2. 发送HTTP POST请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests

# POST请求的数据
data = {'key1': 'value1', 'key2': 'value2'}

# 发送POST请求
response = requests.post('https://www.example.com/api', data=data)

# 检查响应状态码
if response.status_code == 200:
print('请求成功')
print(response.text) # 打印响应内容
else:
print(f'请求失败,状态码:{response.status_code}')

上述代码发送一个HTTP POST请求到https://www.example.com/api,并附带数据作为表单数据发送。

3. 发送HTTP请求并处理JSON响应:

1
2
3
4
5
6
7
8
9
10
11
12
import requests

# 发送GET请求
response = requests.get('https://api.example.com/data')

# 检查响应状态码
if response.status_code == 200:
print('请求成功')
json_data = response.json() # 将JSON响应解析为Python字典或列表
print(json_data)
else:
print(f'请求失败,状态码:{response.status_code}')

上述代码发送一个HTTP GET请求,然后使用.json()方法将JSON响应解析为Python数据结构。

以上是使用requests库发送HTTP请求的基本示例。在实际应用中,你还可以添加请求头、处理异常、处理重定向、使用认证等高级功能,具体取决于你的需求。确保在使用requests模块时,你已经安装了它,你可以使用pip来安装它:

1
pip install requests

python3 通过POST请求发送JSON数据

你可以使用Python 3中的requests库发送POST请求并附加JSON数据。以下是一个示例,展示如何发送带有JSON数据的POST请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
import json

# 定义要发送的JSON数据
data = {
"name": "John",
"age": 30,
"city": "New York"
}

# 将JSON数据转换为字符串
json_data = json.dumps(data)

# 设置请求头,指明发送的数据是JSON格式
headers = {'Content-Type': 'application/json'}

# 发送POST请求
response = requests.post('https://www.example.com/api', data=json_data, headers=headers)

# 检查响应状态码
if response.status_code == 200:
print('请求成功')
print(response.text) # 打印响应内容
else:
print(f'请求失败,状态码:{response.status_code}')

上述代码首先将Python字典转换为JSON格式的字符串,然后设置请求头以指明发送的数据是JSON格式。接下来,它使用requests.post方法发送POST请求到https://www.example.com/api,并附带JSON数据作为请求正文。

确保替换URL为你要发送请求的目标URL,以及替换data变量中的JSON数据为你要发送的实际数据。这样,你就可以通过POST请求发送JSON数据了。

python3 解析JSON 判断字段类型 遍历数组

要解析JSON并根据字段类型进行判断以及遍历JSON数组,你可以使用Python 3的json模块来解析JSON数据,然后根据需要进行类型检查和遍历。以下是一个示例:

假设你有一个JSON文件data.json,其中包含一个JSON数组,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[
{
"name": "John",
"age": 30,
"city": "New York"
},
{
"name": "Alice",
"age": null,
"city": "Los Angeles"
},
{
"name": "Bob",
"age": "25",
"city": "Chicago"
}
]

你可以使用以下Python 3代码来解析JSON,检查字段类型并遍历数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import json

# 打开JSON文件并读取数据
with open('data.json', 'r') as file:
data = json.load(file)

# 遍历JSON数组中的对象
for person in data:
name = person['name']
age = person['age']
city = person['city']

# 检查字段类型
if isinstance(age, int):
age_str = str(age) # 将年龄转换为字符串
age_type = 'int'
elif age is None:
age_str = 'N/A' # 如果年龄字段为null,则将其标记为N/A
age_type = 'null'
elif isinstance(age, str):
age_str = age
age_type = 'string'
else:
age_str = 'Unknown'
age_type = 'unknown'

# 打印信息
print(f"Name: {name}")
print(f"Age: {age_str} (Type: {age_type})")
print(f"City: {city}")
print()

上述代码会遍历JSON数组中的每个对象,并检查年龄字段的类型。根据字段类型,它会打印相应的信息。

这个示例中,我们假设年龄字段可能是整数、字符串、null或其他未知类型,然后根据实际类型执行相应的操作。你可以根据自己的JSON数据结构和字段类型进行适当的调整。

简介

  • OpenCV 常见类,函数

OpenCV cv::flip() 函数 详解

cv::flip() 函数是 OpenCV 库中的一个函数,用于执行图像的翻转操作。该函数可以在水平、垂直或两个方向上翻转图像。下面是对 cv::flip() 函数的详解:

函数原型

1
2
3
4
5
void cv::flip(
InputArray src,
OutputArray dst,
int flipCode
)

参数说明

  • src:输入图像。
  • dst:输出图像,翻转后的结果将存储在这里。
  • flipCode:翻转操作的类型。可以是以下几种值之一:
    • 0:沿 x 轴翻转(垂直翻转)。
    • 1:沿 y 轴翻转(水平翻转)。
    • -1:同时沿 x 轴和 y 轴翻转。

功能

cv::flip() 函数用于对输入图像进行翻转操作。翻转操作可以是水平翻转、垂直翻转或同时在水平和垂直方向上进行翻转。翻转后的结果将存储在输出图像 dst 中。

注意事项

  • 输入图像和输出图像的尺寸和数据类型相同。
  • 如果需要在原地进行翻转操作(即输入图像和输出图像是同一个),可以将 srcdst 设置为相同的图像。

示例

1
2
3
4
5
6
cv::Mat src = cv::imread("input.jpg", cv::IMREAD_COLOR);
cv::Mat flippedImage;
cv::flip(src, flippedImage, 1); // 水平翻转

// 如果需要原地翻转,可以将 src 和 dst 设置为相同的图像
// cv::flip(src, src, 1);

在这个示例中,src 是一个输入的图像,通过 cv::flip() 函数将其进行水平翻转,翻转后的结果存储在 flippedImage 中。

cv::flip() 函数是 OpenCV 中用于执行图像翻转操作的常用函数之一,它在图像处理中广泛用于数据增强、镜像反射等应用场景。

OpenCV cv::findChessboardCorners() 函数 详解

cv::findChessboardCorners() 是 OpenCV(开源计算机视觉库)中的一个函数,用于在图像中找到棋盘格图案的内部角点。这个函数通常用于摄像机校准和计算机视觉应用,以确定棋盘格校准图案的角点位置,这对于摄像机校准非常重要。

以下是对 cv::findChessboardCorners() 函数的详细解释:

1
2
3
4
5
6
bool cv::findChessboardCorners(
InputArray image, // 包含棋盘格图案的输入图像。
Size patternSize, // 棋盘格图案的大小(内部角点的数量)。
OutputArray corners, // 存储找到的角点的输出向量。
int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
)

参数:

  1. image:这是要在其中查找棋盘格角点的输入图像。通常应该是灰度图像,但也可以是彩色图像。

  2. patternSize:此参数指定了棋盘格图案的大小。它应该是一个 Size 对象,包含了棋盘格图案的行和列上的内部角点数量。

  3. corners:这是一个输出参数,函数会将找到的角点位置存储在其中。通常是一个包含2D点的向量(例如 std::vector<cv::Point2f>)。

  4. flags:可选参数,可用于指定各种操作标志。默认标志(CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE)适用于大多数情况。这些标志控制函数如何处理图像。

返回值:
如果成功找到棋盘格角点,则函数返回 true,否则返回 false

cv::findChessboardCorners() 的工作原理:

  1. 该函数分析输入图像以检测棋盘格图案的内部角点。

  2. 它使用自适应阈值技术对图像进行二值化并查找角点。

  3. 找到角点后,它将它们存储在corners 输出向量中。

  4. patternSize 参数帮助函数确定棋盘格图案的期望大小和布局,从而更容易找到角点。

用法:
通常,您将在摄像机校准过程的一部分中使用此函数,其中您从不同角度和距离捕获棋盘格图案的多幅图像。通过在这些图像中找到角点,您可以计算摄像机的内部和外部参数。

以下是如何使用 cv::findChessboardCorners() 的基本示例:

1
2
3
4
5
6
7
8
9
cv::Mat image = cv::imread("chessboard.png", cv::IMREAD_GRAYSCALE);
cv::Size patternSize(7, 7); // 指定棋盘格图案的大小。
std::vector<cv::Point2f> corners;
bool found = cv::findChessboardCorners(image, patternSize, corners);
if (found) {
// 找到了角点,可以继续进行摄像机校准。
} else {
// 未在图像中找到角点。
}

这个函数是摄像机校准的关键步骤,通常用于需要准确了解摄像机参数的计算机视觉应用中。

C++ OpenCV cv::ellipse() 函数 详解

cv::ellipse() 函数是OpenCV中用于绘制椭圆的函数。它允许您在图像上绘制椭圆,可以用于标记或可视化图像中的对象或区域。以下是cv::ellipse()函数的详解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void cv::ellipse(
InputOutputArray img, // 输出图像
Point center, // 椭圆的中心坐标
Size axes, // 长轴和短轴的大小
double angle, // 旋转角度(以度为单位)
double startAngle, // 开始角度(以度为单位)
double endAngle, // 结束角度(以度为单位)
const Scalar& color, // 椭圆的颜色(BGR格式)
int thickness = 1, // 边框线宽
int lineType = LINE_8, // 线的类型
int shift = 0 // 点坐标的小数位数
);`cv::findChessboardCorners()` 是 OpenCV 中用于检测棋盘格角点的函数。这个函数主要用于摄像机标定和校正。下面是有关 `cv::findChessboardCorners()` 函数的详细解释:

```cpp
bool cv::findChessboardCorners(const cv::Mat& image, cv::Size patternSize, cv::OutputArray corners, int flags = cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE)

参数解释:

  • image:输入的图像,通常是拍摄的包含了棋盘格的图像。
  • patternSize:一个 cv::Size 对象,指定了棋盘格的内部角点的行和列数,通常为 (num_cols, num_rows)
  • corners:用于输出检测到的角点坐标的 cv::OutputArray。这是一个包含检测到的角点的 2D 坐标的向量。
  • flags:可选参数,用于指定不同的标志位以控制检测的方式。常用的标志包括:
    • cv::CALIB_CB_ADAPTIVE_THRESH:使用自适应阈值方法。
    • cv::CALIB_CB_NORMALIZE_IMAGE:在角点检测之前归一化图像。
    • cv::CALIB_CB_FAST_CHECK:执行快速检查以排除不合格的图像。

返回值:

  • 如果成功检测到棋盘格角点,函数返回 true,否则返回 false

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cv::Mat image = cv::imread("chessboard.jpg");
cv::Size patternSize(7, 6); // 棋盘格的列数和行数
cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);

std::vector<cv::Point2f> corners;
bool found = cv::findChessboardCorners(grayImage, patternSize, corners);

if (found) {
// 在图像上绘制角点
cv::drawChessboardCorners(image, patternSize, cv::Mat(corners), found);
cv::imshow("Chessboard Corners", image);
cv::waitKey(0);
}

cv::findChessboardCorners() 函数的主要用途是用于相机标定,以便校正图像畸变。检测到的角点可以用于计算相机的内部和外部参数,以及图像的校正和畸变校正。通常,使用棋盘格图像进行标定是摄影测量和计算机视觉中的一个重要步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

参数说明:

- `img`:输入输出图像,您可以在其上绘制椭圆。

- `center`:椭圆的中心坐标,通常表示为`cv::Point`对象。

- `axes`:一个`cv::Size`对象,表示椭圆的长轴和短轴的大小。

- `angle`:椭圆的旋转角度,以度为单位。正值表示顺时针旋转,负值表示逆时针旋转。

- `startAngle`:起始角度,以度为单位。椭圆将从这个角度开始绘制。

- `endAngle`:结束角度,以度为单位。椭圆将绘制到这个角度。

- `color`:椭圆的颜色,通常表示为`cv::Scalar`对象,使用BGR颜色格式。

- `thickness`:椭圆的边框线宽,默认为1。

- `lineType`:线的类型,可以是`LINE_4`、`LINE_8`或`LINE_AA`中的一个,分别表示4-连通、8-连通和抗锯齿线。

- `shift`:点坐标的小数位数,通常为0。

示例用法:

```cpp
#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
Mat image(400, 400, CV_8UC3, Scalar(255, 255, 255)); // 创建白色背景图像

Point center(200, 200);
Size axes(100, 50);
double angle = 30;
double startAngle = 0;
double endAngle = 360;
Scalar color(0, 0, 255); // 蓝色

ellipse(image, center, axes, angle, startAngle, endAngle, color, 2);

imshow("Ellipse", image);
waitKey(0);

return 0;
}

上述示例创建了一个400x400的白色背景图像,在其中绘制了一个蓝色的椭圆。您可以根据需要调整参数以满足您的绘制需求。

Mat operator()( const Rect& roi ) const 详解

cv::Mat 类中的 operator()(const Rect& roi) const 是一个用于提取感兴趣区域(Region of Interest,ROI)的运算符重载。它允许你根据给定的矩形区域来创建一个新的 cv::Mat 对象,其中包含了原始图像中该矩形区域的像素数据。以下是这个运算符重载的详细解释:

1
cv::Mat cv::Mat::operator()(const cv::Rect& roi) const;

参数说明:

  • roi:一个 cv::Rect 对象,表示感兴趣区域的位置和大小。

运算符重载的返回值是一个新的 cv::Mat 对象,其中包含了原始图像中指定感兴趣区域的像素数据。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <opencv2/opencv.hpp>

int main() {
// 读取图像
cv::Mat image = cv::imread("image.jpg");

// 定义感兴趣区域的矩形
cv::Rect roiRect(100, 100, 200, 150); // (x, y, width, height)

// 使用运算符重载提取感兴趣区域
cv::Mat roi = image(roiRect);

// 显示感兴趣区域
cv::imshow("感兴趣区域", roi);
cv::waitKey(0);

return 0;
}

在上述示例中,我们首先读取了一张图像,然后定义了一个 cv::Rect 对象 roiRect,表示感兴趣区域的位置和大小。接着,我们使用运算符重载 image(roiRect) 来提取图像中指定的感兴趣区域,并将其存储在 roi 中。最后,我们显示了这个感兴趣区域。这个运算符重载使得提取感兴趣区域变得非常方便,可以快速获取图像的子区域进行进一步处理。

cv::Mat::setTo() 函数 详解

cv::Mat::setTo() 函数用于将图像中的所有像素设置为指定的值或颜色。这个函数非常有用,可以用来创建具有特定像素值的图像,或者将图像的所有像素设置为某个常数值。以下是 cv::Mat::setTo() 函数的详解:

1
void cv::Mat::setTo(const Scalar& value, const Mat& mask = Mat());

参数说明:

  • value:要设置的像素值,通常是一个 cv::Scalar 对象,表示图像的颜色或强度。例如,如果你想将图像设置为纯黑色,可以使用 cv::Scalar(0, 0, 0)
  • mask:可选参数,一个与输入图像相同大小的掩码图像,用于指定哪些像素应该被设置为指定的值。只有在掩码图像中对应的像素值为非零时,对应的目标图像像素才会被设置。默认情况下,没有掩码。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <opencv2/opencv.hpp>

int main() {
// 创建一个空的图像
cv::Mat image(300, 400, CV_8UC3); // 3通道,8位无符号整数类型

// 设置整个图像为纯蓝色
cv::Scalar blueColor(255, 0, 0);
image.setTo(blueColor);

// 创建一个掩码图像,只有图像中心部分的像素会被修改
cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1);
cv::Rect roiRect(100, 100, 200, 100);
mask(roiRect) = 255; // 将中心区域的掩码设置为255

// 使用掩码将中心部分设置为绿色
cv::Scalar greenColor(0, 255, 0);
image.setTo(greenColor, mask);

// 显示图像
cv::imshow("图像", image);
cv::waitKey(0);

return 0;
}

在上述示例中,我们首先创建了一个空的彩色图像,然后使用 setTo() 函数将整个图像设置为纯蓝色。接下来,我们创建了一个掩码图像,只有中心区域的像素才会被修改。最后,我们使用掩码将中心部分的像素设置为绿色。这是一个简单示例,演示了如何使用 cv::Mat::setTo() 函数来设置图像的像素值。

cv::resize() 函数 详解

cv::resize() 函数用于调整图像或图像区域的大小。你可以使用它来缩小或放大图像,或者将图像裁剪到指定的尺寸。以下是 cv::resize() 函数的详解:

1
2
3
4
5
6
7
8
void cv::resize(
InputArray src, // 输入图像,可以是 cv::Mat 或其他图像数据结构
OutputArray dst, // 输出图像,可以是 cv::Mat 或其他图像数据结构
Size dsize, // 目标图像的大小,指定为 cv::Size(width, height)
double fx = 0, // 沿水平轴的缩放因子
double fy = 0, // 沿垂直轴的缩放因子
int interpolation = INTER_LINEAR // 插值方法,可选,默认为线性插值
);

参数说明:

  • src:输入图像,可以是 cv::Mat 或其他支持的图像数据结构。
  • dst:输出图像,可以是 cv::Mat 或其他支持的图像数据结构。它将包含调整大小后的图像。
  • dsize:目标图像的大小,以 cv::Size 对象表示,指定为目标宽度和高度。
  • fx:沿水平轴的缩放因子。如果为0,则根据垂直缩放因子 fy 来确定输出大小。
  • fy:沿垂直轴的缩放因子。如果为0,则根据水平缩放因子 fx 来确定输出大小。
  • interpolation:插值方法,用于在调整大小时估算像素值。可以选择以下插值方法之一:
    • INTER_NEAREST:最近邻插值(速度最快,但质量较差)
    • INTER_LINEAR:双线性插值(默认,速度适中,质量较好)
    • INTER_CUBIC:双三次插值(速度较慢,质量较好)
    • INTER_LANCZOS4:Lanczos插值(速度较慢,质量最好)

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <opencv2/opencv.hpp>

int main() {
// 读取图像
cv::Mat image = cv::imread("image.jpg");

// 指定目标大小
cv::Size targetSize(200, 150);

// 调整图像大小
cv::Mat resizedImage;
cv::resize(image, resizedImage, targetSize, 0, 0, cv::INTER_LINEAR);

// 显示原始图像和调整大小后的图像
cv::imshow("原始图像", image);
cv::imshow("调整大小后的图像", resizedImage);
cv::waitKey(0);

return 0;
}

上述示例将读取一张图像,将其调整为指定的目标大小,然后显示原始图像和调整大小后的图像。你可以根据需要选择不同的插值方法和目标大小。

cv::convexHull

在 OpenCV 中,cv::convexHull() 函数用于计算一个给定点集的凸包。凸包是包含给定点集中所有点的最小凸多边形。以下是关于 cv::convexHull() 函数的详细解释:

函数签名

1
cv::convexHull(InputArray points, OutputArray hull, bool clockwise = false, bool returnPoints = true)

参数

  • points:输入的点集,可以是 cv::Matcv::Mat_<T>cv::vector<Point> 等。
  • hull:计算出的凸包点集。
  • clockwise:指定计算的凸包是否按逆时针方向排列。
  • returnPoints:如果为 true,函数将返回凸包的点集;如果为 false,函数将返回凸包的索引。

返回值

  • 函数没有返回值。凸包的点集或索引存储在 hull 参数中。

示例
以下示例演示了如何使用 cv::convexHull() 函数计算一组点的凸包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <opencv2/opencv.hpp>

using namespace cv;

int main() {
std::vector<Point2f> points;
points.push_back(Point2f(100, 100));
points.push_back(Point2f(300, 100));
points.push_back(Point2f(300, 200));
points.push_back(Point2f(100, 200));

std::vector<Point2f> hull;
convexHull(points, hull);

Mat image = Mat::zeros(300, 400, CV_8UC3);
for (const Point2f& p : points) {
circle(image, p, 5, Scalar(0, 0, 255), -1); // 绘制红色点
}

for (size_t i = 0; i < hull.size(); i++) {
line(image, hull[i], hull[(i + 1) % hull.size()], Scalar(255, 0, 0), 2); // 绘制蓝色凸包边界
}

imshow("Convex Hull", image);
waitKey(0);

return 0;
}

在上述示例中,我们创建了一个点集 points,并使用 convexHull() 函数计算了这些点的凸包。然后,我们使用绘图函数绘制了原始点和凸包的边界。

运行示例代码后,你将在窗口中看到原始点和计算出的凸包。你可以根据需要调整点的坐标,了解函数的不同参数和用法,以适应你的实际需求。

cv::RotatedRect::points() 函数 详解

cv::RotatedRect::points() 是 OpenCV 中 cv::RotatedRect 类的一个成员函数,用于获取旋转矩形的四个顶点坐标。以下是对 cv::RotatedRect::points() 函数的详细解释:

函数原型:

1
void cv::RotatedRect::points(cv::Point2f pts[]) const

函数功能:
cv::RotatedRect::points() 函数用于获取一个旋转矩形的四个顶点坐标,并将这些坐标存储在提供的数组 pts 中。旋转矩形是由中心点、宽度、高度和旋转角度定义的,它可以是在任意角度下旋转的矩形。

参数:

  • pts:一个大小为4的 cv::Point2f 数组,用于存储旋转矩形的四个顶点坐标。数组应该在调用函数之前分配好空间。

返回值:
函数没有返回值,它直接将四个顶点的坐标存储在提供的数组 pts 中。

示例用法:
以下是一个使用 cv::RotatedRect::points() 函数的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <opencv2/opencv.hpp>

int main() {
cv::Point2f points[4]; // 存储顶点坐标的数组
cv::RotatedRect rotatedRect(cv::Point2f(100, 100), cv::Size2f(200, 100), 30); // 创建一个旋转矩形

rotatedRect.points(points); // 获取旋转矩形的顶点坐标

for (int i = 0; i < 4; ++i) {
std::cout << "Point " << i + 1 << ": (" << points[i].x << ", " << points[i].y << ")" << std::endl;
}

return 0;
}

在上面的示例中,我们首先创建了一个 cv::RotatedRect 对象,然后使用 cv::RotatedRect::points() 函数获取了该旋转矩形的四个顶点坐标。最后,我们遍历数组 points,输出每个顶点的坐标。

总之,cv::RotatedRect::points() 函数是一个方便的函数,用于获取旋转矩形的四个顶点坐标,这对于后续的绘制和分析操作非常有用。

cv::Size2i::area() 函数 详解

cv::Size2i是OpenCV中用于表示二维大小的类,其中cv::Size2i::area()是一个成员函数,用于计算这个二维大小的面积。以下是对cv::Size2i::area()函数的详细解释:

函数原型:

1
int cv::Size2i::area() const

函数功能:
cv::Size2i::area()函数用于计算表示二维大小的cv::Size2i对象的面积。对于cv::Size2i对象,面积等于其宽度(width)乘以高度(height)。

参数:
该函数没有参数,因为它是一个成员函数,作用于cv::Size2i对象本身。

返回值:
函数返回一个整数,表示cv::Size2i对象的面积。

示例用法:
下面是一个使用cv::Size2i::area()函数的示例代码:

1
2
3
4
5
6
7
8
9
10
11
#include <opencv2/opencv.hpp>

int main() {
cv::Size2i size(5, 8); // 创建一个二维大小为(5, 8)的对象
int area = size.area(); // 计算面积,area = 5 * 8 = 40

std::cout << "Width: " << size.width << ", Height: " << size.height << std::endl;
std::cout << "Area: " << area << std::endl;

return 0;
}

在上面的示例中,我们创建了一个cv::Size2i对象,然后使用cv::Size2i::area()函数计算了其面积。面积的计算结果是对象的宽度和高度的乘积。

总而言之,cv::Size2i::area()函数是OpenCV中用于计算cv::Size2i对象面积的方便函数,它直接返回对象宽度和高度的乘积。

cv::fillPoly() 函数 详解

cv::fillPoly() 函数是 OpenCV 库中的一个函数,用于在图像上填充指定的多边形区域。

以下是关于 cv::fillPoly() 函数的详细解释:

  • 函数签名:函数的签名如下:

    1
    2
    3
    4
    5
    6
    7
    void cv::fillPoly(
    InputOutputArray img,
    InputArrayOfArrays pts,
    const Scalar &color,
    int lineType = LINE_8,
    int shift = 0,
    Point offset = Point());
  • 参数

    • img:要填充的图像。
    • pts:多边形的顶点集合,可以是一个包含 cv::Pointstd::vector,也可以是 cv::Mat
    • color:填充的颜色,类型为 cv::Scalar,表示 BGR 通道的颜色值。
    • lineType:线段的类型,默认为 LINE_8,表示8连通线段。
    • shift:坐标的小数部分位数,默认为0。
    • offset:坐标的偏移,默认为 Point()
  • 功能

    • 该函数用于在图像上填充一个或多个多边形区域,根据给定的多边形顶点集合和颜色进行填充。
    • 填充的多边形可以是简单多边形,也可以是包含洞的多边形。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    cv::Mat image(300, 300, CV_8UC3, cv::Scalar(0, 0, 0));

    std::vector<cv::Point> polygon;
    polygon.push_back(cv::Point(50, 50));
    polygon.push_back(cv::Point(150, 50));
    polygon.push_back(cv::Point(150, 150));
    polygon.push_back(cv::Point(50, 150));

    std::vector<std::vector<cv::Point>> polygons;
    polygons.push_back(polygon);

    cv::fillPoly(image, polygons, cv::Scalar(0, 255, 0));

    cv::imshow("Filled Image", image);
    cv::waitKey(0);
  • 注意事项

    • pts 参数接受一个包含多个多边形的顶点集合,因此你可以一次性填充多个多边形。
    • 该函数会直接在输入图像上进行填充操作,所以确保图像的尺寸和类型与所需操作匹配。

总之,cv::fillPoly() 函数是用于在图像上填充多边形区域的函数。通过提供多边形的顶点集合和填充颜色,你可以在图像中创建各种填充区域,用于可视化和图像处理。

cv::Mat::ptr() 函数 详解

cv::Mat::ptr() 函数是 OpenCV 库中 cv::Mat 类的一个成员函数,用于获取指定行的指针,从而允许对图像或矩阵数据进行低级别的访问和操作。

以下是关于 cv::Mat::ptr() 函数的详细解释:

  • 函数签名:函数的签名如下:

    1
    uchar* cv::Mat::ptr(int i = 0);
  • 参数

    • i:指定要获取指针的行数(默认为0),即行的索引。行索引从0开始。
  • 返回值

    • 返回一个 uchar* 类型的指针,指向指定行的数据。这个指针可以用于低级别的数据访问操作。
  • 功能

    • 该函数用于获取指定行的指针,允许你对图像或矩阵数据进行低级别的访问和操作。通过获取指针,你可以在不使用高级 OpenCV 函数的情况下,直接读取和修改像素值。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    cv::Mat image = cv::imread("image.jpg", cv::IMREAD_COLOR);

    if (!image.empty()) {
    int row = 100;

    uchar* ptr = image.ptr(row);

    for (int col = 0; col < image.cols; ++col) {
    uchar blue = ptr[col * 3]; // Blue channel
    uchar green = ptr[col * 3 + 1]; // Green channel
    uchar red = ptr[col * 3 + 2]; // Red channel
    }
    }
  • 注意事项

    • 通过 cv::Mat::ptr() 获取的指针可以用于访问指定行的像素数据。如果你需要访问其他通道的像素值,你需要根据通道数进行适当的偏移。
    • 注意确保访问的像素在图像范围内,以避免越界访问。

总之,cv::Mat::ptr() 函数是用于获取指定行的指针,从而允许你对图像或矩阵数据进行低级别的访问和操作。这对于一些特定的图像处理任务可能会很有用,但需要小心越界访问。

cv::Mat::ptr() 函数 详解

cv::Mat::ptr<uint16_t>() 函数是 OpenCV 库中 cv::Mat 类的一个成员函数的模板化版本,用于获取指定行的指针,并将指针的数据类型设置为 uint16_t,从而允许对图像或矩阵数据进行低级别的访问和操作,特别适用于 uint16_t 类型的像素数据。

以下是关于 cv::Mat::ptr<uint16_t>() 函数的详细解释:

  • 函数签名:函数的签名如下:

    1
    uint16_t* cv::Mat::ptr<uint16_t>(int i = 0);
  • 参数

    • i:指定要获取指针的行数(默认为0),即行的索引。行索引从0开始。
  • 返回值

    • 返回一个 uint16_t* 类型的指针,指向指定行的数据。这个指针可以用于低级别的数据访问操作。
  • 功能

    • 该函数用于获取指定行的指针,并将指针的数据类型设置为 uint16_t,允许你对图像或矩阵数据进行低级别的访问和操作。通过获取指针,你可以在不使用高级 OpenCV 函数的情况下,直接读取和修改像素值。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    cv::Mat depth_image = cv::imread("depth_image.png", cv::IMREAD_ANYDEPTH);

    if (!depth_image.empty() && depth_image.depth() == CV_16U) {
    int row = 100;

    uint16_t* ptr = depth_image.ptr<uint16_t>(row);

    for (int col = 0; col < depth_image.cols; ++col) {
    uint16_t depth_value = ptr[col];
    }
    }
  • 注意事项

    • 通过 cv::Mat::ptr<uint16_t>() 获取的指针可以用于访问指定行的像素数据,数据类型为 uint16_t。确保图像的深度为 CV_16U,以匹配数据类型。
    • 注意确保访问的像素在图像范围内,以避免越界访问。

总之,cv::Mat::ptr<uint16_t>() 函数是用于获取指定行的指针,并将数据类型设置为 uint16_t,允许你对图像或矩阵数据进行低级别的访问和操作。这对于访问 uint16_t 类型的像素数据非常有用,但需要小心越界访问。

cv::pointPolygonTest() 函数 详解

cv::pointPolygonTest() 函数是 OpenCV 库中的一个函数,用于计算一个点与一个多边形之间的关系,即点相对于多边形的内部、外部还是在多边形的边界上。

以下是关于 cv::pointPolygonTest() 函数的详细解释:

  • 函数签名:函数的签名如下:

    1
    2
    3
    4
    double cv::pointPolygonTest(
    InputArray contour,
    Point2f pt,
    bool measureDist);
  • 参数

    • contour:表示多边形的轮廓的输入数组。可以是一个 std::vector<cv::Point>,也可以是一个 cv::Mat
    • pt:要测试的点的坐标,类型为 cv::Point2f
    • measureDist:一个布尔值,表示是否要计算点到多边形边界的距离。如果为 true,函数将返回点到多边形的距离;如果为 false,函数将只返回点相对于多边形的关系(内部、外部或边界)。
  • 返回值

    • 如果 measureDist 参数为 false,返回值的含义如下:
      • 正数:点在多边形内部。
      • 零:点在多边形的边界上。
      • 负数:点在多边形外部。
    • 如果 measureDist 参数为 true,返回值表示点到多边形边界的有符号距离。距离为正数表示点在多边形内部,为零表示点在多边形边界上,为负数表示点在多边形外部。
  • 功能

    • 该函数用于计算一个点与一个多边形之间的关系。它可以确定点相对于多边形的位置,以及点到多边形边界的距离(可选)。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    std::vector<cv::Point> contour = {cv::Point(50, 50), cv::Point(200, 50), cv::Point(200, 200), cv::Point(50, 200)};
    cv::Point2f point(100, 100);

    double distance = cv::pointPolygonTest(contour, point, true);

    if (distance > 0) {
    std::cout << "Point is inside the polygon." << std::endl;
    } else if (distance == 0) {
    std::cout << "Point is on the polygon boundary." << std::endl;
    } else {
    std::cout << "Point is outside the polygon." << std::endl;
    }
  • 注意事项

    • 如果你只关心点相对于多边形的关系而不需要距离信息,可以将 measureDist 参数设置为 false,以提高性能。
    • 多边形的轮廓必须是闭合的,并且点的坐标应在 floatdouble 类型的范围内。

总之,cv::pointPolygonTest() 函数是用于计算点与多边形之间关系的函数,可以判断点是否在多边形内部、外部或边界上,并可以计算点到多边形边界的距离。

cv::Mat::atcv::Vec3b() 函数 详解

cv::Mat::at<cv::Vec3b>() 函数是 OpenCV 库中 cv::Mat 类的一个成员函数,用于访问图像或矩阵中特定位置的像素值。在这个函数中,cv::Vec3b 是一个表示三通道(BGR 或 RGB)像素值的数据类型。

以下是关于 cv::Mat::at<cv::Vec3b>() 函数的详细解释:

  • 函数签名:函数的签名如下:

    1
    cv::Vec3b& cv::Mat::at<cv::Vec3b>(int row, int col);
  • 参数

    • row:像素所在的行数(y 坐标)。
    • col:像素所在的列数(x 坐标)。
  • 返回值

    • 返回一个引用(cv::Vec3b&)到指定位置的像素值。cv::Vec3b 表示一个三通道的像素,例如 (B, G, R)(R, G, B)
  • 功能

    • 该函数用于访问图像或矩阵中指定位置的像素值。返回的引用允许你读取或修改像素的通道值。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    cv::Mat image = cv::imread("image.jpg");

    if (!image.empty()) {
    int row = 100;
    int col = 150;

    cv::Vec3b pixel = image.at<cv::Vec3b>(row, col);

    uchar blue = pixel[0];
    uchar green = pixel[1];
    uchar red = pixel[2];

    std::cout << "Pixel at (" << col << ", " << row << "): "
    << "B: " << int(blue) << " G: " << int(green) << " R: " << int(red) << std::endl;
    }
  • 注意事项

    • cv::Vec3b 表示三通道像素值,它的索引是 [0][1][2] 分别表示蓝色、绿色和红色通道。但需要注意,OpenCV 中的图像默认使用 BGR 顺序。

总之,cv::Mat::at<cv::Vec3b>() 函数是用于访问图像或矩阵中指定位置的三通道像素值的函数。通过该函数,你可以方便地读取和修改图像的像素值,并进行各种图像处理操作。

cv::circle

在 OpenCV 中,cv::circle 是一个用于在图像上绘制圆的函数。这个函数可以用来绘制一个圆,或者在图像上绘制多个圆。

函数原型如下:

1
void cv::circle(cv::InputOutputArray img, cv::Point center, int radius, const cv::Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);

函数参数解释:

  • img: 输入/输出图像,可以是单通道或多通道图像。
  • center: cv::Point 类型的参数,表示圆心的坐标。
  • radius: 圆的半径。
  • color: 绘制圆的颜色,可以使用 cv::Scalar 类来表示颜色。
  • thickness: 圆边界的宽度(线条粗细),默认值为 1。
  • lineType: 圆边界的类型,可以是 LINE_8(8 连通线)或 LINE_AA(反锯齿线)。
  • shift: 坐标值的小数位数,通常为 0。

下面是一个示例代码,演示了如何使用 cv::circle 函数绘制圆:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <opencv2/opencv.hpp>

int main() {
// 创建一个黑色图像
cv::Mat image(300, 400, CV_8UC3, cv::Scalar(0, 0, 0));

// 定义圆心坐标和半径
cv::Point center(200, 150);
int radius = 50;

// 绘制圆
cv::circle(image, center, radius, cv::Scalar(0, 0, 255), 2);

// 显示绘制的图像
cv::imshow("Circle Example", image);
cv::waitKey(0);

return 0;
}

在这个示例中,我们创建了一个黑色的图像,然后使用 cv::circle 函数绘制了一个红色的圆,圆心为 (200, 150),半径为 50。

cv::circle 函数在图像绘制中非常有用,可以用于标记、可视化、边缘检测结果显示等多种情况。可以通过调整参数来控制圆的颜色、半径和边界样式。


cv::Rect

在 OpenCV 中,cv::Rect 是一个用于表示矩形的类。它通常用于图像处理和计算机视觉中,用于表示图像中的感兴趣区域(ROI),或者用于描述物体的边界框。

cv::Rect 的定义位于 opencv2/core.hpp 头文件中,其结构如下:

1
2
3
4
5
6
7
8
9
class Rect {
public:
Rect();
Rect(int x, int y, int width, int height);
Rect(const Rect& r);

int x, y; // 矩形左上角的坐标
int width, height; // 矩形的宽度和高度
};

这个类有以下几个构造函数和成员变量:

  • Rect(): 默认构造函数,会将矩形的属性初始化为默认值。
  • Rect(int x, int y, int width, int height): 构造函数,传入矩形的左上角坐标、宽度和高度。
  • Rect(const Rect& r): 复制构造函数,用于创建一个已有矩形的副本。
  • xy: 整数类型的成员变量,表示矩形左上角的 x 和 y 坐标。
  • widthheight: 整数类型的成员变量,表示矩形的宽度和高度。

下面是一个示例代码,演示了如何使用 cv::Rect 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <opencv2/opencv.hpp>

int main() {
// 创建一个矩形对象
cv::Rect rect1(100, 50, 200, 150);

// 访问矩形的属性
int x = rect1.x;
int y = rect1.y;
int width = rect1.width;
int height = rect1.height;

// 输出矩形的属性
std::cout << "Rectangle: x=" << x << ", y=" << y << ", width=" << width << ", height=" << height << std::endl;

// 创建另一个矩形对象
cv::Rect rect2(50, 30, 100, 80);

// 使用复制构造函数创建新矩形对象
cv::Rect rect3 = rect2;

return 0;
}

cv::Rect 类在许多图像处理和计算机视觉任务中非常有用,特别是在需要表示感兴趣区域、物体的边界框等情况。它可以帮助您存储和操作矩形的属性,以及在图像处理中进行相关操作,例如提取感兴趣区域、绘制边界框等。


cv::line

在 OpenCV 中,cv::line 是一个用于在图像上绘制直线的函数。这个函数可以用来绘制一条连接两个点的直线,或者在图像上绘制多条直线。

函数原型如下:

1
void cv::line(cv::InputOutputArray img, cv::Point pt1, cv::Point pt2, const cv::Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);

函数参数解释:

  • img: 输入/输出图像,可以是单通道或多通道图像。
  • pt1pt2: 两个 cv::Point 类型的参数,表示直线的起点和终点。
  • color: 绘制直线的颜色,可以使用 cv::Scalar 类来表示颜色。
  • thickness: 直线的宽度(线条粗细),默认值为 1。
  • lineType: 直线的类型,可以是 LINE_8(8 连通线)或 LINE_AA(反锯齿直线)。
  • shift: 坐标值的小数位数,通常为 0。

下面是一个示例代码,演示了如何使用 cv::line 函数绘制直线:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <opencv2/opencv.hpp>

int main() {
// 创建一个黑色图像
cv::Mat image(300, 400, CV_8UC3, cv::Scalar(0, 0, 0));

// 定义起点和终点坐标
cv::Point pt1(50, 100);
cv::Point pt2(350, 200);

// 绘制直线
cv::line(image, pt1, pt2, cv::Scalar(0, 0, 255), 2);

// 显示绘制的图像
cv::imshow("Line Example", image);
cv::waitKey(0);

return 0;
}

在这个示例中,我们创建了一个黑色的图像,然后使用 cv::line 函数在图像上绘制了一条红色的直线,连接了起点 (50, 100) 和终点 (350, 200)

cv::line 函数在图像绘制中非常有用,可以用于标记、可视化、边缘检测结果显示等多种情况。可以通过调整参数来控制直线的颜色、宽度和类型。


cv::Size

在 OpenCV 中,cv::Size 是一个用于表示大小(尺寸)的类。它通常用于图像处理和计算机视觉中,用于表示图像的宽度和高度,或者表示其他物体、区域的尺寸。

cv::Size 的定义位于 opencv2/core.hpp 头文件中,其结构如下:

1
2
3
4
5
6
7
8
class Size {
public:
Size();
Size(int width, int height);
Size(const Size& sz);

int width, height;
};

这个类有以下几个构造函数和成员变量:

  • Size(): 默认构造函数,会将宽度和高度初始化为 0。
  • Size(int width, int height): 构造函数,传入宽度和高度。
  • Size(const Size& sz): 复制构造函数,用于创建一个已有尺寸的副本。
  • widthheight: 整数类型的成员变量,分别表示尺寸的宽度和高度。

下面是一个示例代码,演示了如何使用 cv::Size 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <opencv2/opencv.hpp>

int main() {
// 创建一个尺寸对象
cv::Size size1(640, 480);

// 访问尺寸的宽度和高度
int width = size1.width;
int height = size1.height;

// 输出尺寸的宽度和高度
std::cout << "Size: " << width << " x " << height << std::endl;

// 创建另一个尺寸对象
cv::Size size2(320, 240);

// 使用复制构造函数创建新尺寸对象
cv::Size size3 = size2;

return 0;
}

cv::Size 类在许多图像处理和计算机视觉任务中非常有用,特别是在需要表示图像的大小、物体的尺寸等情况。它可以帮助您存储和操作尺寸信息,以及在图像处理中进行相关操作,例如调整图像大小、计算物体的尺寸等。


cv::Point2f

在 OpenCV 中,cv::Point2f 是一个用于表示二维浮点坐标点的类。它是 cv::Point 的变体,其中坐标值使用浮点数而不是整数表示。cv::Point2f 类通常用于图像处理和计算机视觉中,特别是在需要使用浮点坐标来表示像素位置、图像上的点、图像中的特征点等情况。

cv::Point2f 的定义位于 opencv2/core/types.hpp 头文件中,其结构如下:

1
2
3
4
5
6
7
8
class Point2f {
public:
Point2f();
Point2f(float x, float y);
Point2f(const Point2f& pt);

float x, y;
};

这个类有以下几个构造函数和成员变量:

  • Point2f(): 默认构造函数,会将坐标点初始化为 (0, 0)。
  • Point2f(float x, float y): 构造函数,传入 x 和 y 坐标值。
  • Point2f(const Point2f& pt): 复制构造函数,用于创建一个已有点的副本。
  • xy: 浮点数类型的成员变量,表示点的 x 和 y 坐标。

下面是一个示例代码,演示了如何使用 cv::Point2f 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <opencv2/opencv.hpp>

int main() {
// 创建一个点对象
cv::Point2f pt1(10.5, 20.3);

// 访问点的坐标
float x = pt1.x;
float y = pt1.y;

// 输出点的坐标
std::cout << "Point coordinates: (" << x << ", " << y << ")" << std::endl;

// 创建另一个点对象
cv::Point2f pt2(5.2, 8.7);

// 使用复制构造函数创建新点对象
cv::Point2f pt3 = pt2;

return 0;
}

cv::Point2f 类在许多情况下都非常有用,特别是当需要使用浮点坐标来精确表示像素位置、特征点位置等时。它是 OpenCV 中基本的数据结构之一,用于处理图像中的点和坐标。


cv::RotatedRect

在 OpenCV 中,cv::RotatedRect 是一个用于表示旋转矩形的类。旋转矩形是一个带有角度的矩形,通常用于表示在图像中检测到的旋转物体的边界框。

cv::RotatedRect 的定义位于 opencv2/core/types.hpp 头文件中,其结构如下:

1
2
3
4
5
6
7
8
9
class RotatedRect {
public:
RotatedRect();
RotatedRect(const Point2f& center, const Size2f& size, float angle);

Point2f center; // 旋转矩形中心坐标
Size2f size; // 旋转矩形的尺寸,宽度和高度
float angle; // 旋转矩形的角度(以度为单位)
};

这个类有以下几个构造函数和成员变量:

  • RotatedRect(): 默认构造函数,会将旋转矩形的属性初始化为默认值。
  • RotatedRect(const Point2f& center, const Size2f& size, float angle): 构造函数,传入旋转矩形的中心坐标、尺寸和角度。

成员变量解释:

  • center: 一个 Point2f 类型的成员变量,表示旋转矩形的中心坐标。
  • size: 一个 Size2f 类型的成员变量,表示旋转矩形的宽度和高度。
  • angle: 一个浮点数,表示旋转矩形的角度,单位为度。

下面是一个示例代码,演示了如何使用 cv::RotatedRect 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <opencv2/opencv.hpp>

int main() {
cv::Point2f center(100, 100);
cv::Size2f size(200, 100);
float angle = 30.0;

// 创建一个旋转矩形对象
cv::RotatedRect rotatedRect(center, size, angle);

// 访问旋转矩形的属性
cv::Point2f rectCenter = rotatedRect.center;
cv::Size2f rectSize = rotatedRect.size;
float rectAngle = rotatedRect.angle;

// 输出旋转矩形的属性
std::cout << "Center: (" << rectCenter.x << ", " << rectCenter.y << ")" << std::endl;
std::cout << "Size: " << rectSize.width << " x " << rectSize.height << std::endl;
std::cout << "Angle: " << rectAngle << " degrees" << std::endl;

return 0;
}

cv::RotatedRect 类在许多图像处理和计算机视觉任务中非常有用,特别是在需要表示旋转物体的边界框时。它可以帮助您存储和操作旋转矩形的属性,以及在图像中进行相关操作,例如绘制旋转矩形、计算旋转矩形的边界框等。


cv::Point

在 OpenCV 库中,cv::Point 是一个用于表示二维坐标点的类。它通常用于图像处理和计算机视觉中,用于表示像素位置、图像上的点、图像中的特征点等。

cv::Point 的定义位于 opencv2/core.hpp 头文件中,其结构如下:

1
2
3
4
5
6
7
8
class Point {
public:
Point();
Point(int x, int y);
Point(const Point& pt);

int x, y;
};

这个类有以下几个构造函数和成员变量:

  • Point(): 默认构造函数,会将坐标点初始化为 (0, 0)。
  • Point(int x, int y): 构造函数,传入 x 和 y 坐标值。
  • Point(const Point& pt): 复制构造函数,用于创建一个已有点的副本。
  • xy: 整数类型的成员变量,表示点的 x 和 y 坐标。

下面是一个示例代码,演示了如何使用 cv::Point 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <opencv2/opencv.hpp>

int main() {
// 创建一个点对象
cv::Point pt1(10, 20);

// 访问点的坐标
int x = pt1.x;
int y = pt1.y;

// 输出点的坐标
std::cout << "Point coordinates: (" << x << ", " << y << ")" << std::endl;

// 创建另一个点对象
cv::Point pt2(5, 8);

// 使用复制构造函数创建新点对象
cv::Point pt3 = pt2;

return 0;
}

cv::Point 类在许多情况下都非常有用,例如在图像上标记特定位置、表示特征点、进行坐标计算等。它是 OpenCV 中基本的数据结构之一,用于处理图像中的点和坐标。


cv::Scalar

cv::Scalar 是 OpenCV 库中的一个类,用于表示一个包含四个分量的向量,通常用于表示颜色、像素值等。这四个分量可以分别表示蓝色、绿色、红色和透明度(BGR-A)。

这个类在图像处理中经常用于设置颜色、像素值等。每个分量都是一个双精度浮点数,通常取值范围是 0 到 255,表示一个 8 位无符号整数值的颜色分量。

下面是一个简单的例子,演示了如何使用 cv::Scalar 来创建颜色以及像素值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <opencv2/opencv.hpp>

int main() {
// 创建一个红色的 Scalar 对象
cv::Scalar redColor(0, 0, 255);

// 创建一个白色的 Scalar 对象
cv::Scalar whiteColor(255, 255, 255);

// 输出 Scalar 对象的分量值
std::cout << "Red Color: " << redColor[0] << ", " << redColor[1] << ", " << redColor[2] << std::endl;

// 创建一个像素值为 (100, 150, 200) 的 Scalar 对象
cv::Scalar pixelValue(100, 150, 200);

return 0;
}

需要注意的是,这里提供的颜色顺序是 BGR,与一般人们常见的 RGB 顺序不同。另外,如果不需要使用透明度,可以忽略透明度分量。

cv::Scalar 通常用于填充矩形、绘制文本、设置像素值等场景,方便地表示颜色和值。在图像处理和计算机视觉领域中,cv::Scalar 是一个很有用的工具,使颜色和值的处理变得简单且易于理解。


cv::Mat

  • 简介:

    • cv::Mat 是 OpenCV 库中表示图像和矩阵的核心数据结构之一。它是一个多维数组,可以存储和操作图像、矩阵和其他类型的数据
  • 原型:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    class Mat {
    public:
    // 构造函数
    Mat();
    Mat(int rows, int cols, int type);
    Mat(Size size, int type);
    Mat(int rows, int cols, int type, const Scalar& scalar);
    Mat(Size size, int type, const Scalar& scalar);
    Mat(const Mat& m);

    // 数据访问
    int rows;
    int cols;
    int type();
    int channels();
    int depth();
    size_t elemSize();
    size_t elemSize1();
    bool empty();
    void release();
    Mat clone() const;
    Mat& operator=(const Mat& m);
    Mat operator()(const Range& rowRange, const Range& colRange) const;
    Mat row(int y) const;
    Mat col(int x) const;
    Mat rowRange(int startrow, int endrow) const;
    Mat colRange(int startcol, int endcol) const;
    Mat reshape(int cn, int rows = 0) const;

    // 数据操作
    void create(int rows, int cols, int type);
    void create(Size size, int type);
    void convertTo(Mat& m, int rtype, double alpha = 1, double beta = 0) const;
    void copyTo(Mat& m) const;
    void copyTo(Mat& m, const Mat& mask) const;
    void assignTo(Mat& m, int type = -1) const;
    void swap(Mat& m);
    Mat& setTo(const Scalar& scalar, const Mat& mask = Mat());
    Mat& setTo(const Scalar& scalar, const Mat& mask);
    Mat reshape(int cn, int newndims, const int* newsz) const;

    // 图像加载和保存
    static Mat imread(const String& filename, int flags = IMREAD_COLOR);
    bool imwrite(const String& filename, const std::vector<int>& params = std::vector<int>()) const;

    // 其他函数和操作符重载
    // ...
    };
  • 详解:

    • cv::Mat 的主要特点和功能包括
      • 多维数组表示:cv::Mat 可以表示多维数组,如二维图像(矩阵)和三维图像(彩色图像)等。
      • 数据访问:可以通过 rows 和 cols 成员变量获取矩阵的行数和列数,通过 at 成员函数或数组索引操作符 [] 来访问和修改矩阵中的元素。
      • 数据操作:可以对 cv::Mat 执行各种数据操作,如创建矩阵、复制矩阵、转换数据类型、调整大小、提取子矩阵等
      • 图像加载和保存:通过 imread 和 imwrite 函数可以加载和保存图像文件
      • 运算符重载:cv::Mat 支持许多运算符重载,如加法、减法、乘法等,以及与其他 cv::Mat 对象之间的操作
  • 注:

    • 需要注意的是,cv::Mat 的默认构造函数创建了一个空的矩阵对象,必须使用 create 函数来分配内存空间并指定矩阵的大小和数据类型
    • 使用 cv::Mat,你可以进行各种图像处理和计算机视觉任务,如图像加载、图像处理、特征提取、模式识别等。了解和熟悉 cv::Mat 的功能和使用方法是使用 OpenCV 进行图像处理和计算机视觉开发的基础。你可以参考 OpenCV 官方文档和示例代码,深入学习关于 cv::Mat 的更多信息和用法

cv::imread

  • 简介:

    • cv::imread() 是 OpenCV 库中用于读取图像文件的函数。它接受图像文件的路径作为输入,并返回一个表示图像的 cv::Mat 对象
  • 原型:

    1
    cv::Mat cv::imread(const cv::String& filename, int flags = cv::IMREAD_COLOR);
  • 参数:

    • filename:图像文件的路径
    • flags(可选):指定读取图像的方式,默认值为 cv::IMREAD_COLOR。可以使用以下标志来指定读取图像的颜色模式
      • cv::IMREAD_COLOR:读取彩色图像(默认值)
      • cv::IMREAD_GRAYSCALE:将图像以灰度模式读取
      • cv::IMREAD_UNCHANGED:以原始图像的包含 alpha 通道的方式读取
  • 返回值:

    • 如果成功读取图像文件,则返回一个 cv::Mat 对象,表示读取到的图像数据
    • 如果无法读取图像文件,返回一个空的 cv::Mat 对象
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <opencv2/opencv.hpp>

    int main() {
    // 读取图像文件
    cv::Mat image = cv::imread("image.jpg");

    if (image.empty()) {
    std::cout << "无法加载图像文件" << std::endl;
    return -1;
    }

    // 处理图像...

    return 0;
    }
  • 注:

    • 在上述示例中,cv::imread() 函数尝试加载名为 “image.jpg” 的图像文件。如果成功读取图像文件,将返回一个非空的 cv::Mat 对象,可以对其进行进一步的图像处理操作
    • 需要注意的是,cv::imread() 函数需要提供正确的图像文件路径,并确保所使用的图像格式与 OpenCV 支持的图像格式相匹配。如果无法加载图像文件,可以检查文件路径是否正确、文件是否存在以及文件格式是否受支持
    • 另外,OpenCV 还提供了其他的图像读取函数,如 cv::imdecode() 用于从内存中读取图像数据,以及 cv::VideoCapture 类用于读取视频文件或摄像头视频流。你可以根据具体的需求选择适当的图像读取方法

cv::imwrite

  • 简介:

    • cv::imwrite() 是 OpenCV 库中用于将图像数据保存到文件的函数。它接受图像数据和目标文件路径作为输入,并将图像数据写入指定的文件
  • 原型:

    1
    bool cv::imwrite(const cv::String& filename, const cv::Mat& image, const std::vector<int>& params = std::vector<int>());
  • 参数:

    • filename:保存图像的文件路径。
    • image:要保存的图像数据,为一个 cv::Mat 对象。
    • params(可选):保存图像的参数,为一个整数向量。参数可以控制图像的压缩格式、质量等。常用的参数包括:
      • cv::IMWRITE_JPEG_QUALITY:指定 JPEG 格式的图像质量,取值范围为 0 到 100。
      • cv::IMWRITE_PNG_COMPRESSION:指定 PNG 格式的压缩级别,取值范围为 0 到 9,其中 0 表示无压缩,9 表示最高压缩
  • 返回值:

    • 如果成功将图像数据写入文件,则返回 true
    • 如果无法将图像数据写入文件,则返回 false
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <opencv2/opencv.hpp>

    int main() {
    // 读取图像文件
    cv::Mat image = cv::imread("image.jpg");

    if (image.empty()) {
    std::cout << "无法加载图像文件" << std::endl;
    return -1;
    }

    // 保存图像文件
    bool result = cv::imwrite("output.jpg", image);

    if (result) {
    std::cout << "图像保存成功" << std::endl;
    } else {
    std::cout << "图像保存失败" << std::endl;
    }

    return 0;
    }
  • 注:

    • 在上述示例中,cv::imread() 函数尝试加载名为 “image.jpg” 的图像文件,然后将图像数据存储在 cv::Mat 对象 image 中。接下来,通过调用 cv::imwrite() 函数,将图像数据保存到名为 “output.jpg” 的文件中
    • 需要注意的是,cv::imwrite() 函数需要提供正确的文件路径,并确保所指定的文件格式与 OpenCV 支持的图像格式相匹配。如果无法将图像数据写入文件,可以检查文件路径是否正确、文件是否可写以及图像数据是否有效
    • 另外,OpenCV 还提供了其他的图像保存函数,如 cv::imencode() 用于将图像数据编码为内存缓冲区,并将其保存为图像文件。你可以根据具体的需求选择适当的图像保存方法

cv::rectangle

  • 简介:

    • cv::rectangle() 是 OpenCV 库中用于在图像上绘制矩形的函数。它接受一个图像对象和矩形参数,并在图像上绘制指定的矩形
  • 原型:

    1
    void cv::rectangle(cv::Mat& img, const cv::Rect& rect, const cv::Scalar& color, int thickness = 1, int lineType = cv::LINE_8, int shift = 0);
  • 参数:

    • img:要在其上绘制矩形的图像对象,为一个 cv::Mat 对象。
    • rect:矩形的位置和大小,为一个 cv::Rect 对象。
    • color:矩形的颜色,为一个 cv::Scalar 对象,可以是 BGR 或灰度值。
    • thickness(可选):矩形线条的粗细,默认值为 1。
    • lineType(可选):线条的类型,默认值为 cv::LINE_8,表示8连通线条。
    • shift(可选):点坐标的小数位数,默认值为 0
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <opencv2/opencv.hpp>

    int main() {
    // 创建一个空白图像
    cv::Mat image(300, 400, CV_8UC3, cv::Scalar(255, 255, 255));

    // 绘制矩形
    cv::Rect rect(50, 50, 200, 150);
    cv::Scalar color(0, 0, 255); // 红色
    int thickness = 2;
    int lineType = cv::LINE_8;
    int shift = 0;
    cv::rectangle(image, rect, color, thickness, lineType, shift);

    // 显示图像
    cv::imshow("Image", image);
    cv::waitKey(0);

    return 0;
    }
  • 注:

    • 在上述示例中,我们创建了一个大小为 300x400 像素、颜色为白色的图像 image。然后,我们定义了一个矩形 rect,它位于图像上的 (50, 50) 点,宽度为 200,高度为 150。我们将矩形的颜色设置为红色,线条粗细为 2。最后,我们使用 cv::rectangle() 函数在图像上绘制矩形
    • 需要注意的是,cv::rectangle() 函数会在原始图像对象上进行绘制,因此在函数调用之前,确保图像对象已经被创建并且是可写的
    • 除了 cv::rectangle(),OpenCV 还提供了其他的绘制函数,如绘制直线、圆形、多边形等。你可以根据具体的需求选择适当的绘制函数,并使用不同的参数来调整绘制效果

cv::imshow

  • 简介:

    • cv::imshow() 是 OpenCV 库中用于显示图像的函数。它接受一个窗口名称和图像对象,并在一个新的窗口中显示图像
  • 原型:

    1
    void cv::imshow(const cv::String& winname, const cv::Mat& image);
  • 参数:

    • winname:窗口的名称,为一个字符串。
    • image:要显示的图像数据,为一个 cv::Mat 对象
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <opencv2/opencv.hpp>

    int main() {
    // 读取图像文件
    cv::Mat image = cv::imread("image.jpg");

    if (image.empty()) {
    std::cout << "无法加载图像文件" << std::endl;
    return -1;
    }

    // 显示图像
    cv::imshow("Image", image);

    // 等待按下任意按键
    cv::waitKey(0);

    }
  • 注:

    • 在上述示例中,我们使用 cv::imread() 函数加载一个名为 “image.jpg” 的图像文件,并将图像数据存储在 cv::Mat 对象 image 中。然后,我们调用 cv::imshow() 函数,将图像显示在一个名为 “Image” 的窗口中
    • 需要注意的是,cv::imshow() 函数会创建一个新的窗口来显示图像。窗口名称是唯一的,可以使用不同的名称来创建多个窗口并显示不同的图像。如果窗口名称已经存在,则会将新的图像显示在现有窗口中
    • 在调用 cv::imshow() 函数后,通常需要调用 cv::waitKey() 函数来等待用户按下按键。这样可以使窗口保持打开状态,直到用户关闭窗口或按下按键。cv::waitKey() 函数返回按下的键的 ASCII 值,如果没有按下按键,则返回 -1
    • 除了 cv::imshow(),OpenCV 还提供了其他的图像显示和交互函数,如调整窗口大小、绘制图形、注册鼠标事件等。你可以根据具体的需求选择适当的函数,并使用相关的参数和事件处理机制来进行图像显示和交互操作

namedWindow

  • 简介:

    • cv::namedWindow() 是 OpenCV 库中用于创建一个带有指定名称的窗口的函数。它可以用于显示图像、绘制图形和接收用户交互事件
  • 原型:

    1
    void cv::namedWindow(const cv::String& winname, int flags = cv::WINDOW_AUTOSIZE);
  • 参数:

    • winname:窗口的名称,为一个字符串。
    • flags(可选):窗口的属性标志,用于指定窗口的行为和外观。常用的标志包括:
      • cv::WINDOW_NORMAL:创建一个可调整大小的窗口。
      • cv::WINDOW_AUTOSIZE:创建一个自适应大小的窗口,窗口大小将根据图像大小自动调整
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <opencv2/opencv.hpp>

    int main() {
    // 读取图像文件
    cv::Mat image = cv::imread("image.jpg");

    if (image.empty()) {
    std::cout << "无法加载图像文件" << std::endl;
    return -1;
    }

    // 创建一个名为 "Image" 的窗口
    cv::namedWindow("Image", cv::WINDOW_NORMAL);

    // 显示图像
    cv::imshow("Image", image);

    // 等待按下任意按键
    cv::waitKey(0);

    return 0;
    }
  • 注:

    • 在上述示例中,我们使用 cv::imread() 函数加载一个名为 “image.jpg” 的图像文件,并将图像数据存储在 cv::Mat 对象 image 中。然后,我们调用 cv::namedWindow() 函数,创建一个名为 “Image” 的窗口。通过设置 flags 参数为 cv::WINDOW_NORMAL,我们可以创建一个可调整大小的窗口
    • 接下来,我们调用 cv::imshow() 函数将图像显示在 “Image” 窗口中。最后,通过调用 cv::waitKey() 函数等待按键,以保持窗口打开状态,直到用户关闭窗口或按下按键
    • 使用 cv::namedWindow() 函数可以为窗口指定名称,并设置窗口的属性标志以控制其行为和外观。这样可以在显示多个图像时,为每个图像创建独立的窗口,并根据需要进行大小调整

cv::destroyWindow

  • 简介:

    • cv::destroyWindow() 是 OpenCV 库中用于关闭指定名称的窗口的函数。它可以用于关闭已创建的窗口并释放与窗口相关的资源
  • 原型:

    1
    void cv::destroyWindow(const cv::String& winname);
  • 参数:

    • winname:要关闭的窗口的名称,为一个字符串
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <opencv2/opencv.hpp>

    int main() {
    // 创建一个名为 "Image" 的窗口
    cv::namedWindow("Image");

    // ... 一些图像处理操作 ...

    // 关闭名为 "Image" 的窗口
    cv::destroyWindow("Image");

    return 0;
    }
  • 注:

    • 在上述示例中,我们通过调用 cv::namedWindow() 函数创建了一个名为 “Image” 的窗口。然后,在执行一些图像处理操作后,我们通过调用 cv::destroyWindow() 函数关闭了名为 “Image” 的窗口
    • 使用 cv::destroyWindow() 函数可以在不需要显示某个窗口时,将其关闭并释放相关资源。这对于图像处理过程中动态创建和关闭窗口非常有用
    • 除了关闭单个窗口,还可以使用 cv::destroyAllWindows() 函数关闭所有已创建的窗口,释放所有窗口相关的资源
    • 请注意,窗口的创建和销毁是在 OpenCV 的 HighGUI 模块中进行的,因此在使用这些函数之前,需要确保已经正确链接和初始化了 OpenCV 库

cv::waitKey

  • 简介:

    • cv::waitKey() 是 OpenCV 库中用于等待用户按下按键的函数。它在程序执行过程中暂停,并等待用户按下键盘上的按键
  • 原型:

    1
    int cv::waitKey(int delay = 0);
  • 参数:

    • delay(可选):等待按键的时间(以毫秒为单位),默认值为 0。如果设置为正整数,表示等待指定的时间后,如果没有按键按下,则函数将继续执行。如果设置为 0,则函数将无限期等待按键的按下
  • 返回值:

    • 返回按下的键的 ASCII 值。
    • 如果在指定的时间内没有按键按下,或者未能获取按键的值,则返回 -1。
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <opencv2/opencv.hpp>

    int main() {
    // 创建一个名为 "Image" 的窗口
    cv::namedWindow("Image");

    // 显示图像
    cv::Mat image = cv::imread("image.jpg");
    cv::imshow("Image", image);

    // 等待按下任意按键
    int key = cv::waitKey(0);

    // 输出按下的键的 ASCII 值
    std::cout << "按下的键的 ASCII 值: " << key << std::endl;

    return 0;
    }
  • 注:

    • 在上述示例中,我们通过调用 cv::namedWindow() 函数创建了一个名为 “Image” 的窗口,并通过 cv::imshow() 函数显示了一张图像。然后,我们调用 cv::waitKey() 函数,等待用户按下键盘上的按键。将 delay 参数设置为 0 表示无限期等待按键按下
    • 当用户按下按键时,cv::waitKey() 函数将返回按键的 ASCII 值。我们可以通过输出语句将其打印出来。如果没有按键按下或无法获取按键的值,函数将返回 -1
    • 需要注意的是,调用 cv::waitKey() 函数会使程序暂停执行,直到用户按下按键或达到指定的等待时间。这通常与图像显示和交互操作配合使用,以保持窗口打开状态并等待用户操作
    • 除了返回按键的 ASCII 值,cv::waitKey() 函数还可以用于实现视频播放和实时图像处理等应用,其中按键事件用于控制程序的流程和操作

简介

  • python中常用的技巧

python3 获取当前路径

在 Python3 中,可以使用标准库模块 ospathlib 来获取当前路径。以下是两种方式的详细用法:


方法一:使用 os 模块

1. 获取当前工作目录(运行脚本时所在的目录)

1
2
3
4
import os

current_path = os.getcwd()
print("当前工作目录是:", current_path)

2. 获取当前脚本文件所在的目录

1
2
3
4
import os

script_dir = os.path.dirname(os.path.abspath(__file__))
print("当前脚本所在目录是:", script_dir)

方法二:使用 pathlib 模块

pathlib 是从 Python 3.4 开始引入的模块,用于处理文件和路径,功能更强大且代码更简洁。

1. 获取当前工作目录

1
2
3
4
from pathlib import Path

current_path = Path.cwd()
print("当前工作目录是:", current_path)

2. 获取当前脚本文件所在的目录

1
2
3
4
from pathlib import Path

script_dir = Path(__file__).resolve().parent
print("当前脚本所在目录是:", script_dir)

两者的区别

  1. os.getcwd()Path.cwd() 获取的是工作目录(运行脚本时的目录),与脚本文件本身的存储路径无关。
  2. os.path.dirname(os.path.abspath(__file__))Path(__file__).resolve().parent 获取的是脚本文件的实际存储路径。

如果你运行脚本时,工作目录和脚本文件目录不一致,需要特别注意选择合适的方法。

python 执行scp命令

在 Python 中执行 SCP 命令可以使用 paramiko 库,这是一个用于SSH2的Python库,支持SSH会话和文件传输。以下是一个示例,演示如何使用 paramiko 实现在 Python 中执行 SCP 命令:

首先,确保你已经安装了 paramiko 库。如果没有安装,你可以使用 pip 来安装它:

1
pip install paramiko

接下来,以下是一个简单的 Python 示例代码,演示如何使用 paramiko 执行 SCP 命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import paramiko

# 连接 SSH 服务器
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.connect('your_server_ip', username='your_username', password='your_password')

# 执行 SCP 命令,将本地文件复制到远程服务器
local_path = '/path/to/local/file.txt'
remote_path = '/path/to/remote/file.txt'

# 使用 SCPClient 实现文件传输
scp = ssh.open_scp()
scp.put(local_path, remote_path) # 本地文件复制到远程服务器
scp.close()

# 关闭 SSH 连接
ssh.close()

上述代码中的 your_server_ip 是远程服务器的 IP 地址,your_username 是用于 SSH 登录的用户名,your_password 是对应的密码。local_path 是本地文件的路径,remote_path 是远程服务器上的目标路径。

这个示例展示了如何使用 paramiko 库创建一个 SSH 连接并使用 SCP 在本地和远程服务器之间传输文件。根据你的实际情况,你可能需要更改相应的路径和凭据信息。

简介

  • Python编程语言的理论基础

python3 pip -U参数是什么意思

pip 命令中,-U 参数用于升级已经安装的包到最新版本。具体来说,-U 参数表示 “upgrade”,它告诉 pip 将指定的包升级到最新可用版本。

例如:

1
pip install -U package_name

这将会升级 package_name 到最新版本。如果 package_name 没有被安装,它将被安装;如果已经安装,将会被升级到最新版本。

使用 -U 参数是为了确保你使用的是包的最新版本,而不是旧版本。这在确保你使用的软件包具有最新特性、修复了已知问题或者提供了性能改进等方面是很有用的。

python3 str object is not callable

如果你在Python中遇到 “str object is not callable” 错误,通常是因为你意外地使用了内置函数的名称作为变量名。在Python中,避免使用内置函数名作为变量名是一个良好的实践。

例如,以下是一个可能导致该错误的示例:

1
2
3
str = "Hello"
result = str(42) # 这里会引发 "str object is not callable" 错误
print(result)

在这个例子中,str被重新赋值为一个字符串,然后试图调用它就会引发错误。为了避免这种情况,应该使用不同的变量名:

1
2
3
my_str = "Hello"
result = str(42) # 这里不会引发错误,因为 str 是内置函数
print(result)

确保不要覆盖内置函数和关键字的名称,以避免这种类型的错误。如果已经发生了这种情况,重新启动Python解释器并尽量避免使用与内置函数和关键字相同的变量名。

python3 no module named requests

如果您在 Python 3 中遇到 “no module named requests” 错误,这意味着您的 Python 环境中缺少 requests 模块。requests 是一个用于发送 HTTP 请求的常用库,但它不是 Python 的标准库,因此您需要单独安装它。

要解决这个问题,您可以执行以下步骤来安装 requests 模块:

  1. 使用 pip 安装 requests

    打开终端(命令行界面)并运行以下命令来使用 pip 安装 requests 模块:

    1
    pip install requests

    请确保 pip 是与您的 Python 3 版本相关联的 pip,通常情况下,您可以使用 pip3 命令来确保安装到 Python 3:

    1
    pip3 install requests
  2. 验证安装

    安装完成后,您可以在 Python 中导入 requests 模块并验证是否成功。打开 Python 解释器或脚本,尝试运行以下代码:

    1
    2
    import requests
    print(requests.__version__)

    如果没有出现错误,并且成功打印出 requests 版本号,那么说明安装已经成功。

请注意,如果您在虚拟环境中工作,请确保您的虚拟环境处于活动状态,以便 requests 模块安装到虚拟环境而不是全局 Python 环境。如果您使用的是 Python 3,pip 通常会默认安装到 Python 3 的环境中。

如果仍然遇到问题,可以提供更多详细信息,以便我更好地帮助您解决问题。

python3 pip 常用命令 详解

pip 是 Python 的包管理工具,用于安装、卸载和管理 Python 包(也称为库或模块)。以下是一些常用的 pip 命令及其详细解释:

  1. 安装包

    1
    pip install package_name

    用于安装指定的 Python 包。package_name 是要安装的包的名称。可以使用这个命令来安装第三方库,例如 numpyrequestsmatplotlib 等。可以使用 -r 选项从一个文本文件中安装一组包。

  2. 卸载包

    1
    pip uninstall package_name

    用于卸载指定的 Python 包。package_name 是要卸载的包的名称。

  3. 查看已安装的包

    1
    pip list

    显示已经安装的所有 Python 包的列表。

  4. 查看包的详细信息

    1
    pip show package_name

    显示指定包的详细信息,包括版本号、作者、描述等。

  5. 升级包

    1
    pip install --upgrade package_name

    用于升级已安装的包到最新版本。

  6. 搜索包

    1
    pip search search_term

    用于搜索 PyPI(Python Package Index)上的包。search_term 是您要搜索的包的关键字。

  7. 创建 requirements 文件

    1
    pip freeze > requirements.txt

    将当前环境中已安装的所有包及其版本号保存到 requirements.txt 文件中,通常用于共享项目的依赖信息。

  8. 从 requirements 文件安装包

    1
    pip install -r requirements.txt

    requirements.txt 文件中安装指定版本的包,用于在新环境中还原项目的依赖关系。

  9. 查看包的依赖关系

    1
    pip show --files package_name

    显示指定包的依赖关系和文件路径。

  10. 安装包的特定版本

    1
    pip install package_name==version

    安装指定版本的包,其中 version 是要安装的版本号。

这些是一些常用的 pip 命令,用于管理 Python 包。根据您的需求,您可以使用这些命令来安装、升级、卸载、查看和管理 Python 包。使用 pip 可以方便地管理Python项目的依赖关系。

kwargs

在 Python 中,kwargs 是一个特殊的参数,用于接收传递给函数的关键字参数(Keyword Arguments)。kwargs 是一个字典(dictionary),其中包含了函数调用时传递的关键字参数及其对应的值。

使用 **kwargs 语法可以在函数定义中接收关键字参数,并将其作为字典传递给函数体内部。下面是一个示例:

1
2
3
4
5
6
def my_function(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")

# 使用关键字参数调用函数
my_function(name="John", age=30, city="New York")

在上面的示例中,my_function 函数定义中的 **kwargs 表示可以接收任意数量的关键字参数。在函数体内部,kwargs 是一个字典,可以使用 items() 方法迭代其中的键值对,并对其进行处理。在函数调用中,传递的关键字参数会被收集到 kwargs 字典中。

运行上述代码,输出将是:

1
2
3
name: John
age: 30
city: New York

通过使用 **kwargs,函数能够接收灵活的关键字参数,并在函数内部以字典的形式进行处理。这使得函数可以处理各种不同的关键字参数,而无需预先指定它们的名称和数量。

源码编安装

  • 源码路径:zjy-190/Software/Python-3.8.3.tgz

  • 安装依赖包

    • apt-get install -y libssl-dev openssl libffi-dev zlib1g-dev
  • 编译安装

    • cd Python-3.8.0
    • ./configure –prefix=/usr/local/python3
    • make && make install
  • pip up

zlib not available 是什么

“zlib not available” 是一个错误消息,通常在使用Python时出现,表示缺少 zlib 模块或库。zlib 是一个用于压缩和解压缩数据的库,通常用于处理压缩文件、网络传输中的数据压缩等。如果您遇到 “zlib not available” 错误,可能是因为您的Python环境没有正确安装或配置 zlib 库。

要解决这个问题,您可以采取以下步骤:

  1. 安装 zlib 开发库:首先,确保您的系统上已经安装了 zlib 开发库。在大多数Linux系统上,可以使用包管理器安装 zlib 开发库,例如:

    • 在Ubuntu上,可以运行以下命令安装 zlib 开发库:

      1
      sudo apt-get install zlib1g-dev
    • 在CentOS上,可以运行以下命令安装 zlib 开发库:

      1
      sudo yum install zlib-devel
    • 在其他Linux发行版上,请使用相应的包管理器安装 zlib 开发库。

  2. 重新编译Python:如果您已经安装了 zlib 开发库但仍然遇到问题,您可能需要重新编译Python,以便它可以正确地链接到 zlib 库。这可以通过以下步骤完成:

    • 下载Python源代码,如果尚未下载。

    • 进入Python源代码的目录。

    • 运行以下命令:

      1
      2
      3
      ./configure
      make
      sudo make install

    这将重新编译Python,并确保它正确链接到 zlib 库。

  3. 检查Python环境:如果您使用的是虚拟环境,请确保虚拟环境中的Python正确配置并链接到 zlib 库。您可以使用以下命令检查虚拟环境的Python版本和 zlib 链接:

    1
    2
    which python
    python -c "import zlib; print(zlib)"

    确保这些命令返回正确的Python解释器和 zlib 模块。

python3 日志处理 工具 推荐

在Python 3中,有许多优秀的日志处理工具可供选择,这些工具可以帮助你有效地记录和管理应用程序的日志信息。以下是一些常用的Python 3日志处理工具的推荐:

  1. Python内置的logging模块:
    Python的标准库中包含了一个内置的logging模块,它提供了强大的日志记录功能。你可以使用这个模块来配置日志级别、输出目标和格式。它是一个常见的选择,因为它是Python的标准库的一部分,无需额外安装。

    1
    2
    3
    import logging

    logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
  2. Loguru:
    Loguru是一个易于使用的第三方日志库,它提供了直观的API和强大的功能。它支持动态日志级别调整、日志旋转、多种输出格式等功能。

    1
    2
    3
    from loguru import logger

    logger.add("app.log", rotation="500 MB", level="INFO")
  3. structlog:
    structlog是一个用于结构化日志记录的库,它允许你轻松地记录自定义字段,并支持多种输出格式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import structlog

    structlog.configure(
    processors=[
    structlog.processors.JSONRenderer(),
    structlog.processors.TimeStamper(fmt="iso"),
    ],
    logger_factory=structlog.PrintLoggerFactory(),
    )
  4. Fluentd:
    Fluentd是一个开源的日志收集和传输工具,它可以集成到Python应用程序中,并将日志发送到不同的目标,如文件、数据库或日志分析工具中。

  5. Loggly、Papertrail等云日志服务:
    如果你的应用程序部署在云上,可以考虑使用云日志服务,如Loggly、Papertrail等。它们提供了强大的日志管理和分析功能,可以帮助你更轻松地处理日志。

选择哪个日志处理工具取决于你的具体需求和偏好。无论你选择哪一个,都应该根据项目的规模和要求来配置和管理日志,以确保你能够有效地监视和调试你的应用程序。

编码

  • 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码
1
# -*- coding: cp-1252 -*-
  • 上述定义允许在源文件中使用 Windows-1252 字符集中的字符编码,对应适合语言为保加利亚语、白俄罗斯语、马其顿语、俄语、塞尔维亚语。

标识符

  • 第一个字符必须是字母表中字母或下划线 _ 。

  • 标识符的其他的部分由字母、数字和下划线组成。

  • 标识符对大小写敏感。

  • 在 Python 3 中,可以用中文作为变量名,非 ASCII 标识符也是允许的了。

python保留字

  • 保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
    1
    2
    3
    >>> import keyword
    >>> keyword.kwlist
    ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

注释

  • Python中单行注释以 # 开头,实例如下:

    1
    2
    3
    4
    #!/usr/bin/python3

    # 第一个注释
    print ("Hello, Python!") # 第二个注释
  • 多行注释可以用多个 # 号,还有 ‘’’ 和 “””:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/python3

    # 第一个注释
    # 第二个注释

    '''
    第三注释
    第四注释
    '''

    """
    第五注释
    第六注释
    """
    print ("Hello, Python!")

行与缩进

  • python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {}
  • 缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。实例如下
    1
    2
    3
    4
    if True:
    print ("True")
    else:
    print ("False")

多行语句

  • Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \ 来实现多行语句,例如:

    1
    2
    3
    total = item_one + \
    item_two + \
    item_three
  • 在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 \,例如:

    1
    2
    total = ['item_one', 'item_two', 'item_three',
    'item_four', 'item_five']

数字(Number)类型

  • python中数字有四种类型:整数、布尔型、浮点数和复数。
    • int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
    • bool (布尔), 如 True。
    • float (浮点数), 如 1.23、3E-2
    • complex (复数), 如 1 + 2j、 1.1 + 2.2j

字符串(String)

  • Python 中单引号 ‘ 和双引号 “ 使用完全相同。
  • 使用三引号(‘’’ 或 “””)可以指定一个多行字符串。
  • 转义符 \。
  • 反斜杠可以用来转义,使用 r 可以让反斜杠不发生转义。 如 r”this is a line with \n” 则 \n 会显示,并不是换行。
  • 按字面意义级联字符串,如 “this “ “is “ “string” 会被自动转换为 this is string。
  • 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
  • Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
  • Python 中的字符串不能改变。
  • Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
  • 字符串的截取的语法格式如下:变量[头下标:尾下标:步长]
1
2
3
4
word = '字符串'
sentence = "这是一个句子。"
paragraph = """这是一个段落,
可以由多行组成"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python3

str='123456789'

print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第六个的字符(不包含)
print(str[2:]) # 输出从第三个开始后的所有字符
print(str[1:5:2]) # 输出从第二个开始到第五个且每隔一个的字符(步长为2)
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串

print('------------------------------')

print('hello\nrunoob') # 使用反斜杠(\)+n转义特殊字符
print(r'hello\nrunoob') # 在字符串前面添加一个 r,表示原始字符串,不会发生转义

空行

  • 函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始
  • 空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
    • 空行也是程序代码的一部分。

等待用户输入

  • 执行下面的程序在按回车键后就会等待用户输入:

    1
    2
    3
    #!/usr/bin/python3

    input("\n\n按下 enter 键后退出。")
  • 以上代码中 ,\n\n 在结果输出前会输出两个新的空行。一旦用户按下 enter 键时,程序将退出。

同一行显示多条语句

  • Python 可以在同一行中使用多条语句,语句之间使用分号 ; 分割,以下是一个简单的实例:
    1
    2
    3
    #!/usr/bin/python3

    import sys; x = 'runoob'; sys.stdout.write(x + '\n')

多个语句构成代码组

  • 缩进相同的一组语句构成一个代码块,我们称之代码组
  • 像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组
  • 我们将首行及后面的代码组称为一个子句(clause)
    1
    2
    3
    4
    5
    6
    if expression : 
    suite
    elif expression :
    suite
    else :
    suite

print 输出

  • print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end=””
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/python3

    x="a"
    y="b"
    # 换行输出
    print( x )
    print( y )

    print('---------')
    # 不换行输出
    print( x, end=" " )
    print( y, end=" " )
    print()

import 与 from…import

  • 在 python 用 import 或者 from…import 来导入相应的模块。
  • 将整个模块(somemodule)导入,格式为: import somemodule
  • 从某个模块中导入某个函数,格式为: from somemodule import somefunction
  • 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
  • 将某个模块中的全部函数导入,格式为: from somemodule import *
1
2
3
4
5
6
import sys
print('================Python import mode==========================')
print ('命令行参数为:')
for i in sys.argv:
print (i)
print ('\n python 路径为',sys.path)
1
2
3
4
from sys import argv,path  #  导入特定的成员

print('================python from import===================================')
print('path:',path) # 因为已经导入path成员,所以此处引用时不需要加sys.path

基本数据类型

  • Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
  • 在 Python 中,变量就是变量,它没有类型,我们所说的”类型”是变量所指的内存中对象的类型。
  • 等号(=)用来给变量赋值。
  • 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值

标准数据类型

  • Python3 中常见的数据类型有:

    • Number(数字)
    • String(字符串)
    • bool(布尔类型)
    • List(列表)
    • Tuple(元组)
    • Set(集合)
    • Dictionary(字典)
  • Python3 的六个标准数据类型中:

    • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
    • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

数值运算

  • 注:
    1. Python可以同时为多个变量赋值,如a, b = 1, 2。
    2. 一个变量可以通过赋值指向不同类型的对象。
    3. 数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。
    4. 在混合计算时,Python会把整型转换成为浮点数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> 5 + 4  # 加法
9
>>> 4.3 - 2 # 减法
2.3
>>> 3 * 7  # 乘法
21
>>> 2 / 4  # 除法,得到一个浮点数
0.5
>>> 2 // 4 # 除法,得到一个整数
0
>>> 17 % 3 # 取余
2
>>> 2 ** 5 # 乘方
32

List(列表)

  • List(列表) 是 Python 中使用最频繁的数据类型。

  • 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)

  • 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。

  • 和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表

  • 列表截取的语法格式如下:

    • 变量[头下标:尾下标]
  • 注意:

    1. List写在方括号之间,元素用逗号隔开。
    2. 和字符串一样,list可以被索引和切片。
    3. List可以使用+操作符进行拼接。
    4. List中的元素是可以改变的。

Tuple(元组)

  • 元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开

  • 元组中的元素类型也可以不相同:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #!/usr/bin/python3

    tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2  )
    tinytuple = (123, 'runoob')

    print (tuple)             # 输出完整元组
    print (tuple[0])          # 输出元组的第一个元素
    print (tuple[1:3])        # 输出从第二个元素开始到第三个元素
    print (tuple[2:])         # 输出从第三个元素开始的所有元素
    print (tinytuple * 2)     # 输出两次元组
    print (tuple + tinytuple) # 连接元组
  • 注意:

    1. 与字符串一样,元组的元素不能修改。
    2. 元组也可以被索引和切片,方法一样。
    3. 注意构造包含 0 或 1 个元素的元组的特殊语法规则。
    4. 元组也可以使用+操作符进行拼接。

Set(集合)

  • Python 中的集合(Set)是一种无序、可变的数据类型,用于存储唯一的元素。
  • 集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作
  • 在 Python 中,集合使用大括号 {} 表示,元素之间用逗号 , 分隔
  • 另外,也可以使用 set() 函数创建集合
  • 注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
  • 创建格式:
    1
    2
    3
    parame = {value01,value02,...}
    或者
    set(value)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/python3

sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}

print(sites)   # 输出集合,重复的元素被自动去掉

# 成员测试
if 'Runoob' in sites :
    print('Runoob 在集合中')
else :
    print('Runoob 不在集合中')


# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')

print(a)

print(a - b)     # a 和 b 的差集

print(a | b)     # a 和 b 的并集

print(a & b)     # a 和 b 的交集

print(a ^ b)     # a 和 b 中不同时存在的元素

Dictionary(字典)

  • 字典(dictionary)是Python中另一个非常有用的内置数据类型
  • 列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
  • 字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合
  • 键(key)必须使用不可变类型。
  • 在同一个字典中,键(key)必须是唯一的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/python3

dict = {}
dict['one'] = "1 - 菜鸟教程"
dict[2]     = "2 - 菜鸟工具"

tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'}


print (dict['one'])       # 输出键为 'one' 的值
print (dict[2])           # 输出键为 2 的值
print (tinydict)          # 输出完整的字典
print (tinydict.keys())   # 输出所有键
print (tinydict.values()) # 输出所有值
  • 构造函数 dict() 可以直接从键值对序列中构建字典如下:

    1
    2
    3
    4
    5
    6
    >>> dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)])
    {'Runoob': 1, 'Google': 2, 'Taobao': 3}
    >>> {x: x**2 for x in (2, 4, 6)}
    {2: 4, 4: 16, 6: 36}
    >>> dict(Runoob=1, Google=2, Taobao=3)
    {'Runoob': 1, 'Google': 2, 'Taobao': 3}
  • 字典类型也有一些内置的函数,例如 clear()、keys()、values() 等。

  • 注意:

    1. 字典是一种映射类型,它的元素是键值对。
    2. 字典的关键字必须为不可变类型,且不能重复。
    3. 创建空字典使用 { }

bytes类型

  • 在 Python3 中,bytes 类型表示的是不可变的二进制序列(byte sequence)。

  • 与字符串类型不同的是,bytes 类型中的元素是整数值(0 到 255 之间的整数),而不是 Unicode 字符。

  • bytes 类型通常用于处理二进制数据,比如图像文件、音频文件、视频文件等等。在网络编程中,也经常使用 bytes 类型来传输二进制数据。

  • 创建 bytes 对象的方式有多种,最常见的方式是使用 b 前缀:

  • 此外,也可以使用 bytes() 函数将其他类型的对象转换为 bytes 类型。bytes() 函数的第一个参数是要转换的对象,第二个参数是编码方式,如果省略第二个参数,则默认使用 UTF-8 编码:

    1
    x = bytes("hello", encoding="utf-8")
  • 与字符串类型类似,bytes 类型也支持许多操作和方法,如切片、拼接、查找、替换等等。同时,由于 bytes 类型是不可变的,因此在进行修改操作时需要创建一个新的 bytes 对象。例如:

    1
    2
    3
    x = b"hello"
    y = x[1:3]  # 切片操作,得到 b"el"
    z = x + b"world"  # 拼接操作,得到 b"helloworld"

逻辑运算符

  • Python语言支持逻辑运算符,以下假设变量 a 为 10, b为 20:

  • and : x and y

    • 布尔”与” - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值。
    • (a and b) 返回 20。
  • or : x or y

    • 布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。
    • (a or b) 返回 10。
  • not : not x

    • 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。
    • not(a and b) 返回 False

成员运算符

  • 除了以上的一些运算符之外,Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组

  • in

    • 如果在指定的序列中找到值返回 True,否则返回 False。
    • x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
  • not in

    • 如果在指定的序列中没有找到值返回 True,否则返回 False。
    • x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。

身份运算符

  • 身份运算符用于比较两个对象的存储单元

  • is

    • is 是判断两个标识符是不是引用自一个对象
    • x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
  • is not

    • is not 是判断两个标识符是不是引用自不同对象
    • x is not y , 类似 id(x) != id(y)。如果引用的不是同一个对象则返回结果 True,否则返回 False。

if语句

  • Python中if语句的一般形式如下所示:

    1
    2
    3
    4
    5
    6
    if condition_1:
    statement_block_1
    elif condition_2:
    statement_block_2
    else:
    statement_block_3
  • Python 中用 elif 代替了 else if,所以if语句的关键字为:if – elif – else。

  • 注意:

    1. 每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语句块。
    2. 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
    3. 在 Python 中没有 switch…case 语句,但在 Python3.10 版本添加了 match…case,功能也类似

match…case

  • Python 3.10 增加了 match…case 的条件判断,不需要再使用一连串的 if-else 来判断了

  • match 后的对象会依次与 case 后的内容进行匹配,如果匹配成功,则执行匹配到的表达式,否则直接跳过,_ 可以匹配一切。

  • 语法格式如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    match subject:
    case <pattern_1>:
    <action_1>
    case <pattern_2>:
    <action_2>
    case <pattern_3>:
    <action_3>
    case _:
    <action_wildcard>
  • case _: 类似于 C 和 Java 中的 default:,当其他 case 都无法匹配时,匹配这条,保证永远会匹配成功。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def http_error(status):
        match status:
            case 400:
                return "Bad request"
            case 404:
                return "Not found"
            case 418:
                return "I'm a teapot"
            case _:
                return "Something's wrong with the internet"

    mystatus=400
    print(http_error(400))

while循环

  • Python 中 while 语句的一般形式:

    1
    2
    while 判断条件(condition):
    执行语句(statements)……
  • 同样需要注意冒号和缩进。另外,在 Python 中没有 do..while 循环。

  • 以下实例使用了 while 来计算 1 到 100 的总和:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #!/usr/bin/env python3

    n = 100

    sum = 0
    counter = 1
    while counter <= n:
    sum = sum + counter
    counter += 1

    print("1 到 %d 之和为: %d" % (n,sum))
  • 无限循环

    • 我们可以通过设置条件表达式永远不为 false 来实现无限循环,实例如下:
      1
      2
      3
      4
      5
      6
      7
      8
      #!/usr/bin/python3

      var = 1
      while var == 1 : # 表达式永远为 true
      num = int(input("输入一个数字 :"))
      print ("你输入的数字是: ", num)

      print ("Good bye!")
  • while 循环使用 else 语句

    • 如果 while 后面的条件语句为 false 时,则执行 else 的语句块。
    • 语法格式如下:
      1
      2
      3
      4
      while <expr>:
      <statement(s)>
      else:
      <additional_statement(s)>
  • expr 条件语句为 true 则执行 statement(s) 语句块,如果为 false,则执行 additional_statement(s)。

for 语句

  • Python for 循环可以遍历任何可迭代对象,如一个列表或者一个字符串

  • for循环的一般格式如下:

    1
    2
    3
    4
    for <variable> in <sequence>:
    <statements>
    else:
    <statements>
  • 在 Python 中,for…else 语句用于在循环结束后执行一段代码。

    1
    2
    3
    4
    for item in iterable:
    # 循环主体
    else:
    # 循环结束后执行的代码
  • 当循环执行完毕(即遍历完 iterable 中的所有元素)后,会执行 else 子句中的代码,如果在循环过程中遇到了 break 语句,则会中断循环,此时不会执行 else 子句。

range()函数

  • 如果你需要遍历数字序列,可以使用内置 range() 函数。它会生成数列

break 和 continue 语句及循环中的 else 子句

  • break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
  • continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。

pass 语句

  • Python pass是空语句,是为了保持程序结构的完整性。
  • pass 不做任何事情,一般用做占位语句,如下实例
    1
    2
    >>>while True:
    ... pass # 等待键盘中断 (Ctrl+C)

end 关键字

  • 关键字end可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符,实例如下:
    1
    2
    3
    4
    5
    6
    7
    8
    #!/usr/bin/python3

    # Fibonacci series: 斐波纳契数列
    # 两个元素的总和确定了下一个数
    a, b = 0, 1
    while b < 1000:
    print(b, end=',')
    a, b = b, a+b

推导式

  • Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。
  • Python 支持各种数据结构的推导式:
    • 列表(list)推导式
    • 字典(dict)推导式
    • 集合(set)推导式
    • 元组(tuple)推导式

列表推导式

  • 列表推导式格式为:

    1
    2
    3
    4
    5
    6
    7
    [表达式 for 变量 in 列表] 
    [out_exp_res for out_exp in input_list]

    或者

    [表达式 for 变量 in 列表 if 条件]
    [out_exp_res for out_exp in input_list if condition]
  • out_exp_res:列表生成元素表达式,可以是有返回值的函数。

  • for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中。

  • if condition:条件语句,可以过滤列表中不符合条件的值。

字典推导式

  • 字典推导基本格式:
    1
    2
    3
    4
    5
    { key_expr: value_expr for value in collection }



    { key_expr: value_expr for value in collection if condition }

集合推导式

  • 集合推导式基本格式:
    1
    2
    3
    { expression for item in Sequence }

    { expression for item in Sequence if conditional }

元组推导式(生成器表达式)

  • 元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组

  • 元组推导式基本格式:

    1
    2
    3
    (expression for item in Sequence )

    (expression for item in Sequence if conditional )
  • 元组推导式和列表推导式的用法也完全相同,只是元组推导式是用 () 圆括号将各部分括起来,而列表推导式用的是中括号 [],另外元组推导式返回的结果是一个生成器对象

迭代器与生成器

迭代器

  • 迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。
  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:iter() 和 next()。

生成器

  • 在 Python 中,使用了 yield 的函数被称为生成器(generator)。
  • yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。
  • 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
  • 当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。
  • 然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。
  • 调用一个生成器函数,返回的是一个迭代器对象

函数

  • 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

  • 函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数

  • 你可以定义一个由自己想要功能的函数,以下是简单的规则:

    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
    • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号 : 起始,并且缩进。
    • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
  • Python 定义函数使用 def 关键字,一般格式如下:

    1
    2
    def 函数名(参数列表):
    函数体
  • 定义一个函数:给了函数一个名称,指定了函数里包含的参数,和代码块结构。

  • 这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行

参数传递

  • 在 python 中,类型属于对象,对象有不同类型的区分,变量是没有类型的:
    1
    2
    3
    a=[1,2,3]

    a="Runoob"
  • 以上代码中,[1,2,3] 是 List 类型,”Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象

可更改(mutable)与不可更改(immutable)对象

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。

  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

  • python 函数的参数传递:

    • 不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
    • 可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
  • python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象

参数

  • 以下是调用函数时可使用的正式参数类型:
    • 必需参数
    • 关键字参数
    • 默认参数
    • 不定长参数

必需参数

  • 必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
  • 调用 printme() 函数,你必须传入一个参数,不然会出现语法错误:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/python3

    #可写函数说明
    def printme( str ):
    "打印任何传入的字符串"
    print (str)
    return

    # 调用 printme 函数,不加参数会报错
    printme()

关键字参数

  • 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
  • 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
  • 以下实例在函数 printme() 调用时使用参数名:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/python3

    #可写函数说明
    def printme( str ):
    "打印任何传入的字符串"
    print (str)
    return

    #调用printme函数
    printme( str = "菜鸟教程")

默认参数

  • 调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/python3

    #可写函数说明
    def printinfo( name, age = 35 ):
    "打印任何传入的字符串"
    print ("名字: ", name)
    print ("年龄: ", age)
    return

    #调用printinfo函数
    printinfo( age=50, name="runoob" )
    print ("------------------------")
    printinfo( name="runoob" )

不定长参数

  • 你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下:

    1
    2
    3
    4
    def functionname([formal_args,] *var_args_tuple ):
    "函数_文档字符串"
    function_suite
    return [expression]
  • 加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #!/usr/bin/python3

    # 可写函数说明
    def printinfo( arg1, *vartuple ):
    "打印任何传入的参数"
    print ("输出: ")
    print (arg1)
    print (vartuple)

    # 调用printinfo 函数
    printinfo( 70, 60, 50 )

匿名函数

  • Python 使用 lambda 来创建匿名函数。
  • 所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
    • lambda 只是一个表达式,函数体比 def 简单很多。
    • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
    • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
    • 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,内联函数的目的是调用小函数时不占用栈内存从而减少函数调用的开销,提高代码的执行速度。

语法

  • lambda 函数的语法只包含一个语句,如下:

    1
    lambda [arg1 [,arg2,.....argn]]:expression
  • 设置参数 a 加上 10:

    1
    2
    x = lambda a : a + 10
    print(x(5))
  • 我们可以将匿名函数封装在一个函数内,这样可以使用同样的代码来创建多个匿名函数。

  • 以下实例将匿名函数封装在 myfunc 函数中,通过传入不同的参数来创建不同的匿名函数:

    1
    2
    3
    4
    5
    6
    7
    8
    def myfunc(n):
    return lambda a : a * n

    mydoubler = myfunc(2)
    mytripler = myfunc(3)

    print(mydoubler(11))
    print(mytripler(11))

return 语句

  • return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None。之前的例子都没有示范如何返回数值,以下实例演示了 return 语句的用法:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/python3

    # 可写函数说明
    def sum( arg1, arg2 ):
    # 返回2个参数的和."
    total = arg1 + arg2
    print ("函数内 : ", total)
    return total

    # 调用sum函数
    total = sum( 10, 20 )
    print ("函数外 : ", total)

强制位置参数

  • Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。

  • 在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:

    1
    2
    def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)
  • 以下使用方法是正确的:

    1
    f(10, 20, 30, d=40, e=50, f=60)
  • 以下使用方法会发生错误:

    1
    2
    f(10, b=20, c=30, d=40, e=50, f=60)   # b 不能使用关键字参数的形式
    f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式

模块

  • 在前面的几个章节中我们基本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。
  • 为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
  • 模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。

import 语句

  • 想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下:

    1
    import module1[, module2[,... moduleN]
  • 当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。

  • 搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support,需要把命令放在脚本的顶端:

    1
    2
    3
    4
    5
    6
    #!/usr/bin/python3
    # Filename: support.py

    def print_func( par ):
    print ("Hello : ", par)
    return

from … import 语句

  • Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:
    1
    from modname import name1[, name2[, ... nameN]]

from … import * 语句

  • 把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
    1
    from modname import *

name 属性

  • 一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。

    1
    2
    3
    4
    5
    6
    7
    #!/usr/bin/python3
    # Filename: using_name.py

    if __name__ == '__main__':
    print('程序自身在运行')
    else:
    print('我来自另一模块')
  • 每个模块都有一个__name__属性,当其值是’main‘时,表明该模块自身在运行,否则是被引入。

  • namemain 底下是双下划线, _ _ 是这样去掉中间的那个空格。

dir() 函数

  • 内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    >>> import fibo, sys
    >>> dir(fibo)
    ['__name__', 'fib', 'fib2']
    >>> dir(sys)
    ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
    '__package__', '__stderr__', '__stdin__', '__stdout__',
    '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
    '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
    'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
    'call_tracing', 'callstats', 'copyright', 'displayhook',
    'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
    'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
    'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
    'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
    'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
    'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
    'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
    'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
    'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
    'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
    'thread_info', 'version', 'version_info', 'warnoptions']
  • 如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> a = [1, 2, 3, 4, 5]
    >>> import fibo
    >>> fib = fibo.fib
    >>> dir() # 得到一个当前模块中定义的属性列表
    ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
    >>> a = 5 # 建立一个新的变量 'a'
    >>> dir()
    ['__builtins__', '__doc__', '__name__', 'a', 'sys']
    >>>
    >>> del a # 删除变量名a
    >>>
    >>> dir()
    ['__builtins__', '__doc__', '__name__', 'sys']
    >>>

标准模块

  • Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的”库参考文档”)。
  • 有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。
  • 这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。
  • 应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> import sys
    >>> sys.ps1
    '>>> '
    >>> sys.ps2
    '... '
    >>> sys.ps1 = 'C> '
    C> print('Runoob!')
    Runoob!
    C>

  • 包是一种管理 Python 模块命名空间的形式,采用”点模块名称”。

  • 比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。

  • 就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

  • 这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。

  • 不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个”包”)。

  • 现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。

  • 并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。

  • 这里给出了一种可能的包结构(在分层的文件系统中):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    sound/                          顶层包
    __init__.py 初始化 sound 包
    formats/ 文件格式转换子包
    __init__.py
    wavread.py
    wavwrite.py
    aiffread.py
    aiffwrite.py
    auread.py
    auwrite.py
    ...
    effects/ 声音效果子包
    __init__.py
    echo.py
    surround.py
    reverse.py
    ...
    filters/ filters 子包
    __init__.py
    equalizer.py
    vocoder.py
    karaoke.py
    ...
  • 在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

  • 目录只有包含一个叫做 init.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。

  • 最简单的情况,放一个空的 :file:init.py就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。

  • 用户可以每次只导入一个包里面的特定模块,比如:

    1
    import sound.effects.echo
  • 这将会导入子模块:sound.effects.echo。 他必须使用全名去访问:

    1
    sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
  • 还有一种导入子模块的方法是:

    1
    from sound.effects import echo
  • 这同样会导入子模块: echo,并且他不需要那些冗长的前缀,所以他可以这样使用:

    1
    echo.echofilter(input, output, delay=0.7, atten=4)
  • 还有一种变化就是直接导入一个函数或者变量:

    1
    from sound.effects.echo import echofilter
  • 同样的,这种方法会导入子模块: echo,并且可以直接使用他的 echofilter() 函数:

    1
    echofilter(input, output, delay=0.7, atten=4)
  • 注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。

  • import 语法会首先把 item 当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,抛出一个 :exc:ImportError 异常。

  • 反之,如果使用形如 import item.subitem.subsubitem 这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。

输入输出

输出格式美化

  • Python两种输出值的方式: 表达式语句和 print() 函数。
  • 第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用。
  • 如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。
  • 如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。
    • str(): 函数返回一个用户易读的表达形式。
    • repr(): 产生一个解释器易读的表达形式。

旧式字符串格式化

  • % 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串. 例如:

    1
    2
    3
    >>> import math
    >>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
    常量 PI 的值近似为:3.142
  • 因为 str.format() 是比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().

读取键盘输入

  • Python 提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘。
    1
    2
    3
    4
    #!/usr/bin/python3

    str = input("请输入:")
    print ("你输入的内容是: ", str)

读和写文件

  • open() 将会返回一个 file 对象,基本语法格式如下:

    1
    open(filename, mode)
    • filename:包含了你要访问的文件名称的字符串值。
    • mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
  • 以下实例将字符串写入到文件 foo.txt 中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/usr/bin/python3

    # 打开一个文件
    f = open("/tmp/foo.txt", "w")

    f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )

    # 关闭打开的文件
    f.close()
    • 第一个参数为要打开的文件名。
    • 第二个参数描述文件如何使用的字符。 mode 可以是 ‘r’ 如果文件只读, ‘w’ 只用于写 (如果存在同名文件则将被删除), 和 ‘a’ 用于追加文件内容; 所写的任何数据都会被自动增加到末尾. ‘r+’ 同时用于读写。 mode 参数是可选的; ‘r’ 将是默认值。

文件对象的方法

  • 本节中剩下的例子假设已经创建了一个称为 f 的文件对象。

  • f.read()

  • 为了读取一个文件的内容,调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。

  • size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。

  • 以下实例假定文件 foo.txt 已存在(上面实例中已创建):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/python3

    # 打开一个文件
    f = open("/tmp/foo.txt", "r")

    str = f.read()
    print(str)

    # 关闭打开的文件
    f.close()
  • f.readline()

  • f.readline() 会从文件中读取单独的一行。换行符为 ‘\n’。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/python3

    # 打开一个文件
    f = open("/tmp/foo.txt", "r")

    str = f.readline()
    print(str)

    # 关闭打开的文件
    f.close()
  • f.readlines()

  • f.readlines() 将返回该文件中包含的所有行。

  • 如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/python3

    # 打开一个文件
    f = open("/tmp/foo.txt", "r")

    str = f.readlines()
    print(str)

    # 关闭打开的文件
    f.close()
  • f.write()

  • f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/usr/bin/python3

    # 打开一个文件
    f = open("/tmp/foo.txt", "w")

    num = f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
    print(num)
    # 关闭打开的文件
    f.close()
  • f.tell()

  • f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。

  • f.seek()

  • 如果要改变文件指针当前的位置, 可以使用 f.seek(offset, from_what) 函数。

  • from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:

    • seek(x,0) : 从起始位置即文件首行首字符开始移动 x 个字符
    • seek(x,1) : 表示从当前位置往后移动x个字符
    • seek(-x,2):表示从文件的结尾往前移动x个字符
  • from_what 值为默认为0,即文件开头。下面给出一个完整的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> f = open('/tmp/foo.txt', 'rb+')
    >>> f.write(b'0123456789abcdef')
    16
    >>> f.seek(5)     # 移动到文件的第六个字节
    5
    >>> f.read(1)
    b'5'
    >>> f.seek(-3, 2) # 移动到文件的倒数第三字节
    13
    >>> f.read(1)
    b'd'
  • f.close()

  • 在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。

  • 当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常。

    1
    2
    3
    4
    5
    >>> f.close()
    >>> f.read()
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: I/O operation on closed file
  • 当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:

    1
    2
    3
    4
    >>> with open('/tmp/foo.txt', 'r') as f:
    ...     read_data = f.read()
    >>> f.closed
    True

pickle 模块

  • python的pickle模块实现了基本的数据序列和反序列化。

  • 通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

  • 通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

  • 基本接口:

    1
    pickle.dump(obj, file, [,protocol])

python3 OS 文件/目录 方法

  • os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:
    序号 方法及描述
    1
    os.access(path, mode)

检验权限模式
2
os.chdir(path)

改变当前工作目录
3
os.chflags(path, flags)

设置路径的标记为数字标记。
4
os.chmod(path, mode)

更改权限
5
os.chown(path, uid, gid)

更改文件所有者
6
os.chroot(path)

改变当前进程的根目录
7
os.close(fd)

关闭文件描述符 fd
8
os.closerange(fd_low, fd_high)

关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略
9
os.dup(fd)

复制文件描述符 fd
10
os.dup2(fd, fd2)

将一个文件描述符 fd 复制到另一个 fd2
11
os.fchdir(fd)

通过文件描述符改变当前工作目录
12
os.fchmod(fd, mode)

改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。
13
os.fchown(fd, uid, gid)

修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。
14
os.fdatasync(fd)

强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。
15
os.fdopen(fd[, mode[, bufsize]])

通过文件描述符 fd 创建一个文件对象,并返回这个文件对象
16
os.fpathconf(fd, name)

返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。
17
os.fstat(fd)

返回文件描述符fd的状态,像stat()。
18
os.fstatvfs(fd)

返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。
19
os.fsync(fd)

强制将文件描述符为fd的文件写入硬盘。
20
os.ftruncate(fd, length)

裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。
21
os.getcwd()

返回当前工作目录
22
os.getcwdb()

返回一个当前工作目录的Unicode对象
23
os.isatty(fd)

如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。
24
os.lchflags(path, flags)

设置路径的标记为数字标记,类似 chflags(),但是没有软链接
25
os.lchmod(path, mode)

修改连接文件权限
26
os.lchown(path, uid, gid)

更改文件所有者,类似 chown,但是不追踪链接。
27
os.link(src, dst)

创建硬链接,名为参数 dst,指向参数 src
28
os.listdir(path)

返回path指定的文件夹包含的文件或文件夹的名字的列表。
29
os.lseek(fd, pos, how)

设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效
30
os.lstat(path)

像stat(),但是没有软链接
31
os.major(device)

从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。
32
os.makedev(major, minor)

以major和minor设备号组成一个原始设备号
33
os.makedirs(path[, mode])

递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。
34
os.minor(device)

从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。
35
os.mkdir(path[, mode])

以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。
36
os.mkfifo(path[, mode])

创建命名管道,mode 为数字,默认为 0666 (八进制)
37
os.mknod(filename[, mode=0600, device])
创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。

38
os.open(file, flags[, mode])

打开一个文件,并且设置需要的打开选项,mode参数是可选的
39
os.openpty()

打开一个新的伪终端对。返回 pty 和 tty的文件描述符。
40
os.pathconf(path, name)

返回相关文件的系统配置信息。
41
os.pipe()

创建一个管道. 返回一对文件描述符(r, w) 分别为读和写
42
os.popen(command[, mode[, bufsize]])

从一个 command 打开一个管道
43
os.read(fd, n)

从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。
44
os.readlink(path)

返回软链接所指向的文件
45
os.remove(path)

删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。
46
os.removedirs(path)

递归删除目录。
47
os.rename(src, dst)

重命名文件或目录,从 src 到 dst
48
os.renames(old, new)

递归地对目录进行更名,也可以对文件进行更名。
49
os.rmdir(path)

删除path指定的空目录,如果目录非空,则抛出一个OSError异常。
50
os.stat(path)

获取path指定的路径的信息,功能等同于C API中的stat()系统调用。
51
os.stat_float_times([newvalue])
决定stat_result是否以float对象显示时间戳

52
os.statvfs(path)

获取指定路径的文件系统统计信息
53
os.symlink(src, dst)

创建一个软链接
54
os.tcgetpgrp(fd)

返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组
55
os.tcsetpgrp(fd, pg)

设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。
56
os.tempnam([dir[, prefix]])

Python3 中已删除。返回唯一的路径名用于创建临时文件。
57
os.tmpfile()

Python3 中已删除。返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。
58
os.tmpnam()

Python3 中已删除。为创建一个临时文件返回一个唯一的路径
59
os.ttyname(fd)

返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。
60
os.unlink(path)

删除文件路径
61
os.utime(path, times)

返回指定的path文件的访问和修改的时间。
62
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])

输出在文件夹中的文件名通过在树中游走,向上或者向下。
63
os.write(fd, str)

写入字符串到文件描述符 fd中. 返回实际写入的字符串长度
64
os.path 模块

获取文件的属性信息。
65
os.pardir()

获取当前目录的父目录,以字符串形式显示目录名。
66
os.replace()

重命名文件或目录。

错误和异常

  • Python 有两种错误很容易辨认:语法错误和异常。
  • Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。

异常

  • 即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
  • 错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息

异常处理 try/except

  • try 语句按照如下方式工作;

    • 首先,执行 try 子句(在关键字 try 和关键字 except 之间的语句)。
    • 如果没有异常发生,忽略 except 子句,try 子句执行后结束。
    • 如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行。
    • 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中。
  • 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行

  • 处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

  • 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组

try/except…else

  • try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后

  • else 子句将在 try 子句没有发生任何异常的时候执行。

try-finally 语句

  • try-finally 语句无论是否发生异常都将执行最后的代码。

抛出异常

  • Python 使用 raise 语句抛出一个指定的异常。

  • raise语法格式如下:

    1
    raise [Exception [, args [, traceback]]]
  • raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。

  • 如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出

用户自定义异常

  • 你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:

定义清理行为

  • try 语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。 例如:

预定义的清理行为

  • 一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行

简介

  • pytorch框架

Python pytorch 是什么

PyTorch 是一个用于深度学习的开源机器学习库,由Facebook的人工智能研究小组开发。它提供了一个灵活而直观的深度学习开发平台,支持动态计算图,这使得模型的定义和训练更加直观和灵活。

以下是 PyTorch 的一些主要特点:

  1. 动态计算图: PyTorch 使用动态计算图,这意味着计算图是在运行时构建的。这使得模型的定义更加灵活,方便调试和动态修改模型结构。

  2. 张量操作: PyTorch 提供了一个名为 torch.Tensor 的多维数组对象,支持丰富的张量操作。张量是 PyTorch 中用于表示数据的核心数据结构。

  3. 自动微分: PyTorch 自带了自动微分系统,称为 Autograd。它能够自动计算张量上的梯度,这对于训练神经网络和优化模型参数非常有用。

  4. 模块化设计: PyTorch 的模块化设计使得构建和训练复杂的深度学习模型变得更加简单。你可以通过组合不同的模块来构建自己的模型。

  5. 丰富的生态系统: PyTorch 生态系统包含了许多用于深度学习的工具和库,包括 TorchVision(用于计算机视觉任务的库)、TorchText(用于文本处理的库)等。

  6. 易用性: PyTorch 的 API 设计注重用户友好性,其接口简单而直观,使得新手和专业人士都能够轻松上手。

使用 PyTorch,你可以构建、训练和部署各种深度学习模型,包括卷积神经网络(CNN)、循环神经网络(RNN)、变换器(Transformer)等。由于其灵活性和易用性,PyTorch 在学术界和工业界都广泛应用。

Python pytorch库 详解

PyTorch是一个用于深度学习的开源机器学习库,它提供了一个灵活而直观的深度学习开发平台。以下是对PyTorch库的一些详细解释:

  1. torch.Tensor: torch.Tensor 是PyTorch的核心数据结构,用于表示多维数组。它支持各种数学运算,具有自动微分功能,允许用户轻松地计算梯度。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import torch

    # 创建一个张量
    x = torch.tensor([[1, 2, 3], [4, 5, 6]])

    # 加法操作
    y = x + 2

    # 自动微分
    y.backward()
  2. torch.nn: torch.nn 模块提供了用于构建神经网络的类和函数。用户可以通过继承torch.nn.Module创建自定义的神经网络模型,并使用各种层(如线性层、卷积层、循环层等)构建模型。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import torch
    import torch.nn as nn

    class SimpleModel(nn.Module):
    def __init__(self):
    super(SimpleModel, self).__init__()
    self.fc = nn.Linear(10, 5)

    def forward(self, x):
    return self.fc(x)

    model = SimpleModel()
  3. torch.optim: torch.optim 模块提供了各种优化算法,例如SGD、Adam、RMSprop等,用于优化模型的参数。用户可以选择适合自己问题的优化器。例如:

    1
    2
    3
    import torch.optim as optim

    optimizer = optim.SGD(model.parameters(), lr=0.01)
  4. torch.autograd: torch.autograd 模块提供了自动微分的功能,用于计算梯度。通过使用requires_grad=True的张量,PyTorch可以追踪相关的计算,并生成计算图,从而计算梯度。例如:

    1
    2
    3
    4
    5
    6
    import torch

    x = torch.tensor([2.0], requires_grad=True)
    y = x ** 2
    y.backward()
    print(x.grad)
  5. torch.utils.data: torch.utils.data 模块提供了用于数据处理和加载的工具,包括DatasetDataLoader。用户可以自定义数据集,然后使用DataLoader来加载批量数据。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    import torch
    from torch.utils.data import Dataset, DataLoader

    class CustomDataset(Dataset):
    # 定义自己的数据集

    dataset = CustomDataset()
    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
  6. torchvision: torchvision 库提供了用于计算机视觉任务的工具和数据集。其中包括常用的数据集、模型和图像转换函数。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import torchvision.transforms as transforms
    from torchvision.datasets import CIFAR10
    from torch.utils.data import DataLoader

    transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
    ])

    dataset = CIFAR10(root='./data', train=True, download=True, transform=transform)
    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

这只是 PyTorch 库中的一部分功能,它提供了许多其他工具和库,以支持广泛的深度学习任务。详细的文档和示例可以在 PyTorch 的官方网站上找到。

简介

  • python3中常见的问题

python3 列表中省略号后面跟逗号加数字是什么意思

在 Python 中,省略号(Ellipsis)后面跟着逗号和数字表示一个带有省略号的扩展切片。

这种形式的扩展切片通常在多维数组(如 NumPy 数组)中使用,用来指定对多个维度的切片操作。

例如,在一个二维列表中,省略号后面跟着逗号和数字表示对所有维度的切片,但是指定其中一个维度的索引值:

1
2
3
4
5
my_list = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

print(my_list[..., 1]) # 输出为 [2, 5, 8]

这个例子中,... 表示对所有维度的切片操作,后面的逗号和数字 1 指定了对第二维度(列)进行切片,并且取出了每个子列表的第二个元素。

简介

  • Tornado框架相关笔记

Tornado是什么

  • Python3 Tornado是一个基于Python语言的异步网络框架,它可以用于编写高性能的Web服务器和Web应用程序。Tornado的主要特点是其非阻塞的I/O模型,使得它在处理大量并发连接时能够表现出色。它也被广泛用于实时Web服务、长连接应用和WebSocket等场景。

python3 Tornado详解

Python的Tornado框架是一个强大的异步网络库,它专注于高性能和可伸缩性。下面是对Tornado的一些详细解释:

  1. 异步IO:Tornado采用了异步的I/O模型,使用非阻塞的事件循环来处理并发连接。这意味着它可以在不同的客户端连接之间快速切换,而不会阻塞整个进程。

  2. Web框架:Tornado提供了一个简单而灵活的Web框架,可以用于构建Web应用程序。它包含了路由、请求处理器、模板引擎等功能,使得开发Web应用变得更加容易。

  3. 异步HTTP客户端和服务器:除了作为Web框架,Tornado还提供了异步的HTTP客户端和服务器,可以用于构建各种类型的网络应用,包括代理、爬虫等。

  4. WebSocket支持:Tornado支持WebSocket协议,这使得它可以用于构建实时的Web应用,如聊天应用、实时数据展示等。

  5. 协程支持:Tornado支持使用Python的协程来编写异步代码,这使得编写异步程序更加简单和直观。

  6. 性能优化:Tornado在设计上注重性能和可伸缩性,它的事件循环机制和非阻塞IO可以有效地处理大量的并发连接,使得应用程序可以轻松地应对高负载的情况。

总的来说,Tornado是一个功能丰富且性能出色的异步网络库,适用于构建各种类型的网络应用。

python3 Tornado安装

安装 Tornado 可以通过 pip 工具来完成。如果你已经安装了 Python3 和 pip,只需在命令行中运行以下命令:

1
pip install tornado

这会自动下载并安装 Tornado 及其依赖项。安装完成后,你就可以在 Python 中使用 Tornado 框架了。

python3 Tornado 示例

以下是一个简单的Python 3 Tornado示例,演示了如何创建一个简单的Web服务器,监听端口并返回 “Hello, World!” 消息给客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, World!")

def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])

if __name__ == "__main__":
app = make_app()
app.listen(8888)
print("Server is running at http://localhost:8888")
tornado.ioloop.IOLoop.current().start()

在这个示例中,我们首先导入了Tornado的必要模块。然后,我们定义了一个名为MainHandler的请求处理器类,它继承自tornado.web.RequestHandler。在MainHandler类中,我们定义了一个get()方法来处理HTTP GET请求,并使用self.write()方法向客户端返回 “Hello, World!” 消息。

接着,我们定义了一个make_app()函数来创建Tornado应用程序对象。在这个函数中,我们通过tornado.web.Application类来创建一个应用程序实例,并指定了一个URL路由映射,将”/“路径映射到MainHandler类。

最后,在if __name__ == "__main__":块中,我们创建了应用程序对象,并通过app.listen()方法指定了服务器监听的端口(在这里是8888)。然后,我们启动了Tornado的事件循环,使得服务器可以一直运行并监听来自客户端的HTTP请求。

你可以运行这个示例代码,然后在浏览器中访问”http://localhost:8888",就会看到 “Hello, World!” 消息返回给你。

简介

  • ultralytics库

Python ultralytics 是什么

Ultralytics 是一个开源的深度学习工具库,专注于计算机视觉任务。它为研究人员和开发者提供了一系列用于训练、评估和部署深度学习模型的工具和实用程序。Ultralytics 最为人熟知的是其与目标检测、语义分割和其他计算机视觉任务相关的支持。

Ultralytics 提供了一个名为 YOLOv5(You Only Look Once,版本 5)的目标检测框架,这是一个快速且高效的实时目标检测算法。YOLOv5 是在 PyTorch 中实现的,并通过 Ultralytics 提供的工具进行训练和部署。

以下是 Ultralytics 的一些主要特点:

  1. YOLOv5 框架: Ultralytics 提供了 YOLOv5 的实现,支持目标检测任务。YOLOv5 是一种单阶段目标检测算法,具有较快的推理速度和较好的准确性。

  2. 简化的训练流程: Ultralytics 提供了简化的训练流程,使得用户能够轻松地使用自己的数据集进行模型训练。通过简单的配置文件,用户可以指定数据集、模型架构、超参数等信息。

  3. 全面的评估工具: Ultralytics 提供了丰富的评估工具,用于评估模型在不同任务上的性能。这包括目标检测、语义分割等任务。

  4. 模型导出和部署: Ultralytics 支持将训练好的模型导出为 TorchScript 格式,以便在不同平台上进行部署。这使得用户能够在移动设备、边缘设备等环境中使用训练好的模型。

  5. 实时监控和可视化: Ultralytics 提供了实时的训练监控和结果可视化工具,方便用户实时了解模型的训练进度和性能。

要使用 Ultralytics,你可以通过其 GitHub 仓库(https://github.com/ultralytics/yolov5)获取源代码和文档,了解详细的使用说明和示例。请注意,Ultralytics 的主要重点是目标检测任务,如果你有其他计算机视觉任务的需求,可能需要考虑其他专注于该任务的工具库。

Python ultralytics 详解

截至我的知识截止日期(2022年1月),Ultralytics提供了YOLOv5(You Only Look Once,版本5)的实现,是一个用于计算机视觉目标检测的开源库。以下是关于Ultralytics YOLOv5的一些详细信息:

  1. YOLOv5模型: YOLOv5是一种目标检测算法,其特点是在单个前向传播中直接预测图像中的多个边界框及其对应的类别概率。YOLOv5相对于先前版本做了一些改进,包括更高的性能、更好的准确性和更灵活的训练流程。

  2. 模型架构: YOLOv5的架构包括骨干网络(Backbone)、特征金字塔网络(Feature Pyramid Network,FPN)、锚点框(Anchor Boxes)等组件。这些组件的组合使得模型能够有效地检测各种尺度和形状的目标。

  3. 训练流程: Ultralytics提供了一个简单的训练流程,用户可以通过配置文件指定训练参数、数据集路径、模型架构等。训练脚本会加载配置并开始训练过程。用户可以使用自己的数据集进行训练,同时Ultralytics也提供了一些标准的计算机视觉数据集的支持。

  4. 评估工具: Ultralytics提供了全面的评估工具,用户可以使用这些工具评估训练好的模型在测试集上的性能。评估包括计算各种指标,如精度、召回率、F1分数等。

  5. 部署支持: Ultralytics支持将训练好的模型导出为TorchScript格式,这使得用户能够在不同平台上进行模型部署。这对于将模型部署到嵌入式设备或生产环境中是非常有用的。

  6. 实时监控和可视化: Ultralytics提供了实时监控工具,用户可以实时查看模型在训练过程中的性能。此外,Ultralytics还提供了可视化工具,帮助用户直观地理解模型的预测结果。

如果你想深入了解Ultralytics YOLOv5的使用和详细信息,建议查阅官方文档和GitHub仓库。请注意,软件库的更新可能会导致信息的变更,因此建议查看最新版本的文档。

python3 安装ultralytics库

目前(截至我的知识截止日期2022年1月),Ultralytics库是专为YOLOv5目标检测框架设计的,它提供了用于训练、评估和部署YOLOv5模型的工具和实用程序。下面是安装Ultralytics库的步骤:

使用 pip 安装:

1
pip install -U ultralytics

这将会安装最新版本的Ultralytics库。请确保你的Python环境已经安装了pip,如果没有,你需要首先安装pip。

使用源代码安装:

你也可以从Ultralytics的GitHub仓库中获取源代码并安装:

1
2
3
git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip install -U -r requirements.txt

请注意,Ultralytics库对其他一些Python库有依赖关系,因此你可能需要先安装这些依赖。上述命令中的requirements.txt文件列出了这些依赖项。

注意事项:

  1. Ultralytics库可能会更新,因此建议定期检查其GitHub仓库以获取最新版本和文档。

  2. 我的回答基于2022年1月的信息,版本和依赖关系可能发生变化。请查看Ultralytics的GitHub仓库和文档以获取最新的安装说明和使用说明。

  3. 如果你的Python环境有多个版本,请确保你使用的是正确的Python版本(通常是Python 3.x)。

希望这能帮助你成功安装Ultralytics库。

简介

  • zmq通讯组件相关理论基础

概述

  • mq,是消息队列(message queue)的简称,目前有多种消息队列可用,包括RabbitMQ、Kafka等,它们各有特色,可以结合具体的项目需求使用。
  • ZeroMQ简称Zmq,或者0mq,核心引擎由c++编写,是轻量级消息通信库,在对传统的标准socket接口扩展的基础上形成的特色消息通信中间件。
  • Zmq提供了异步消息队列的抽象,具有多种消息通信模式,能够实现消息过滤,能够无缝对接多种传输协议。
  • 简言之,使用socket时,需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而ZMQ屏 蔽了这些细节,让网络编程更简单
  • ZeroMQ是网络通信中新的一层,介于应用层和传输层之间(按照TCP/IP划分),是一个可伸缩层,可并行运行,分散在分布式系统间。
  • 官方描述
    • ZMQ(?MQ、ZeroMQ, 0MQ)看起来像是一套嵌入式的网络链接库,但工作起来更像是一个并发式的框架。它提供的套接字可以在多种协议中传输消息,如线程间、进程间、TCP、广播等。你可以使用套接字构建多对多的连接模式,如扇出、发布-订阅、任务分发、请求-应答等。ZMQ的快速足以胜任集群应用产品。它的异步I/O机制让你能够构建多核应用程序,完成异步消息处理任务。ZMQ有着多语言支持,并能在几乎所有的操作系统上运行。
  • ZMQ是iMatix公司的产品,以LGPLv3开源协议发布。

为什么要使用ZMQ

  • 当今的许多应用程序都包含了跨越某种网络的组件,无论这种网络是局域网还是互联网。因此,许多应用程序开发者最终都会处理某种类型的消息传递

  • 一些开发人员使用消息队列产品,但大多数时候,他们使用TCP或UDP自己做。

  • 这些协议并不难用,但是,​从 A 发送几个字节到 B 和以任何一种可靠的方式处理消息,这两者之间有很大的区别。

  • 让我们来看看当开始使用原始的TCP连接部件的时候,我们要面对的典型问题。任何可复用的消息层都需要解决如下所有这些问题或其中的大部分问题:

    • 我们如何处理I/O呢?
      • ​是让我们的应用程序阻塞,还是在后台处理I/O呢?这是一个关键的设计决策。阻塞式I/O 创建的架构不能很好地扩展,但后台I/O 也是非常难以正确做到的
    • 我们如何处理动态组件(例如,暂时撤除的块)呢?​
      • 我们需要正式将组件划分为“客户端”和“服务器”,并强制该服务器不能撤除吗?那么,如果我们想将服务器连接到服务器时该怎么办呢?我们需要每隔几秒钟就尝试重新连接吗?.
    • ​我们如何表示在线路上的消息呢?​
      • 我们应该怎样将数据组织为帧,才能使得它很容易写入和读取,避免缓冲区溢出,既对小型消息高效,也足以处理非常大的戴着聚会礼帽的跳舞猫的视频呢?
    • ​我们如何处理不能立即传递的消息呢?
      • ​特别是当我们在等待一个组件的联机回应时如何处理呢?我们需要丢弃消息,把它们放入一个数据库,或者把它们放到一个内存队列吗?
    • 我们在哪里存储消息队列呢?​
      • 如果组件从队列中读取很慢,导致我们的队列堆积,这会发生什么情况?我们的策略是什么呢?
    • 我们如何处理丢失的消息呢?
      • ​我们应该等待新的数据,要求重发,还是应该建立某种可靠性层,确保信息不会丢失呢?如果该层本身崩溃了该怎么办呢?
    • 如果我们需要使用一个不同的网络传输,比如说,用多播来取代TCP 单播,或IPv6,该怎么办呢?​我们需要重写应用程序吗?还是将传输抽象到某个层中呢?
    • 我们如何路由消息呢?​我们可以发送同样的消息到多个接收者吗?我们可以发送应答给原来的请求者吗?
    • 我们如何编写出另一种语言的API 呢?
      • ​我们应该重新实现一个线路级协议,还是重新包装一个库?如果是前者,我们怎么能保证协议栈的高效稳定呢?如果是后者,我们又怎么能保证互操作性呢?
    • ​我们应该如何表示数据,以便它可以在不同的架构之间读取呢?​我们应该对数据类型强制执行特定的编码吗?究竟到什么程度,才是消息传递系统的工作,而不是更高一层的工作呢?
    • ​我们应该如何处理网络错误呢?​是等待并重试,默默地忽略它们,还是终止它们呢?
  • ​ZeroMQ解决传统网络编程的问题:

    • 调用的socket接口较多。
    • TCP是一对一的连接。
    • 编程需要关注很多socket细节问题。
    • 不支持跨平台编程。
    • 需要自行处理分包、组包问题。
    • 流式传输时需处理粘包、半包问题。
    • 需自行处理网络异常,比如连接异常中断、重连等。
    • 服务端和客户端启动有先后。
    • 自行处理IO模型。
    • 自行实现消息的缓存。
    • 自行实现对消息的加密。

依赖环境

  • libzmq3-dev, libzmq5
  • libzmqpp-dev, libzmqpp4

客户端-服务器模式(Client-server)

  • 客户机-服务器模式用于允许一个ZMQ_SERVER服务器与一个或多个ZMQ_CLIENT客户机通信。客户端总是启动对话,之后任何一方都可以向另一方异步发送消息

ZMQ_CLIENT

  • ZMQ_CLIENT套接字与ZMQ_SERVER套接字通信。任何一个对等点都可以连接,但是通常推荐的模型是绑定ZMQ_SERVER并连接ZMQ_CLIENT。

  • 如果ZMQ_CLIENT套接字已经建立了连接,zmq_send()将接受消息,将它们排成队列,并在网络允许的情况下尽可能快地发送它们。传出缓冲区限制由套接字的高水位标志定义。如果传出缓冲区已满,或者没有连接的对等点,zmq_send()将默认阻塞。ZMQ_CLIENT套接字不会删除消息。

  • 当ZMQ_CLIENT套接字连接到多个ZMQ_SERVER套接字时,发送出去的消息将在连接的对等端之间循环分发。同样,ZMQ_CLIENT套接字公平地从每个连接的对等端接收消息。这种用法仅适用于无状态协议。

  • ZMQ_CLIENT套接字是线程安全的,可以从多个线程同时使用。注意,来自ZMQ_SERVER套接字的响应将发送到调用zmq_msg_recv()的第一个客户机线程。如果需要获得对原始线程的响应,每个线程使用一个ZMQ_CLIENT套接字。

  • ZMQ_CLIENT套接字是线程安全的。它们在发送时不接受ZMQ_SNDMORE选项,而在接收时不接受ZMQ_RCVMORE。这就限制了他们只能使用单个部件的数据。其目的是扩展API以允许分散/收集多部分数据。

  • ZMQ_CLIENT特性摘要 

    • 兼容的对等套接字ZMQ_SERVER方向双向的发送/接收模式无限制外发路由策略扇出(Fan out)入网路由策略公平排队静音状态下的操作阻塞

ZMQ_SERVER

  • ZMQ_SERVER套接字与一组ZMQ_CLIENT套接字通信。ZMQ_SERVER套接字只能应答传入消息:ZMQ_CLIENT对等端必须始终发起对话。

  • 每个接收到的消息都有一个routing_id,它是一个32位无符号整数。应用程序可以使用zmq_msg_routing_id(3)来获取它。要向给定的ZMQ_CLIENT对等点发送消息,应用程序必须使用zmq_msg_set_routing_id(3)在消息上设置对等点的routing_id。

  • 如果没有指定routing_id,或者没有引用已连接的客户端对等点,则发送调用将在EHOSTUNREACH中失败。如果客户端对等端的传出缓冲区已满,发送调用将阻塞,除非在发送中使用ZMQ_DONT_WAIT,在这种情况下,它将通过EAGAIN失败。ZMQ_SERVER套接字在任何情况下都不应该丢失消息。

  • ZMQ_SERVER套接字是线程安全的。它们在发送时不接受ZMQ_SNDMORE选项,而在接收时不接受ZMQ_RCVMORE。这就限制了他们只能使用单个部件的数据。其目的是扩展API以允许分散/收集多部分数据。

  • ZMQ_SERVER特性摘要 

    • 兼容的对等套接字ZMQ_CLIENT方向双向的发送/接收模式无限制外发路由策略扇出(Fan out)入网路由策略公平排队静音状态下的操作返回EAGAIN

其他

  • API参考文档:http://api.zeromq.org/master:_start

简介

  • zmq库中常用的函数

C++ zmq::socket_t::set()函数 详解

在 ZeroMQ 的 C++ 绑定中,zmq::socket_t::set() 函数用于设置套接字选项。它允许你在运行时修改 ZeroMQ 套接字的行为,以满足特定的需求。这个函数的签名通常是这样的:

1
2
template<typename T>
socket_t& set(zmq::sockopt::opt<T> option, const T& value);

其中,option 是一个枚举类型,表示要设置的选项,value 是相应选项的值。

下面是一些常用的套接字选项以及它们的用途:

  1. ZMQ_SUBSCRIBE/ZMQ_UNSUBSCRIBE:用于设置订阅的消息过滤器。在订阅者套接字上调用 set() 函数并传递 ZMQ_SUBSCRIBE 选项可以指定要订阅的消息前缀,而 ZMQ_UNSUBSCRIBE 用于取消订阅。

  2. ZMQ_LINGER:设置套接字关闭时等待未发送消息的时间。如果未设置,套接字在关闭时将立即丢弃未发送的消息。可以通过设置这个选项来等待一段时间,以确保消息被发送。

  3. ZMQ_SNDHWM/ZMQ_RCVHWM:设置套接字的发送和接收高水位标记。当队列中的消息数量达到这个水位标记时,后续的发送操作将被阻塞(发送者)或丢弃(接收者)。

  4. ZMQ_SNDTIMEO/ZMQ_RCVTIMEO:设置发送和接收操作的超时时间。当设置了这个选项后,发送和接收操作将在超时时间内等待,如果超时则返回错误。

  5. ZMQ_TCP_KEEPALIVE/ZMQ_TCP_KEEPALIVE_CNT/ZMQ_TCP_KEEPALIVE_IDLE/ZMQ_TCP_KEEPALIVE_INTVL:用于设置 TCP 连接的保持活动参数。

  6. ZMQ_ROUTER_MANDATORY:在 ROUTER 套接字上设置此选项,如果无法路由消息,则立即报告错误。

等等。

需要注意的是,不是所有的选项都适用于所有类型的套接字,而且某些选项的行为可能因 ZeroMQ 版本而异。因此,在使用 set() 函数设置选项时,建议参考 ZeroMQ 文档和版本说明以确保选项的行为符合预期。

zmq::socket_t::set() 函数

  • 这个函数是zmq::socket_t的父类zmq::socket_base中的成员函数,其函数声明为

    1
    2
    3
    4
    5
    6
    7
    // Set array socket option, e.g.
    // `socket.set(zmq::sockopt::plain_username, "foo123")`
    template<int Opt, int NullTerm>
    void set(sockopt::array_option<Opt, NullTerm>, const char *buf)
    {
    set_option(Opt, buf, std::strlen(buf));
    }
  • 其中,第一个参数是一个枚举值,用来表示该连接的属性,其值如下

    • zmq::sockopt::subscribe
  • 第二个参数是字符串,用来标记该连接

简介

  • zmq通讯组件相关理论基础知识

维基百科 zmq

  • zmq(ZeroMQ)是一个为可伸缩的分布式或并发应用程序设计的高性能异步消息库。它提供一个消息队列, 但是与面向消息的中间件不同,ZeroMQ的运行不需要专门的消息代理(message broker)。该库设计成常见的套接字风格的API

  • ZeroMQ是由iMatix公司和大量贡献者组成的社群共同开发的。ZeroQ通过许多第三方软件支持大部分流行的编程语言,从Java和Python到Erlang和Haskell

  • ZMQ的技术

    • 类库提供一些套接字(对传统Berkeley套接字和Unix domain socket的泛化),每一个套接字可以代表一个端口之间的多对多连接。以消息的粒度进行操作,套接字需要使用一种消息模式(message pattern),然后专门为那种模式进行了优化。
  • 基本的ZeroMQ模式有:

    • 请求响应模式,将一组客户端连接到一组服务器。这是一种远程过程调用和任务分发模式
    • 发布/订阅模式,将一组发布者连接到一组订阅者。这是一种数据分发模式。
    • 管道模式,以扇出/扇入模式连接节点,可以有多个步骤,可以有循环。这是一种并行的任务分发和收集模式。
    • 排他对模式,在一个排他对中连接两个套接字。 (这是一种高级的为某种用例而设计的低级别模式)
  • 任何通过套接字的消息被看作不透明的数据块。发送给订阅者的消息可以自动地通过块最开始的字符串进行过滤。ZeroMQ提供多种消息传输协议,包括TCP,PGM(可靠的多播),进程间通信(IPC) 以及线程间通讯(ITC)。

  • 由于内部线程模型,ZeroMQ的性能非常好,通过利用一种自动消息批处理技术,它甚至在吞吐量上超过了TCP的性能。

  • ZeroMQ实现了ZMTP, ZeroMQ消息传输协议。[4] ZMTP定义了向后兼容性的规则,可扩展的安全机制,命令和消息分帧,连接元数据,以及其他传输层功能。不使用完整的ZeroMQ实现,而是直接实现ZMTP协议的项目不断增加。

C++ zmq是什么

C++ zmq 是指 ZeroMQ 的 C++ 绑定。ZeroMQ 是一个高性能、异步消息传递库,用于在分布式系统中实现消息通信。它提供了简单而强大的 API,允许开发者构建各种通信模式,包括请求-应答、发布-订阅、推送-拉取等。

C++ zmq 库提供了 ZeroMQ 的 C++ API,使得在 C++ 应用程序中使用 ZeroMQ 变得更加方便。通过 C++ zmq,你可以利用 ZeroMQ 的功能来构建分布式系统,实现各种消息传递模式,并且可以在不同的平台上进行部署。

ZeroMQ 的设计理念是简单易用,同时保持高性能和灵活性,因此它在许多项目中被广泛使用,包括大规模分布式系统、实时数据处理系统、消息队列等场景。C++ zmq 的出现进一步促进了 ZeroMQ 在 C++ 生态系统中的应用和普及。

C++ zmq库 详解

C++ zmq 是 ZeroMQ 的 C++ 绑定,允许你在 C++ 应用程序中使用 ZeroMQ 的功能。ZeroMQ 是一个轻量级的消息传递库,用于构建分布式和并发系统。下面是 C++ zmq 库的一些详细解释:

  1. 简单而强大的 API:C++ zmq 提供了简单而直观的 API,使得在 C++ 应用程序中使用 ZeroMQ 变得容易。它的设计目标之一是简化消息传递的复杂性,因此 API 设计得非常易于理解和使用。

  2. 支持各种通信模式:ZeroMQ 支持多种通信模式,包括请求-应答、发布-订阅、推送-拉取等。C++ zmq 库允许你利用这些通信模式来构建不同类型的分布式系统,根据需要进行灵活的通信。

  3. 高性能和低延迟:ZeroMQ 被设计为高性能和低延迟的消息传递库。C++ zmq 库继承了这些特性,在 C++ 应用程序中实现了高效的消息传递,适用于需要快速响应和高吞吐量的场景。

  4. 跨平台支持:C++ zmq 库支持多种操作系统,包括 Linux、Windows 和 macOS,使得你可以在不同的平台上部署和运行你的应用程序。

  5. 灵活性和可扩展性:ZeroMQ 的设计具有很高的灵活性和可扩展性,允许你根据应用程序的需要定制通信模式和传输协议。C++ zmq 提供了丰富的配置选项,使得你可以根据需求进行定制。

  6. 社区活跃:ZeroMQ 是一个开源项目,拥有活跃的社区支持和持续的更新。C++ zmq 库也得到了广泛的使用和贡献,因此可以在社区中找到丰富的资源和支持。

总的来说,C++ zmq 是一个强大而灵活的库,适用于构建各种类型的分布式系统和消息传递应用程序。它提供了简单易用的 API、高性能的消息传递、跨平台支持等特性,使得在 C++ 应用程序中实现分布式通信变得更加容易和高效。

简介

  • 简介:用于开发移动应用的框架

环境依赖

buildozer

  • pip3 install buildozer

  • apt install -y git zip unzip openjdk-8-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev

buildozer init 错误

  • python3.8 -m pip install --upgrade pexpect

简介

  • argparse模块

python3 argparse模块 详解

argparse 是 Python 中的一个用于处理命令行参数的标准模块。它允许您定义命令行工具的参数、选项和子命令,并提供帮助文档生成以及错误处理功能。下面是一个详细的解释 argparse 的主要功能和用法。

创建 ArgumentParser 对象

首先,您需要导入 argparse 模块并创建一个 ArgumentParser 对象,这个对象用于定义和解析命令行参数。

1
2
3
import argparse

parser = argparse.ArgumentParser(description='一个命令行工具示例')

定义命令行参数

通过 add_argument() 方法,您可以定义要接受的命令行参数、选项和标志。

  • 位置参数:通常是必需的参数,它们没有前缀,只需列出参数名称即可。

    1
    parser.add_argument('filename', help='要处理的文件名')
  • 选项参数:选项参数通常以一个或多个前缀字符(通常是 ---)开头。

    1
    parser.add_argument('-f', '--file', help='指定文件名')
  • 标志参数:标志参数通常是布尔类型,表示是否启用某个功能,使用 action='store_true' 参数。

    1
    parser.add_argument('--verbose', action='store_true', help='启用详细日志')
  • 默认值:您可以使用 default 参数来设置参数的默认值。

    1
    parser.add_argument('-n', '--number', type=int, default=1, help='指定一个整数(默认为1)')

解析命令行参数

使用 parse_args() 方法来解析命令行参数,它返回一个包含参数值的命名空间对象。

1
args = parser.parse_args()

访问参数值

访问解析后的参数值,可以通过命名空间对象的属性来获取。例如:

1
2
3
print('文件名:', args.file)
print('整数值:', args.number)
print('详细日志:', args.verbose)

自动生成帮助信息

argparse 会自动生成帮助信息,包括参数的用法、描述和默认值。要输出帮助信息,用户可以在命令行中使用 -h--help 选项。

1
python my_script.py -h

或者在程序内部使用 parser.print_help()

1
parser.print_help()

处理错误

argparse 也能处理一些常见的错误,如无效参数值或参数缺失。如果用户提供了无效的参数值或未提供必需的参数,argparse 会显示错误信息并退出。

这是一个 argparse 的基本用法示例,您可以根据自己的需求定义更多参数、选项和标志,以及编写自定义的处理逻辑。argparse 还提供了其他功能,如子命令支持、互斥参数等,以满足更复杂的命令行解析需求。

简介

  • datetime模块笔记

python3 datetime模块 详解

datetime 模块是 Python 标准库中用于处理日期和时间的重要模块。它提供了各种类和函数,允许你在 Python 中执行日期和时间操作。以下是 datetime 模块的一些重要类和函数,以及它们的详细说明:

  1. datetime 类

    datetime 类是 datetime 模块的核心,用于表示日期和时间的对象。它包含年、月、日、时、分、秒和微秒等信息。你可以使用 datetime 类来执行日期和时间的各种操作,例如创建日期时间对象、格式化日期时间、执行算术运算等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from datetime import datetime

    # 获取当前日期时间
    now = datetime.now()

    # 创建自定义日期时间对象
    custom_date = datetime(2023, 5, 15, 10, 30)

    # 格式化日期时间为字符串
    formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")

    # 执行日期时间算术操作
    delta = custom_date - now
  2. date 类

    date 类用于表示日期信息,不包括具体时间。它包含年、月和日信息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from datetime import date

    # 创建日期对象
    today = date.today()

    # 访问日期的年、月、日
    year = today.year
    month = today.month
    day = today.day
  3. time 类

    time 类用于表示时间信息,不包括日期。它包含时、分、秒和微秒信息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from datetime import time

    # 创建时间对象
    current_time = time(14, 30, 0)

    # 访问时间的时、分、秒
    hour = current_time.hour
    minute = current_time.minute
    second = current_time.second
  4. timedelta 类

    timedelta 类用于表示时间间隔,可以用于执行日期时间的算术运算,如加法和减法。

    1
    2
    3
    4
    5
    6
    7
    from datetime import timedelta

    # 创建时间间隔
    delta = timedelta(days=5, hours=2, minutes=30)

    # 执行日期时间的算术运算
    future_date = now + delta
  5. strftime 和 strptime 函数

    strftime 函数用于将日期时间对象格式化为字符串,而 strptime 函数用于将字符串解析为日期时间对象。

    1
    2
    3
    4
    from datetime import datetime

    formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
    parsed_date = datetime.strptime("2023-05-15 10:30:00", "%Y-%m-%d %H:%M:%S")

这只是 datetime 模块的一部分功能。你可以使用这些类和函数来执行日期和时间相关的各种操作,包括日期时间的比较、格式化、时区处理、日历计算等。这个模块非常强大,适用于各种日期时间处理需求。

简介

  • base64模块笔记

python3 base64模块 详解

base64 模块是Python标准库中的一个模块,用于处理Base64编码和解码。Base64是一种二进制数据编码方式,通常用于将二进制数据转换为可打印字符,以便在不损失数据的情况下进行传输和存储。以下是关于Python3中base64模块的详细解释:

导入base64模块

首先,您需要导入base64模块,以便在代码中使用它:

1
import base64

Base64编码

base64模块提供了多种方法来执行Base64编码。其中最常用的是b64encode()函数,它将二进制数据编码为Base64字符串。以下是一个示例:

1
2
3
4
5
6
7
8
9
10
# 要编码的二进制数据
binary_data = b'Hello, World!'

# 进行Base64编码
encoded_data = base64.b64encode(binary_data)

# 将编码后的数据转换为字符串
encoded_string = encoded_data.decode('utf-8')

print(encoded_string)

Base64解码

base64模块也提供了多种方法来执行Base64解码。最常用的是b64decode()函数,它将Base64编码的字符串解码为原始的二进制数据。以下是一个示例:

1
2
3
4
5
6
7
8
# Base64编码后的字符串
encoded_string = 'SGVsbG8sIFdvcmxkIQ=='

# 进行Base64解码
decoded_data = base64.b64decode(encoded_string)

# 打印解码后的二进制数据
print(decoded_data)

URL安全的Base64编解码

有时候,Base64编码的字符串需要在URL中传输,但标准的Base64编码字符串中包含一些特殊字符(如+/),这可能会引起问题。为了解决这个问题,base64模块提供了urlsafe_b64encode()urlsafe_b64decode()函数,它们会将+/字符替换为-_,以使编码的字符串在URL中更安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 要编码的二进制数据
binary_data = b'Hello, World!'

# 进行URL安全的Base64编码
urlsafe_encoded_data = base64.urlsafe_b64encode(binary_data)

# 将编码后的数据转换为字符串
urlsafe_encoded_string = urlsafe_encoded_data.decode('utf-8')

print(urlsafe_encoded_string)

# 进行URL安全的Base64解码
decoded_data = base64.urlsafe_b64decode(urlsafe_encoded_string)

# 打印解码后的二进制数据
print(decoded_data)

这些是Python3中base64模块的基本用法。请注意,在进行编码和解码操作时,要确保输入的数据类型是字节序列(bytes)。base64模块是处理二进制数据的常见工具之一,特别是在与文件、网络传输和加密相关的应用中。

简介

  • PIL模块相关笔记

python3 PIL是什么

PIL代表Python Imaging Library,它是Python中用于处理图像的标准库之一。PIL提供了许多功能强大的图像处理工具和函数,使您能够打开、编辑、保存各种图像文件格式(如JPEG、PNG、GIF等),以及执行各种图像操作,如调整大小、裁剪、旋转、滤镜应用等。

虽然PIL在许多Python发行版中都是预安装的,但有时您可能需要手动安装它。在Python 3中,PIL的一个流行的替代品是Pillow库,它是对PIL的增强版本,提供了更多功能和改进。

总之,PIL(或Pillow)是Python中一个强大且灵活的图像处理库,适用于各种图像处理任务,从简单的图像格式转换到复杂的图像编辑操作。

python3 PIL详解

Python Imaging Library(PIL)是一个用于图像处理的Python库,它提供了许多功能强大的工具和函数,用于打开、编辑和保存各种图像文件格式。以下是关于PIL的一些详细解释:

  1. 功能:PIL库提供了许多图像处理功能,包括图像加载、裁剪、缩放、旋转、滤镜应用、颜色转换等。您可以使用PIL来执行各种常见的图像处理任务,以及一些高级的图像操作。

  2. 支持的文件格式:PIL支持各种常见的图像文件格式,如JPEG、PNG、GIF、BMP等,以及一些较少常见的格式。您可以使用PIL来打开这些文件格式的图像,进行处理,并将其保存为其他格式。

  3. 易于使用:PIL提供了简单易用的API,使得对图像进行处理变得容易。您可以通过几行代码来完成许多常见的图像处理任务,而不需要编写复杂的算法。

  4. Pillow库:在Python 3中,Pillow库是对PIL的增强版本,它包含了PIL的所有功能,并提供了一些额外的功能和改进。因此,如果您在Python 3中使用PIL,通常建议使用Pillow库。

  5. 社区支持:PIL/Pillow是一个受欢迎的Python库,拥有活跃的社区支持。您可以在网络上找到大量的文档、教程和示例代码,以帮助您学习和使用PIL进行图像处理。

总之,PIL/Pillow是Python中一个功能强大且易于使用的图像处理库,适用于各种图像处理任务,从简单的图像格式转换到复杂的图像编辑和处理操作。

简介

  • json模块笔记

python3 json 模块 详解

Python 3中的json模块是用于处理JSON(JavaScript Object Notation)数据的标准库。JSON是一种轻量级数据交换格式,通常用于数据序列化和跨语言数据传输。下面是对Python 3中的json模块的详细解释:

  1. 加载和解析JSON数据

    • json.loads(json_string):将JSON格式的字符串解析为Python数据结构,通常是字典或列表。
    • json.load(file):从文件中读取JSON数据并解析为Python数据结构。
  2. 将Python数据转换为JSON

    • json.dumps(python_data):将Python数据(字典、列表等)转换为JSON格式的字符串。
    • json.dump(python_data, file):将Python数据写入文件,以JSON格式进行序列化。
  3. 格式化输出

    • json.dumps(python_data, indent=4):以缩进格式输出JSON字符串,使其更易读。
    • json.dump(python_data, file, indent=4):以缩进格式将JSON数据写入文件。
  4. 自定义编码和解码

    • json.JSONEncoder:自定义JSON编码器,允许你扩展默认的JSON编码行为。
    • json.JSONDecoder:自定义JSON解码器,允许你处理JSON字符串中的特殊情况。
  5. 处理特殊数据类型

    • json.dumps(..., default=custom_function):允许你在将不支持的数据类型转换为JSON时使用自定义函数。
    • json.loads(..., object_hook=custom_function):允许你在从JSON解析数据时使用自定义函数来处理特殊情况。
  6. 异常处理

    • json.JSONDecodeError:用于捕获JSON解码期间可能发生的异常,如JSON格式不正确等。
  7. 其他选项

    • json.dumps(..., ensure_ascii=False):允许非ASCII字符在JSON字符串中保持原样,而不是进行转义。
    • json.dumps(..., separators=(',', ':')):指定分隔符以节省生成的JSON字符串的空间。

下面是一个示例,展示如何使用json模块加载、解析、生成和格式化JSON数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json

# 创建一个Python字典
data = {
"name": "John",
"age": 30,
"city": "New York"
}

# 将Python字典转换为JSON字符串
json_string = json.dumps(data, indent=4)

# 打印JSON字符串
print(json_string)

# 将JSON字符串解析为Python字典
parsed_data = json.loads(json_string)

# 访问解析后的数据
print(parsed_data["name"]) # 输出 "John"

json模块提供了在Python中处理JSON数据的强大功能,允许你在不同系统之间轻松交换数据,并在Python应用程序中进行数据序列化和反序列化。

简介

  • onnxruntime库相关笔记

python3 onnxruntime库 是什么

ONNX Runtime是一个用于在Python中执行ONNX模型的库。ONNX(Open Neural Network Exchange)是一种开放式的深度学习模型表示格式,它允许在不同的深度学习框架之间轻松转换模型。ONNX Runtime提供了一个高性能的推理引擎,可以在CPU、GPU和其他加速器上运行ONNX模型。通过使用ONNX Runtime,您可以在Python中轻松加载、优化和执行ONNX模型,这使得您可以快速部署和执行各种类型的深度学习模型。ONNX Runtime支持各种常见的深度学习框架,如PyTorch、TensorFlow等,并提供了用于与这些框架集成的API。

python3 onnxruntime库 详解

ONNX Runtime是一个用于在Python中执行ONNX模型的库。下面是ONNX Runtime库的一些详细解释:

  1. 用途:ONNX Runtime用于加载、优化和执行ONNX格式的深度学习模型。它是一个用于推理(即模型预测)的高性能引擎。

  2. 跨平台性:ONNX Runtime是一个跨平台的库,可以在不同的设备上运行,包括CPU、GPU和特定硬件加速器。这使得您可以将模型轻松部署到各种设备上,并利用硬件加速以获得更高的性能。

  3. 支持的框架:ONNX Runtime支持各种常见的深度学习框架,如PyTorch、TensorFlow等。这意味着您可以使用这些框架训练模型,并在ONNX Runtime中执行这些模型,而无需进行复杂的转换。

  4. 高性能:ONNX Runtime旨在提供高性能的推理体验。它经过优化,以在各种设备上实现快速的模型推理,并且通常比使用原始深度学习框架进行推理更加高效。

  5. API接口:ONNX Runtime提供了用于加载、运行和评估模型的Python API接口。这些接口易于使用,并且提供了各种功能,包括异步推理、模型优化和性能调优等。

总之,ONNX Runtime是一个强大的工具,使得您可以在Python中轻松地加载、优化和执行ONNX模型,从而实现快速且高效的深度学习推理。

python3 onnxruntime库 示例

以下是一个简单的示例,演示如何使用Python中的ONNX Runtime库加载并执行一个ONNX模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import onnxruntime as rt
import numpy as np

# 加载ONNX模型
model_path = 'model.onnx'
sess = rt.InferenceSession(model_path)

# 模型输入名称和形状
input_name = sess.get_inputs()[0].name
input_shape = sess.get_inputs()[0].shape
print("模型输入名称:", input_name)
print("模型输入形状:", input_shape)

# 创建模拟输入数据
input_data = np.random.rand(*input_shape).astype(np.float32)

# 执行推理
output = sess.run(None, {input_name: input_data})

# 输出结果
print("模型输出:", output)

在这个示例中:

  • 首先,我们导入了onnxruntime库。
  • 然后,我们使用rt.InferenceSession加载了一个ONNX模型,该模型的路径存储在model_path变量中。
  • 我们通过sess.get_inputs()获取了模型的输入信息,包括输入名称和形状。
  • 接下来,我们创建了一个随机的模拟输入数据input_data,其形状与模型输入相匹配。
  • 最后,我们使用sess.run方法执行推理,将输入数据传递给模型,并获取模型的输出结果。

这只是一个简单的示例,演示了如何使用ONNX Runtime库加载和执行模型。实际应用中,您可能需要根据模型的具体要求进行更复杂的输入数据准备和后处理操作。

python3 onnxruntime.InferenceSession.run()函数 详解

onnxruntime.InferenceSession.run()函数是ONNX Runtime库中用于执行推理(inference)的主要函数。这个函数允许您将输入数据传递给ONNX模型,并获取模型的输出结果。以下是该函数的详解:

参数:

  • inputs:一个字典,表示模型的输入。字典的键是输入张量的名称,值是相应的输入张量数据。如果模型有多个输入,那么这个字典将包含多个键值对。
  • outputs:一个列表,表示您希望获取的模型输出。列表中的每个元素都是一个字符串,表示模型输出张量的名称。

返回值:

  • outputs:一个列表,包含了模型的输出结果。列表中的每个元素都是一个NumPy数组,表示相应的输出张量数据。如果模型有多个输出,那么返回的列表将包含多个数组。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import onnxruntime as rt
import numpy as np

# 加载ONNX模型
model_path = 'model.onnx'
sess = rt.InferenceSession(model_path)

# 准备输入数据
input_data = np.random.rand(1, 3, 224, 224).astype(np.float32)

# 执行推理
output = sess.run(None, {'input': input_data})

# 输出结果
print("模型输出:", output)

在这个示例中,我们首先加载了一个ONNX模型,并准备了输入数据。然后,我们使用sess.run()函数执行推理,将输入数据传递给模型,并获取模型的输出结果。最后,我们打印了输出结果。