Python 机器视觉入门:第1-5章完整学习指南
欢迎来到Python机器视觉的世界!本系列教程专门为像你这样有C#开发经验、希望快速入门Python及机器视觉基础的朋友设计。我们将用5章的篇幅,从零搭建Python知识体系,为后续的OpenCV学习打下坚实基础。
Python 机器视觉入门:第1-5章完整学习指南(博客版)
欢迎来到Python机器视觉的世界!本系列教程专门为像你这样有C#开发经验、希望快速入门Python及机器视觉基础的朋友设计。我们将用5章的篇幅,从零搭建Python知识体系,为后续的OpenCV学习打下坚实基础。
第1章:Python 环境搭建与基础语法
1.1 Python安装与环境配置
重点:下载Python 3.8+(推荐3.8或3.9,对机器视觉库兼容性最好),安装时务必勾选“Add Python to PATH”。
验证安装:打开命令行(cmd),输入:
python --version
若显示版本号,则安装成功。
推荐IDE:VS Code(安装Python插件)或 PyCharm Community Edition。
1.2 第一个Python程序
# 使用 print() 输出内容
print("Hello, 机器视觉!") # 输出:Hello, 机器视觉!
重点:print() 是最常用的输出函数;字符串用引号包围。
1.3 变量与数据类型
Python变量不需要声明类型,直接赋值即可。
# 整数
age = 25
print(age, type(age)) # 输出:25 <class 'int'>
# 浮点数
price = 19.99
print(price, type(price)) # 输出:19.99 <class 'float'>
# 字符串
name = "硅片检测"
print(name, type(name)) # 输出:硅片检测 <class 'str'>
# 布尔值
is_ok = True
print(is_ok, type(is_ok)) # 输出:True <class 'bool'>
重点:type() 函数可查看变量类型;布尔值首字母大写 True/False。
1.4 基本运算符
a = 10
b = 3
# 算术运算
print(a + b) # 13
print(a - b) # 7
print(a * b) # 30
print(a / b) # 3.333...
print(a // b) # 3 (整除)
print(a % b) # 1 (取余)
print(a ** b) # 1000 (幂)
# 比较运算
print(a > b) # True
print(a == b) # False
# 逻辑运算
x = True
y = False
print(x and y) # False
print(x or y) # True
print(not x) # False
重点:// 整除,% 取余,** 幂;逻辑运算符 and/or/not。
1.5 字符串操作
s = "opencv learning"
# 拼接
s2 = s + " is fun"
print(s2) # opencv learning is fun
# 索引与切片(索引从0开始)
print(s[0]) # 'o'
print(s[-1]) # 'g' (倒数第一个)
print(s[7:13]) # 'learn' (切片 7~12)
# 常用方法
print(s.upper()) # OPENCV LEARNING
print(s.replace("learning", "tutorial")) # opencv tutorial
print(s.split(" ")) # ['opencv', 'learning']
print(len(s)) # 16
重点:字符串是不可变对象;切片 [start:end:step] 非常重要;常用方法如 split, replace, upper, len。
1.6 列表(list)—— 最常用容器
# 创建列表
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
# 增删改查
fruits.append("orange") # 尾部添加
fruits.insert(1, "grape") # 指定位置插入
fruits.remove("banana") # 删除第一个匹配项
popped = fruits.pop() # 弹出最后一个元素
fruits[0] = "watermelon" # 修改
# 列表推导式(快速生成列表)
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
print(fruits) # ['watermelon', 'grape', 'cherry']
print(squares) # [0, 1, 4, 9, 16]
重点:列表是可变有序集合;常用方法 append, insert, remove, pop, index, sort;列表推导式是 Python 特色。
1.7 元组与字典
# 元组 (tuple) —— 不可变列表
point = (10, 20)
print(point[0]) # 10
# point[0] = 5 # 错误,元组不能修改
# 字典 (dict) —— 键值对
person = {
"name": "张三",
"age": 30,
"skill": "机器视觉"
}
print(person["name"]) # 通过键访问
person["company"] = "科技公司" # 添加新键值对
print(person.keys()) # 所有键
print(person.values()) # 所有值
# 遍历字典
for key, value in person.items():
print(f"{key}: {value}")
重点:元组常用于表示不变数据;字典通过键快速查找,键必须是不可变类型(如字符串、数字、元组)。
1.8 条件判断(if-elif-else)
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B" # 条件成立,执行此分支
elif score >= 70:
grade = "C"
else:
grade = "D"
print(f"成绩等级:{grade}") # 成绩等级:B
# 条件表达式(三元运算符)
age = 20
status = "成年人" if age >= 18 else "未成年人"
print(status) # 成年人
重点:缩进决定代码块;elif 是 else if 的缩写;三元运算符用于简单条件赋值。
1.9 循环(for / while)
# for 循环遍历可迭代对象
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# 配合 range() 生成数字序列
for i in range(5): # 0,1,2,3,4
print(i)
for i in range(2, 8, 2): # 2,4,6 (起始2,结束8前,步长2)
print(i)
# while 循环
count = 0
while count < 5:
print(f"count = {count}")
count += 1
# break 退出循环,continue 跳过本次循环
for i in range(10):
if i == 3:
continue # 跳过3
if i == 8:
break # 遇到8退出循环
print(i) # 输出:0,1,2,4,5,6,7
重点:for...in 遍历列表、字符串、字典等;range(start, stop, step);break 彻底退出循环,continue 结束本次迭代进入下一次。
第2章:函数与模块
2.1 函数的定义与调用
# 定义简单函数
def greet():
print("Hello, 欢迎学习OpenCV!")
# 调用函数
greet() # Hello, 欢迎学习OpenCV!
# 带参数的函数
def add(a, b):
result = a + b
print(f"{a} + {b} = {result}")
add(5, 3) # 5 + 3 = 8
重点:使用 def 关键字定义函数;函数必须先定义后调用。
2.2 参数传递
# 位置参数(按顺序传递)
def introduce(name, age):
print(f"我是{name},今年{age}岁")
introduce("李四", 28) # 我是李四,今年28岁
# 默认参数(有默认值的参数放在后面)
def power(base, exponent=2):
return base ** exponent
print(power(3)) # 3^2 = 9
print(power(3, 3)) # 3^3 = 27
# 关键字参数(调用时指定参数名)
introduce(age=30, name="王五") # 我是王五,今年30岁
# 可变参数(*args 收集为元组)
def sum_all(*numbers):
total = 0
for n in numbers:
total += n
return total
print(sum_all(1, 2, 3, 4)) # 10
# 关键字可变参数(**kwargs 收集为字典)
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="赵六", age=25, city="北京")
# 输出:
# name: 赵六
# age: 25
# city: 北京
重点:区分位置参数、默认参数、关键字参数;*args 和 **kwargs 用于处理可变数量的参数。
2.3 返回值(return)
def multiply(a, b):
return a * b
result = multiply(4, 5)
print(result) # 20
# 返回多个值(实际返回元组)
def get_min_max(numbers):
return min(numbers), max(numbers)
min_val, max_val = get_min_max([3, 7, 2, 9, 5])
print(f"最小值:{min_val},最大值:{max_val}") # 最小值:2,最大值:9
重点:return 可返回任意类型;没有 return 则返回 None;返回多个值实际是返回元组。
2.4 变量作用域
# 全局变量
global_var = "全局变量"
def test_scope():
# 局部变量
local_var = "局部变量"
print(local_var) # 可以访问局部
print(global_var) # 可以访问全局
test_scope()
# print(local_var) # 错误,局部变量在函数外不可访问
# 在函数内修改全局变量需要使用 global 关键字
counter = 0
def increment():
global counter
counter += 1
increment()
increment()
print(counter) # 2
重点:函数内部可以读取全局变量,但修改全局变量必须用 global 声明;函数内定义的变量默认为局部。
2.5 模块的导入(import)
# 导入整个模块
import math
print(math.sqrt(16)) # 4.0
# 导入特定函数/变量
from math import pi, sin
print(pi) # 3.14159...
print(sin(pi/2)) # 1.0
# 导入并起别名
import numpy as np # 后面学 NumPy 时常用
重点:import 语句放在文件顶部;from...import... 可直接引入名称;as 起别名简化。
2.6 常用内置模块示例
# os 模块:与操作系统交互
import os
print(os.getcwd()) # 当前工作目录
print(os.listdir('.')) # 当前目录下的文件和文件夹
# sys 模块:Python 解释器信息
import sys
print(sys.version) # Python 版本
print(sys.argv) # 命令行参数(列表)
# random 模块:生成随机数
import random
print(random.random()) # 0~1 随机浮点数
print(random.randint(1, 10)) # 1~10 随机整数
print(random.choice(['a','b','c'])) # 随机选择一个元素
# datetime 模块:处理日期时间
from datetime import datetime
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S")) # 格式化输出
重点:这些内置模块在文件操作、日志、随机数生成等场景非常常用。
第3章:文件与异常处理
3.1 文件的读写
# 写入文件
file = open('test.txt', 'w', encoding='utf-8')
file.write('Hello, 机器视觉!\n')
file.write('这是第二行')
file.close() # 记得关闭文件
# 读取文件
file = open('test.txt', 'r', encoding='utf-8')
content = file.read()
print(content)
file.close()
重点:open(filename, mode, encoding);模式 'w' 写入(覆盖),'r' 读取,'a' 追加;必须调用 close() 释放资源。
3.2 使用 with 语句自动管理文件
# with 语句会自动关闭文件,更安全、更简洁
with open('test.txt', 'r', encoding='utf-8') as file:
content = file.read()
print(content)
# 文件在此处自动关闭
重点:with 语句是 Python 推荐的文件操作方式,确保即使发生异常也能正确关闭文件 。
3.3 异常处理(try-except-else-finally)
try:
# 可能会出错的代码
num = int(input("请输入一个数字: "))
result = 10 / num
print(f"结果是: {result}")
except ValueError:
# 处理值错误(比如输入了字母)
print("输入的不是有效数字!")
except ZeroDivisionError as e:
# 处理除以零错误,并获取异常信息
print(f"数学错误: {e}")
except Exception as e:
# 捕获其他所有异常(不推荐滥用)
print(f"发生未知错误: {e}")
else:
# 没有异常时执行
print("计算成功完成!")
finally:
# 无论是否异常都会执行
print("程序执行结束")
重点:try 块放可能出错的代码;except 捕获特定异常;else 在没有异常时执行;finally 总是执行,适合资源清理 。
3.4 文件操作的异常处理
try:
with open('不存在.txt', 'r', encoding='utf-8') as f:
content = f.read()
except FileNotFoundError:
print("文件不存在,请检查路径!")
except IOError as e:
print(f"文件读写错误: {e}")
重点:文件操作常见的异常有 FileNotFoundError(文件不存在)、PermissionError(权限不足)、IOError(其他I/O错误)。
第4章:NumPy 基础(OpenCV 的基石)
4.1 NumPy 的安装与导入
pip install numpy
import numpy as np # 约定俗成的别名
4.2 创建数组
# 从列表创建
arr1 = np.array([1, 2, 3, 4])
print(arr1) # [1 2 3 4]
# 创建全0数组
zeros = np.zeros((3, 3)) # 3x3矩阵,元素全0
print(zeros)
# 创建全1数组
ones = np.ones((2, 4)) # 2行4列,元素全1
print(ones)
# 创建指定范围的数组
range_arr = np.arange(0, 10, 2) # 从0开始,10结束,步长2
print(range_arr) # [0 2 4 6 8]
# 创建等间隔数组
lin_arr = np.linspace(0, 1, 5) # 0到1之间均匀取5个数
print(lin_arr) # [0. 0.25 0.5 0.75 1. ]
重点:np.array() 从列表创建;np.zeros()、np.ones() 创建特殊数组;np.arange() 类似 Python 的 range();np.linspace() 生成等间隔数列 。
4.3 数组属性
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"形状: {arr.shape}") # (2, 3) - 2行3列
print(f"维度: {arr.ndim}") # 2
print(f"元素个数: {arr.size}") # 6
print(f"数据类型: {arr.dtype}") # int64
重点:shape 返回元组表示各维度大小;ndim 返回维度数;size 返回总元素数;dtype 返回数据类型 。
4.4 索引与切片
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 索引
print(arr[0, 1]) # 第一行第二列:2
# 切片
print(arr[0:2, 1:3]) # 前两行,后两列
# [[2 3]
# [5 6]]
# 花式索引
print(arr[[0, 2], :]) # 第0行和第2行,所有列
# [[1 2 3]
# [7 8 9]]
重点:NumPy 切片语法 [行起始:行结束, 列起始:列结束];可以用列表进行花式索引 。
4.5 数组运算
arr = np.array([1, 2, 3, 4])
# 标量运算
print(arr + 10) # [11 12 13 14]
print(arr * 2) # [2 4 6 8]
# 数组间运算
arr2 = np.array([5, 6, 7, 8])
print(arr + arr2) # [ 6 8 10 12]
print(arr * arr2) # [ 5 12 21 32]
# 广播机制(不同形状数组运算)
arr3 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr3 + 10) # 每个元素都加10
# [[11 12 13]
# [14 15 16]]
重点:NumPy 支持向量化运算,无需显式循环;广播机制允许不同形状的数组进行运算 。
4.6 常用函数
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 改变形状
reshaped = arr.reshape(3, 2)
print(reshaped)
# [[1 2]
# [3 4]
# [5 6]]
# 转置
transposed = arr.T
print(transposed)
# [[1 4]
# [2 5]
# [3 6]]
# 拼接
arr_a = np.array([1, 2, 3])
arr_b = np.array([4, 5, 6])
concat = np.concatenate([arr_a, arr_b])
print(concat) # [1 2 3 4 5 6]
# 条件筛选
print(arr[arr > 3]) # 筛选大于3的元素:[4 5 6]
重点:reshape() 改变形状;T 转置;concatenate() 拼接数组;布尔索引直接筛选满足条件的元素 。
4.7 随机数生成
# 设置随机种子(保证结果可复现)
np.random.seed(42)
# 均匀分布 [0,1)
rand_arr = np.random.rand(3, 3)
print(rand_arr)
# 标准正态分布
randn_arr = np.random.randn(3, 3)
print(randn_arr)
# 随机整数
randint_arr = np.random.randint(0, 10, size=(2, 3)) # 0~9的整数,2行3列
print(randint_arr)
重点:np.random.rand() 生成 [0,1) 均匀分布;np.random.randn() 生成标准正态分布;np.random.randint() 生成随机整数;seed() 保证随机数可重现 。
4.8 图像在 NumPy 中的表示
# 模拟一张彩色图像:高度100,宽度200,3通道(RGB)
image = np.random.randint(0, 256, size=(100, 200, 3), dtype=np.uint8)
print(f"图像形状: {image.shape}") # (100, 200, 3)
print(f"数据类型: {image.dtype}") # uint8 (0-255)
print(f"第一个像素的RGB值: {image[0, 0]}") # [R, G, B]
# 提取红色通道
red_channel = image[:, :, 0]
print(f"红色通道形状: {red_channel.shape}") # (100, 200)
重点:OpenCV 中图像用 NumPy 数组表示,形状为 (height, width, channels),数据类型通常是 uint8 。
第5章:Matplotlib 基础(可视化)
5.1 Matplotlib 的安装
pip install matplotlib
import matplotlib.pyplot as plt # 常用别名
5.2 基本绘图
# 折线图
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
plt.plot(x, y, 'b-') # 'b-' 表示蓝色实线
plt.xlabel('X轴')
plt.ylabel('Y轴')
plt.title('简单折线图')
plt.show()
# 散点图
x = np.random.rand(50)
y = np.random.rand(50)
plt.scatter(x, y, c='red', alpha=0.5) # alpha透明度
plt.title('散点图示例')
plt.show()
# 柱状图
categories = ['A', 'B', 'C', 'D']
values = [10, 20, 15, 25]
plt.bar(categories, values, color='green')
plt.title('柱状图示例')
plt.show()
# 直方图
data = np.random.randn(1000) # 1000个正态分布随机数
plt.hist(data, bins=20, edgecolor='black')
plt.title('直方图示例')
plt.show()
重点:plt.plot() 折线图;plt.scatter() 散点图;plt.bar() 柱状图;plt.hist() 直方图;plt.xlabel/ylabel/title 添加标签和标题;plt.show() 显示图形 。
5.3 显示图像
# 创建模拟图像(随机噪点)
image = np.random.randint(0, 256, size=(100, 100, 3), dtype=np.uint8)
plt.imshow(image)
plt.title('随机图像')
plt.axis('off') # 关闭坐标轴
plt.show()
# 显示灰度图
gray_image = np.random.randint(0, 256, size=(100, 100), dtype=np.uint8)
plt.imshow(gray_image, cmap='gray') # 使用灰度颜色映射
plt.title('灰度图像')
plt.colorbar() # 显示颜色条
plt.show()
重点:plt.imshow() 显示图像;彩色图像默认用 RGB 顺序;灰度图需指定 cmap='gray';plt.colorbar() 添加颜色条 。
5.4 图像显示调整
# 子图显示
plt.figure(figsize=(12, 4)) # 设置画布大小
plt.subplot(1, 3, 1) # 1行3列,第1个
plt.imshow(image)
plt.title('原图')
plt.axis('off')
plt.subplot(1, 3, 2) # 1行3列,第2个
plt.imshow(gray_image, cmap='gray')
plt.title('灰度图')
plt.axis('off')
plt.subplot(1, 3, 3) # 1行3列,第3个
plt.imshow(image[:, :, 0], cmap='Reds') # 红色通道
plt.title('红色通道')
plt.axis('off')
plt.tight_layout() # 自动调整子图间距
plt.show()
重点:plt.figure() 创建画布;plt.subplot(rows, cols, index) 创建子图;plt.tight_layout() 防止重叠 。
参考文档与扩展阅读
- Python 官方文档:https://docs.python.org/3/
- NumPy 官方快速入门:https://numpy.org/doc/stable/user/quickstart.html
- Matplotlib 官方教程:https://matplotlib.org/stable/tutorials/index.html
- 异常处理最佳实践:Python 官方教程 - Errors and Exceptions
学习建议
- 边学边练:每学完一个小节,立即在 Python 交互环境或脚本中运行代码示例,观察输出结果。
- 修改参数:尝试修改代码中的参数(如
bins=20改成bins=50),观察变化,加深理解。 - 结合机器视觉目标:在学习过程中,多思考这些知识点如何应用到图像处理中(例如 NumPy 数组操作就是图像像素操作的基础)。
- 遇到问题善用文档:Python、NumPy、Matplotlib 的官方文档都非常完善,遇到函数用法不熟时,养成查文档的习惯。
下一阶段,我们将进入 OpenCV 的学习,届时你会惊喜地发现,前面学的 NumPy 和 Matplotlib 知识会大量派上用场!祝学习顺利!
更多推荐
所有评论(0)