使用迈德威视(MindVision)的MV-UB300相机进行单目视觉测量(长度和外形)需要结合相机标定、图像处理和几何算法。以下是详细的步骤指南:
1. 硬件和软件准备
- 硬件:
- MV-UB300相机(支持USB3.0接口,分辨率640×480,帧率60fps)。
- 标定板(如棋盘格、圆形网格标定板)。
- 固定支架(确保相机稳定无振动)。
- 光源(均匀照明被测物体,减少阴影和反光)。
- 软件:
- 迈德威视官方SDK(用于相机控制和图像采集)。
- OpenCV(Python或C++版本,用于图像处理和标定)。
- 开发环境(如Visual Studio、PyCharm)。
2. 相机标定(关键步骤)
标定目的是获取相机的内参(焦距、畸变系数)和外参(位置、姿态),确保测量结果准确。
步骤:
-
采集标定图像:
- 将标定板(如8×6棋盘格)放置在相机视野内的不同位置和角度,拍摄10-20张图像。
- 确保标定板覆盖整个视野,避免模糊或过曝。
-
使用OpenCV标定:
import cv2
import numpy as np
# 标定板参数
pattern_size = (8, 6) # 内角点数量(棋盘格交点)
obj_points = [] # 3D世界坐标
img_points = [] # 2D图像坐标
# 生成标定板的理论3D点(Z=0)
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)
# 遍历所有标定图像
for img_path in calibration_images:
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 查找角点
ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)
if ret:
obj_points.append(objp)
img_points.append(corners)
# 标定相机
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
obj_points, img_points, gray.shape[::-1], None, None
)
-
保存标定结果:
- 内参矩阵(
mtx )和畸变系数(dist )需保存,后续用于图像去畸变。
3. 图像采集与预处理
-
通过SDK获取图像:
from MindVision import Camera # 示例代码,具体接口参考官方文档
camera = Camera()
frame = camera.capture_frame()
-
去畸变:
h, w = frame.shape[:2]
new_mtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1)
undistorted = cv2.undistort(frame, mtx, dist, None, new_mtx)
-
预处理:
- 灰度化:
gray = cv2.cvtColor(undistorted, cv2.COLOR_BGR2GRAY)
- 去噪:
blur = cv2.GaussianBlur(gray, (5, 5), 0)
- 二值化:
ret, thresh = cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY)
4. 特征提取与测量
长度测量:
-
边缘检测:
edges = cv2.Canny(thresh, 50, 150)
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
-
选择目标轮廓:
target_contour = max(contours, key=cv2.contourArea)
-
计算实际长度:
-
假设已知标定板的一个方格边长为 L (单位:毫米),对应图像中的像素数为 P 。
-
像素当量(单位:mm/pixel)为 scale = L / P 。
-
测量目标轮廓的长度(像素)并转换为实际长度:
length_pixel = cv2.arcLength(target_contour, closed=True)
length_real = length_pixel * scale
外形测量:
-
多边形拟合:
epsilon = 0.02 * cv2.arcLength(target_contour, True)
approx = cv2.approxPolyDP(target_contour, epsilon, True)
-
绘制轮廓:
cv2.drawContours(undistorted, [approx], -1, (0, 255, 0), 2)
5. 提高精度的关键点
-
亚像素边缘检测:
corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1),
(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001))
-
多帧平均:采集多张图像取平均值,减少噪声。
-
透视校正:若物体倾斜,使用透视变换(Homography)将其校正为正视图:
pts_src = np.array([approx[0], approx[1], approx[2], approx[3]])
pts_dst = np.array([[0, 0], [w, 0], [w, h], [0, h]])
M, _ = cv2.findHomography(pts_src, pts_dst)
warped = cv2.warpPerspective(undistorted, M, (w, h))
6. 验证与调试
- 测试已知尺寸物体:使用标准件(如已知长度的标定块)验证系统误差。
- 调整光照和焦距:确保图像清晰且无运动模糊。
- 输出结果可视化:在图像上标注测量结果(如长度、轮廓)。
7. 注意事项
- 被测物体需与标定板处于相同平面,或已知深度信息。
- 光照变化会显著影响测量结果,建议使用稳定光源。
- 高精度测量需使用更高分辨率的相机(如MV-UB300的640×480可能受限)。
通过以上步骤,可以实现基于MV-UB300的单目视觉测量系统。如果涉及复杂三维测量,建议升级为双目或多目视觉系统。 |