admin 管理员组文章数量: 1184232
import cv2
import numpy as np
import time
# 定义HSV阈值范围
h_min = 36
h_max = 98
s_min = 88
s_max = 255
v_min = 76
v_max = 157
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
# 打开摄像头
cap = cv2.VideoCapture(0,cv2.CAP_V4L2)
if not cap.isOpened():
cap = cv2.VideoCapture(0)
raise RuntimeError('not open')
# 设置较低分辨率(如 640x480)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
cap.set(cv2.CAP_PROP_FPS, 15) # 限制帧率
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 减少缓冲区大小
while True:
ret, frame = cap.read()
if not ret:
print("摄像头读取失败,尝试重新初始化...")
cap.release()
time.sleep(1)
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
continue
# 图像预处理
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
# mask = cv2.bilateralFilter(mask, d=5, sigmaColor=50, sigmaSpace=50)
kernel = (5, 5) if frame.shape[1] < 1000 else (10, 10)
kernel_combined = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel_combined, iterations=2)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_combined, iterations=2)
# binary = cv2.adaptiveThreshold(mask, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 2)
edges = cv2.Canny(mask, 50, 150)
# 将处理之后的掩码应用在原始图像上
result = cv2.bitwise_and(frame, frame, mask=mask)
# 在图像x轴中心画一条线
frame_center_x = frame.shape[1] // 2
cv2.line(result, (frame_center_x, 0), (frame_center_x, frame.shape[0]), (0, 255, 0), 2)
# 边缘检测
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
green_cx = None
for i, cnt in enumerate(contours):
if hierarchy[0][i][3] == -1:
inner_contours = [c for j, c in enumerate(contours) if hierarchy[0][j][3] == i]
if inner_contours:
M_outer = cv2.moments(cnt)
if len(max(inner_contours, key=cv2.contourArea)) >= 5:
M_inner = cv2.moments(max(inner_contours, key=cv2.contourArea))
if M_outer['m00'] > 0 and M_inner['m00'] > 0:
cx_outer = int(M_outer["m10"] / M_outer["m00"])
cy_outer = int(M_outer["m01"] / M_outer["m00"])
cx_inner = int(M_inner["m10"] / M_inner["m00"])
cy_inner = int(M_inner["m01"] / M_inner["m00"])
distance = np.sqrt((cx_outer - cx_inner) ** 2 + (cy_outer - cy_inner) ** 2)
if distance < 5:
# 外沿圆以及圆心用蓝色绘制
cv2.circle(result, (cx_outer, cy_outer), 5, (255, 0, 0), -1)
outer_ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(result, outer_ellipse, (255, 0, 0), 2)
# 内沿圆以及圆心用绿色绘制
inner_ellipse = cv2.fitEllipse(max(inner_contours, key=cv2.contourArea))
cv2.ellipse(result, inner_ellipse, (0, 255, 0), 2)
cv2.circle(result, (cx_inner, cy_inner), 5, (0, 255, 0), -1)
green_cx = cx_inner
if green_cx is not None:
# 计算圆心偏移量(像素)
pixel_offset = green_cx - frame_center_x
# 找到外沿椭圆
outer_contour = max(contours, key=cv2.contourArea)
if len(outer_contour) >= 5:
outer_ellipse = cv2.fitEllipse(outer_contour)
(_, _), (outer_a, outer_b), _ = outer_ellipse
# 计算像素与实际长度的比例
outer_avg_axis_pixel = (outer_a + outer_b) / 2
outer_avg_axis_actual = (12 + 12) / 2 # 外沿实际直径平均值
scale = outer_avg_axis_actual / outer_avg_axis_pixel
# 计算实际偏移量(mm)
actual_offset = pixel_offset * scale
# 显示实际偏移量
text = f"Actual Offset: {actual_offset:.2f} mm"
cv2.putText(result, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 显示
cv2.imshow('Color Segmentation', result)
key = cv2.waitKey(1)
if key == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
v_
版权声明:本文标题:从卡顿到流畅:优化摄像头的全面攻略 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1772104098a3552175.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论