opencv利用双目摄像头获取小球轮廓空间坐标代码
时间: 2023-08-13 11:02:26 浏览: 197
以下是一个基于OpenCV的双目摄像头获取小球轮廓空间坐标的示例代码:
```python
import cv2
import numpy as np
# 定义左右相机的摄像头ID
left_camera_id = 0
right_camera_id = 1
# 读取标定数据
left_camera_matrix = np.load('left_camera_matrix.npy')
left_distortion = np.load('left_distortion.npy')
right_camera_matrix = np.load('right_camera_matrix.npy')
right_distortion = np.load('right_distortion.npy')
R = np.load('R.npy')
T = np.load('T.npy')
# 创建双目摄像头对象
left_camera = cv2.VideoCapture(left_camera_id)
right_camera = cv2.VideoCapture(right_camera_id)
while True:
# 读取双目图像
ret1, left_frame = left_camera.read()
ret2, right_frame = right_camera.read()
# 矫正图像畸变
left_frame = cv2.undistort(left_frame, left_camera_matrix, left_distortion)
right_frame = cv2.undistort(right_frame, right_camera_matrix, right_distortion)
# 立体校正
R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(left_camera_matrix, left_distortion, right_camera_matrix, right_distortion, left_frame.shape[:2], R, T, alpha=0)
left_frame = cv2.undistort(left_frame, left_camera_matrix, left_distortion, None, P1)
right_frame = cv2.undistort(right_frame, right_camera_matrix, right_distortion, None, P2)
# 计算视差图
stereo = cv2.StereoSGBM_create(numDisparities=16, blockSize=15)
disparity = stereo.compute(left_frame, right_frame)
# 通过视差图计算点云
h, w = left_frame.shape[:2]
f = left_camera_matrix[0][0]
Q[3][2] = Q[3][3] = 0
points = cv2.reprojectImageTo3D(disparity, Q)
colors = cv2.cvtColor(left_frame, cv2.COLOR_BGR2RGB)
mask = disparity > disparity.min()
out_points = points[mask]
out_colors = colors[mask]
# 过滤出小球轮廓
hsv = cv2.cvtColor(left_frame, cv2.COLOR_BGR2HSV)
lower = np.array([0, 100, 100])
upper = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 计算小球在世界坐标系中的坐标
for cnt in contours:
M = cv2.moments(cnt)
if M['m00'] != 0:
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
z = out_points[cy][cx][2]
x = (cx - left_camera_matrix[0][2]) * z / f
y = (cy - left_camera_matrix[1][2]) * z / f
print('x: %.2f, y: %.2f, z: %.2f' % (x, y, z))
# 显示图像
cv2.imshow('left', left_frame)
cv2.imshow('right', right_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
left_camera.release()
right_camera.release()
cv2.destroyAllWindows()
```
需要注意的是,以上代码仅为示例代码,具体实现方式可能因为摄像头型号、环境光照等因素而有所不同。在实际使用中,需要根据实际情况进行调整。
阅读全文