Python 代码使用 OpenCV 库实现了从摄像头获取视频流,并在视频中检测特定颜色区域的边缘线条
import cv2
import numpy as np
#想和大神交朋友或想软件开发兼职接项目,请通过手机端搜小#程#序: "黄页小艺" 。
def extend_line_to_borders(x1, y1, x2, y2, width, height):
# Compute the slope and intercept
if x1 == x2 or abs(x2 - x1) < 1e-6: # Vertical line
return [(x1, 0), (x1, height)]
else:
slope = (y2 - y1) / (x2 - x1)
intercept = y1 - slope * x1
# Compute intersections with image borders
y_at_x_min = int(intercept) # x = 0
y_at_x_max = int(slope * width + intercept) # x = width
if slope != 0:
x_at_y_min = int(-intercept / slope) # y = 0
x_at_y_max = int((height - intercept) / slope) # y = height
else:
x_at_y_min = 0
x_at_y_max = width
points = []
if 0 <= y_at_x_min <= height:
points.append((0, y_at_x_min))
if 0 <= y_at_x_max <= height:
points.append((width, y_at_x_max))
if 0 <= x_at_y_min <= width:
points.append((x_at_y_min, 0))
if 0 <= x_at_y_max <= width:
points.append((x_at_y_max, height))
return points[:2] # Return two intersection points
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("无法打开摄像头")
exit()
# Set camera properties
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25)
cap.set(cv2.CAP_PROP_EXPOSURE, -5)
cap.set(cv2.CAP_PROP_AUTO_WB, 0)
cap.set(cv2.CAP_PROP_WB_TEMPERATURE, 4000)
# Color range in HSV
lower_color = np.array([0, 0, 70])
upper_color = np.array([92, 70, 219])
while True:
ret, frame = cap.read()
if not ret:
print("无法接收到帧 (摄像头已断开)")
break
# Convert to HSV color space
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Filter black and white color regions
mask = cv2.inRange(hsv, lower_color, upper_color)
# Use Canny edge detection
edges = cv2.Canny(frame, 100, 300)
# Hough Line Transform to detect lines
lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi/180, threshold=100, minLineLength=100, maxLineGap=10)
# Get image dimensions
height, width = frame.shape[:2]
if lines is not None:
if len(lines) == 1:
# Only one line detected
x1, y1, x2, y2 = lines[0][0]
points = extend_line_to_borders(x1, y1, x2, y2, width, height)
if len(points) == 2:
cv2.line(frame, points[0], points[1], (0, 255, 0), 2)
else:
found_pair = False
# Compute angles between pairs of lines
for i in range(len(lines)):
for j in range(i + 1, len(lines)):
x1_i, y1_i, x2_i, y2_i = lines[i][0]
x1_j, y1_j, x2_j, y2_j = lines[j][0]
# Direction vectors
v1 = np.array([x2_i - x1_i, y2_i - y1_i])
v2 = np.array([x2_j - x1_j, y2_j - y1_j])
# Normalize vectors
v1_norm = np.linalg.norm(v1)
v2_norm = np.linalg.norm(v2)
if v1_norm == 0 or v2_norm == 0:
continue # Skip zero-length vectors
v1_unit = v1 / v1_norm
v2_unit = v2 / v2_norm
# Compute angle between vectors
dot_product = np.dot(v1_unit, v2_unit)
angle = np.arccos(dot_product) * 180 / np.pi # In degrees
# Check if angle is approximately 90 degrees
if abs(angle - 90) < 10: # Threshold of 10 degrees
# Extend and draw the lines
points_i = extend_line_to_borders(x1_i, y1_i, x2_i, y2_i, width, height)
points_j = extend_line_to_borders(x1_j, y1_j, x2_j, y2_j, width, height)
if len(points_i) == 2 and len(points_j) == 2:
cv2.line(frame, points_i[0], points_i[1], (0, 255, 0), 2)
cv2.line(frame, points_j[0], points_j[1], (0, 255, 0), 2)
found_pair = True
break
if found_pair:
break
else:
# If no perpendicular pair found, you may choose to draw a single longest line or take other action
pass
# Display the frame with detected lines
cv2.imshow('Camera', frame)
# Press 'q' to exit
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
#想和大神交朋友或想软件开发兼职接项目,请通过手机端搜小#程#序: "黄页小艺" 。
上面 Python 代码使用 OpenCV 库实现了从摄像头获取视频流,并在视频中检测特定颜色区域的边缘线条,然后进行以下操作:
一、定义辅助函数
extend_line_to_borders
函数:- 该函数用于将给定的线段延长至图像的边界。
- 首先计算线段的斜率和截距。如果线段是垂直的(斜率为无穷大或接近无穷大),则直接返回与图像上下边界的交点。
- 对于非垂直线段,根据斜率和截距计算与图像四个边界的交点。
- 最后返回两个交点(如果存在)。
二、摄像头设置与图像预处理
-
打开摄像头并设置摄像头属性:
- 使用
cv2.VideoCapture(0)
打开默认摄像头。 - 设置摄像头的分辨率为 1280x720,自动曝光为特定值,手动设置曝光值为 -5,关闭自动白平衡并设置白平衡温度为 4000。
- 使用
-
定义颜色范围并进行图像处理:
- 在 HSV 颜色空间中定义一个颜色范围,用于过滤出特定颜色(可能是接近黑色和白色的颜色范围)。
- 将每一帧图像从 BGR 颜色空间转换为 HSV 颜色空间。
- 使用
cv2.inRange
函数根据定义的颜色范围创建一个掩码,用于过滤出特定颜色区域。 - 使用 Canny 边缘检测算法对图像进行边缘检测,得到边缘图像。
三、线条检测与绘制
-
使用 Hough 变换检测直线:
- 通过
cv2.HoughLinesP
函数在边缘图像上检测直线。
- 通过
-
处理检测到的直线:
- 如果只检测到一条直线,使用
extend_line_to_borders
函数将该直线延长至图像边界,并在图像上绘制延长后的直线。 - 如果检测到多条直线,计算每对直线之间的夹角。如果夹角接近 90 度(在 10 度误差范围内),将这两条直线延长至图像边界并绘制在图像上。如果没有找到垂直的直线对,则可以选择绘制最长的直线或采取其他操作。
- 如果只检测到一条直线,使用
-
显示图像并等待退出:
- 使用
cv2.imshow
函数显示带有检测到的直线的图像帧。 - 当用户按下’q’键时,退出循环并释放摄像头资源,关闭所有窗口。
- 使用
总体来说,这段代码实现了一个实时的视频处理程序,用于在摄像头捕获的视频中检测特定颜色区域的边缘,并找到垂直或接近垂直的直线对,将其延长至图像边界并绘制在图像上。#想和大神交朋友或想软件开发兼职接项目,请通过手机端搜小#程#序: “黄页小艺” 。