工业视觉入门必看:Python基础语法与OpenCV核心操作速成

很多想入行工业视觉的朋友都会问我:“我需要把Python学到什么程度才能开始做工业视觉?”
我的答案永远是:不需要精通Python,掌握50%的核心语法就足够了。
我见过太多人陷入了"先把Python学透再开始做项目"的误区,花了几个月时间学了面向对象、多线程、装饰器、生成器这些高级特性,结果到了工业视觉项目中发现90%都用不上。反而最基础的列表操作、循环、函数这些内容掌握得不够扎实。
同样,OpenCV有几百个函数,但工业视觉中90%的需求只需要用到不到20个核心函数。只要掌握了这些核心操作,你就能解决80%以上的工业图像处理问题。
本文是我专门为工业视觉初学者准备的速成指南,只讲工业视觉中最常用、最实用的Python语法和OpenCV操作,没有任何废话。看完这篇文章,你就能写出第一个工业缺陷检测程序。
一、工业视觉必备Python基础语法
Python是工业视觉开发的首选语言,它语法简单、库丰富、开发速度快。下面我会列出工业视觉开发中必须掌握的Python语法,每个知识点都配有工业场景的实际例子。
1.1 变量与数据类型
工业视觉中最常用的数据类型只有4种:整数、浮点数、字符串和布尔值。
# 整数:用于计数、坐标、像素值
defect_count = 5 # 缺陷数量
x = 100 # 缺陷x坐标
y = 200 # 缺陷y坐标
# 浮点数:用于精度、置信度、尺寸
confidence = 0.85 # 检测置信度
defect_length = 12.5 # 缺陷长度(mm)
# 字符串:用于文件路径、日志信息
image_path = "D:/images/pcb_001.jpg" # 图像路径
log_message = "检测到5个缺陷" # 日志信息
# 布尔值:用于判断
has_defect = True # 是否有缺陷
is_running = False # 程序是否运行
1.2 列表与字典
列表和字典是工业视觉中最重要的数据结构,几乎所有的检测结果都会用它们来存储。
列表:用于存储多个相同类型的数据,比如多个缺陷的坐标。
# 存储多个缺陷的坐标
defect_coordinates = [(100, 200), (300, 400), (500, 600)]
# 列表常用操作
defect_coordinates.append((700, 800)) # 添加一个缺陷
print(f"缺陷数量: {len(defect_coordinates)}") # 获取缺陷数量
print(f"第一个缺陷坐标: {defect_coordinates[0]}") # 访问第一个元素
# 遍历列表
for coord in defect_coordinates:
print(f"缺陷坐标: x={coord[0]}, y={coord[1]}")
字典:用于存储一个对象的多个属性,比如一个缺陷的详细信息。
# 存储一个缺陷的详细信息
defect = {
"id": 1,
"type": "划痕",
"x": 100,
"y": 200,
"length": 12.5,
"confidence": 0.85
}
# 字典常用操作
print(f"缺陷类型: {defect['type']}") # 访问属性
defect["area"] = 25.0 # 添加新属性
print(f"缺陷信息: {defect}") # 打印完整信息
1.3 条件与循环
条件判断和循环是程序的基本控制结构,工业视觉中最常用的就是if-else判断和for循环。
# 条件判断:根据缺陷数量决定是否报警
defect_count = 5
if defect_count == 0:
print("产品合格")
elif defect_count <= 3:
print("产品合格,存在轻微缺陷")
else:
print("产品不合格,存在严重缺陷")
# 触发报警信号
trigger_alarm()
# for循环:处理多张图片
image_paths = ["pcb_001.jpg", "pcb_002.jpg", "pcb_003.jpg"]
for path in image_paths:
print(f"正在处理: {path}")
# 读取图像
image = cv2.imread(path)
# 进行缺陷检测
result = detect_defect(image)
# 保存结果
save_result(result)
1.4 函数
函数可以将重复的代码封装起来,提高代码的可读性和复用性。在工业视觉项目中,我们通常会把每个功能都封装成一个函数。
def calculate_defect_area(contour):
"""计算缺陷的面积"""
area = cv2.contourArea(contour)
return area
def is_valid_defect(area, min_area=10, max_area=1000):
"""判断是否为有效缺陷"""
return min_area < area < max_area
# 调用函数
contour = [...] # 轮廓数据
area = calculate_defect_area(contour)
if is_valid_defect(area):
print("检测到有效缺陷")
else:
print("噪声,忽略")
1.5 文件操作
工业视觉中经常需要读取图像文件、保存检测结果、写入日志文件。
# 写入检测日志
with open("detection_log.txt", "a", encoding="utf-8") as f:
f.write("2026-05-16 10:30:00 - 检测到5个缺陷\n")
# 读取配置文件
with open("config.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line.strip())
1.6 异常处理
工业设备需要7×24小时连续运行,异常处理至关重要。一个未捕获的异常就可能导致整个产线停机。
try:
# 尝试读取图像
image = cv2.imread("pcb_001.jpg")
if image is None:
raise Exception("图像读取失败")
# 进行缺陷检测
result = detect_defect(image)
except Exception as e:
# 捕获所有异常,记录日志
print(f"发生错误: {e}")
with open("error_log.txt", "a", encoding="utf-8") as f:
f.write(f"2026-05-16 10:30:00 - 错误: {e}\n")
finally:
# 无论是否发生错误,都会执行的代码
release_resources()
二、OpenCV核心操作:工业视觉90%的需求都在这里
OpenCV是最流行的计算机视觉库,工业视觉中几乎所有的图像处理操作都是基于OpenCV实现的。下面我会介绍工业视觉中最常用的10个OpenCV核心操作,每个操作都有明确的工业应用场景。
2.1 图像读取与显示
这是OpenCV最基础的操作,也是所有图像处理的第一步。
import cv2
import numpy as np
# 读取图像
# 注意:OpenCV默认使用BGR颜色空间,而不是RGB
image = cv2.imread("pcb_001.jpg")
# 检查图像是否读取成功
if image is None:
print("图像读取失败")
exit()
# 获取图像信息
height, width, channels = image.shape
print(f"图像尺寸: {width}x{height}, 通道数: {channels}")
# 显示图像
cv2.imshow("Original Image", image)
cv2.waitKey(0) # 等待按键输入
cv2.destroyAllWindows() # 关闭所有窗口
踩坑提醒:OpenCV读取中文路径会报错,解决方法是用
cv2.imdecode:# 读取中文路径图像 image = cv2.imdecode(np.fromfile("PCB板001.jpg", dtype=np.uint8), cv2.IMREAD_COLOR)
2.2 图像基本操作
工业视觉中最常用的图像基本操作包括:裁剪、缩放、旋转和翻转。
# 1. 裁剪ROI区域(最重要!工业中只关心产品所在的区域)
# ROI: Region of Interest,感兴趣区域
# 格式: image[y1:y2, x1:x2]
roi = image[100:500, 200:600] # 裁剪x从200到600,y从100到500的区域
# 2. 缩放图像
# 缩小到原来的一半
resized = cv2.resize(image, (width//2, height//2))
# 缩放到指定尺寸640x480
resized = cv2.resize(image, (640, 480))
# 3. 旋转图像
# 旋转90度
rotated = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
# 旋转180度
rotated = cv2.rotate(image, cv2.ROTATE_180)
# 4. 翻转图像
# 水平翻转
flipped = cv2.flip(image, 1)
# 垂直翻转
flipped = cv2.flip(image, 0)
2.3 颜色空间转换
工业视觉中最常用的颜色空间转换是BGR转灰度,因为大多数图像处理算法都是基于灰度图像的。
# BGR转灰度图像(最常用)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# BGR转HSV(用于颜色检测)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# 显示灰度图像
cv2.imshow("Gray Image", gray)
cv2.waitKey(0)
2.4 图像滤波
滤波的主要目的是去除图像中的噪声,这是缺陷检测前必不可少的预处理步骤。
# 高斯滤波(最常用,对高斯噪声效果好)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 中值滤波(对椒盐噪声效果好,适合去除金属表面的亮点)
median_blurred = cv2.medianBlur(gray, 5)
# 双边滤波(去噪的同时保留边缘)
bilateral_blurred = cv2.bilateralFilter(gray, 9, 75, 75)
2.5 阈值处理
阈值处理可以将灰度图像转换为二值图像,将目标和背景分离开,这是缺陷检测中最核心的步骤之一。
# 1. 全局阈值处理(适用于光照均匀的场景)
# 像素值大于127的设为255(白色),小于的设为0(黑色)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 2. 自适应阈值处理(适用于光照不均匀的场景,工业中最常用)
binary = cv2.adaptiveThreshold(
gray,
255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV,
11,
2
)
# 3. OTSU阈值处理(自动计算最佳阈值)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
2.6 边缘检测
边缘检测可以找到图像中物体的边界,常用于尺寸测量和缺陷定位。
# Canny边缘检测(最常用)
edges = cv2.Canny(blurred, 50, 150)
# 显示边缘图像
cv2.imshow("Edges", edges)
cv2.waitKey(0)
2.7 轮廓检测
轮廓检测可以找到图像中所有连通区域的边界,是工业缺陷检测中最常用的技术之一。通过分析轮廓的面积、周长、形状等特征,我们可以判断是否存在缺陷。
# 查找轮廓
contours, hierarchy = cv2.findContours(
binary,
cv2.RETR_EXTERNAL, # 只检测最外层轮廓
cv2.CHAIN_APPROX_SIMPLE # 压缩轮廓点
)
print(f"找到{len(contours)}个轮廓")
# 遍历所有轮廓
for contour in contours:
# 计算轮廓面积
area = cv2.contourArea(contour)
# 面积过滤,去除噪声
if area < 10 or area > 1000:
continue
# 计算轮廓的外接矩形
x, y, w, h = cv2.boundingRect(contour)
print(f"有效缺陷: 位置({x},{y}), 尺寸{w}x{h}, 面积{area}")
2.8 绘制图形与文字
检测到缺陷后,我们需要在图像上绘制矩形框和文字,直观地显示检测结果。
# 创建一个原始图像的副本,用于绘制
result = image.copy()
for contour in contours:
area = cv2.contourArea(contour)
if 10 < area < 1000:
x, y, w, h = cv2.boundingRect(contour)
# 绘制矩形框
cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 2)
# 绘制文字
cv2.putText(
result,
f"Defect: {area:.1f}",
(x, y-10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(0, 0, 255),
2
)
# 显示结果
cv2.imshow("Detection Result", result)
cv2.waitKey(0)
踩坑提醒:OpenCV的
putText函数不支持中文,会显示成乱码。如果需要显示中文,可以使用PIL库。
2.9 图像保存
检测完成后,我们需要将结果图像保存下来,用于后续的追溯和分析。
# 保存结果图像
cv2.imwrite("result.jpg", result)
# 保存中文路径图像
cv2.imencode('.jpg', result)[1].tofile("检测结果.jpg")
2.10 视频与相机操作
工业视觉中最常见的是实时处理相机流,而不是处理静态图片。
# 打开USB相机(0表示第一个相机)
cap = cv2.VideoCapture(0)
# 设置相机参数
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv2.CAP_PROP_FPS, 30)
# 检查相机是否打开成功
if not cap.isOpened():
print("无法打开相机")
exit()
# 实时处理相机流
while True:
# 读取一帧图像
ret, frame = cap.read()
if not ret:
print("无法读取图像")
break
# 在这里添加你的图像处理代码
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
ret, binary = cv2.threshold(blurred, 127, 255, cv2.THRESH_BINARY)
# 显示结果
cv2.imshow("Live Detection", binary)
# 按q键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
三、综合实战:简单的PCB缺陷检测程序
现在我们把前面学到的所有知识整合起来,写一个完整的PCB缺陷检测程序。这个程序可以检测PCB板上的孔洞缺陷,并在图像上标注出来。
import cv2
import numpy as np
def detect_pcb_defects(image_path):
"""检测PCB板上的孔洞缺陷"""
# 1. 读取图像
image = cv2.imread(image_path)
if image is None:
print(f"无法读取图像: {image_path}")
return None
# 2. 预处理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 3. 阈值处理
ret, binary = cv2.threshold(blurred, 100, 255, cv2.THRESH_BINARY_INV)
# 4. 查找轮廓
contours, hierarchy = cv2.findContours(
binary,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE
)
# 5. 轮廓过滤与结果绘制
result = image.copy()
defect_count = 0
for contour in contours:
area = cv2.contourArea(contour)
# 过滤掉面积太小和太大的轮廓
if 20 < area < 200:
x, y, w, h = cv2.boundingRect(contour)
# 绘制缺陷框
cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 2)
cv2.putText(
result,
f"Hole: {area:.1f}",
(x, y-10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(0, 0, 255),
2
)
defect_count += 1
# 6. 在图像上添加统计信息
cv2.putText(
result,
f"Defects: {defect_count}",
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(0, 255, 0),
2
)
print(f"检测完成,共发现{defect_count}个孔洞缺陷")
return result, defect_count
# 主程序
if __name__ == "__main__":
image_path = "pcb_sample.jpg"
result_image, defect_count = detect_pcb_defects(image_path)
if result_image is not None:
# 显示结果
cv2.imshow("PCB Defect Detection", result_image)
cv2.waitKey(0)
# 保存结果
cv2.imwrite("pcb_result.jpg", result_image)
# 判断产品是否合格
if defect_count == 0:
print("产品合格")
else:
print("产品不合格")
四、常见问题与踩坑指南
4.1 OpenCV读取中文路径报错
这是OpenCV最常见的坑,解决方法是使用cv2.imdecode和cv2.imencode:
# 读取中文路径
image = cv2.imdecode(np.fromfile("中文路径.jpg", dtype=np.uint8), cv2.IMREAD_COLOR)
# 保存中文路径
cv2.imencode('.jpg', image)[1].tofile("中文结果.jpg")
4.2 图像显示不出来或一闪而过
这是因为没有调用cv2.waitKey(0),这个函数会等待用户按键输入,否则窗口会立即关闭。
4.3 中文乱码问题
OpenCV的putText函数不支持中文,解决方法是使用PIL库:
from PIL import Image, ImageDraw, ImageFont
def put_chinese_text(image, text, position, font_size=20, color=(0, 0, 255)):
"""在图像上绘制中文文字"""
pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(pil_image)
font = ImageFont.truetype("msyh.ttc", font_size)
draw.text(position, text, font=font, fill=color)
return cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
4.4 相机无法打开
- 检查相机是否正确连接
- 检查相机驱动是否安装
- 尝试更换USB端口
- 关闭其他可能占用相机的程序
五、总结与下一步
恭喜你!看完这篇文章,你已经掌握了工业视觉开发所需的90%的Python基础语法和OpenCV核心操作。
回顾一下我们学到的内容:
- Python基础:变量、列表、字典、条件、循环、函数、文件操作、异常处理
- OpenCV核心:图像读写、裁剪缩放、灰度化、滤波、阈值处理、边缘检测、轮廓检测、绘制结果、相机操作
这些知识足够你解决大多数简单的工业视觉问题了。接下来你可以:
- 找一些工业缺陷图片,自己动手写代码进行检测
- 学习YOLO算法,用深度学习的方法解决更复杂的缺陷检测问题
- 学习工业相机的使用和标定
- 学习如何与PLC、机器人等工业设备通信
在后续的文章中,我会详细介绍这些内容,带你一步步成为工业视觉工程师。
👉 点击我的头像进入主页,关注专栏第一时间收到更新提醒,有问题评论区交流,看到都会回。
更多推荐
所有评论(0)