pythonopencv双目视觉检测球半径代码
时间: 2023-10-01 13:06:31 浏览: 85
以下是一个基本的双目视觉检测球半径的 Python OpenCV 代码示例:
```python
import cv2
import numpy as np
# 摄像头参数
camera_width = 640
camera_height = 480
camera_fov = 60 # 摄像头视场角
# 读取摄像头
left_camera = cv2.VideoCapture(0)
right_camera = cv2.VideoCapture(1)
# 设置摄像头参数
left_camera.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
left_camera.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
right_camera.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
right_camera.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
# 标定参数
camera_matrix_left = np.array([[ 6.24044717e+02, 0.00000000e+00, 3.19500000e+02],
[ 0.00000000e+00, 6.24044717e+02, 2.39500000e+02],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
camera_matrix_right = np.array([[ 6.24044717e+02, 0.00000000e+00, 3.19500000e+02],
[ 0.00000000e+00, 6.24044717e+02, 2.39500000e+02],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
dist_coeffs_left = np.array([0.0, 0.0, 0.0, 0.0, 0.0])
dist_coeffs_right = np.array([0.0, 0.0, 0.0, 0.0, 0.0])
R = np.array([[0.99996828, 0.00287274, -0.00794566],
[-0.00287338, 0.99999502, 0.00180313],
[ 0.00794456, -0.00180528, 0.99996889]])
T = np.array([-76.1136, 0.0141, -0.5795])
# 创建 StereoSGBM 对象
min_disp = 0
num_disp = 16 * 4
block_size = 5
stereo = cv2.StereoSGBM_create(minDisparity=min_disp,
numDisparities=num_disp,
blockSize=block_size,
P1=8 * 3 * block_size ** 2,
P2=32 * 3 * block_size ** 2,
disp12MaxDiff=1,
uniquenessRatio=10,
speckleWindowSize=100,
speckleRange=32)
while True:
# 读取图片
_, left_frame = left_camera.read()
_, right_frame = right_camera.read()
# 立体校正
R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(camera_matrix_left,
dist_coeffs_left,
camera_matrix_right,
dist_coeffs_right,
(camera_width, camera_height),
R,
T)
left_map1, left_map2 = cv2.initUndistortRectifyMap(camera_matrix_left,
dist_coeffs_left,
R1,
P1,
(camera_width, camera_height),
cv2.CV_32FC1)
right_map1, right_map2 = cv2.initUndistortRectifyMap(camera_matrix_right,
dist_coeffs_right,
R2,
P2,
(camera_width, camera_height),
cv2.CV_32FC1)
left_frame_rectified = cv2.remap(left_frame, left_map1, left_map2, cv2.INTER_LINEAR)
right_frame_rectified = cv2.remap(right_frame, right_map1, right_map2, cv2.INTER_LINEAR)
# 计算视差
gray_left = cv2.cvtColor(left_frame_rectified, cv2.COLOR_BGR2GRAY)
gray_right = cv2.cvtColor(right_frame_rectified, cv2.COLOR_BGR2GRAY)
disparity = stereo.compute(gray_left, gray_right).astype(np.float32) / 16
# 立体匹配
height, width = gray_left.shape
focal_length = width / (2 * np.tan(np.deg2rad(camera_fov / 2)))
baseline = np.linalg.norm(T)
depth = np.zeros(gray_left.shape)
for y in range(height):
for x in range(width):
if disparity[y, x] > 0:
depth[y, x] = (focal_length * baseline) / disparity[y, x]
# 检测球
hsv = cv2.cvtColor(left_frame_rectified, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 70, 50])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([170, 70, 50])
upper_red = np.array([180, 255, 255])
mask2 = cv2.inRange(hsv, lower_red, upper_red)
mask = mask1 + mask2
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
area = cv2.contourArea(contour)
if area > 1000:
(x, y), radius = cv2.minEnclosingCircle(contour)
depth_value = depth[int(y), int(x)]
if depth_value > 0:
print("球半径:", round(radius))
print("球深度:", round(depth_value, 2))
# 显示图像
cv2.imshow("Left Camera", left_frame_rectified)
cv2.imshow("Right Camera", right_frame_rectified)
cv2.imshow("Depth", depth / np.max(depth))
# 退出
if cv2.waitKey(1) == ord('q'):
break
# 释放摄像头
left_camera.release()
right_camera.release()
# 关闭窗口
cv2.destroyAllWindows()
```
请注意,此代码示例仅适用于双目摄像头,并且需要进行摄像头标定以获取摄像头参数。在此基础上,代码使用立体校正和立体匹配技术来计算球的深度,最后使用 HSV 颜色空间和轮廓检测来检测球并计算其半径。
阅读全文