flyfish
import cv2
video_path = 'input_video.mp4'
cap = cv2.VideoCapture(video_path)
while True:
ret, frame = cap.read()
if not ret:
break # 视频结束
# 转灰度
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 高斯模糊(减少噪声)
blurred = cv2.GaussianBlur(frame_gray, (5, 5), 0)
# 边缘检测**
edges = cv2.Canny(blurred, threshold1=100, threshold2=200) # Canny 算子参数
# 可视化结果
cv2.imshow('Original Frame', frame)
cv2.imshow('Edges', edges) # 显示边缘检测结果
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
edges = cv2.Canny(blurred, threshold1=100, threshold2=200)
cv2.Canny
函数:blurred
:输入的模糊后的灰度图像(减少噪声后效果更好)。threshold1=100
:低阈值(用于检测弱边缘)。threshold2=200
:高阈值(用于检测强边缘)。
edges
是单通道二值图像(0 表示非边缘,255 表示边缘)。cv2.imshow('Edges', edges)
Edges
,显示检测到的边缘(黑白图像,白色为边缘)。cv2.imshow('Original Frame', frame)
可选保留,方便对比。threshold1
和 threshold2
100
和 200
:适用于大多数场景,但需根据视频内容调整。threshold1=150, threshold2=250
):threshold1=50, threshold2=150
):(5,5)
:平衡去噪和保留细节。(7,7)
):更强的去噪,但边缘可能更模糊。(3,3)
):保留更多细节,但噪声可能更明显。如果希望将边缘叠加到原图上(彩色显示),可以这样做:
# 将边缘图转换为三通道图像(与原图合并)
edges_color = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
# 合并原图和边缘图(横向拼接)
combined = np.hstack((frame, edges_color))
cv2.imshow('Combined', combined)
apertureSize
:Sobel 算子的核大小(默认 3
,可选 5
增加边缘检测的鲁棒性):edges = cv2.Canny(blurred, 100, 200, apertureSize=5)
Canny 边缘检测是一种经典且广泛应用的边缘检测算法,它具有低错误率、高定位精度和抑制虚假边缘等优点。
在进行边缘检测之前,图像中可能存在噪声,这些噪声会干扰边缘的检测结果。因此,第一步通常是对图像进行高斯平滑处理,使用高斯滤波器来减少噪声。高斯滤波器是一个二维的高斯函数,它对图像中的每个像素及其邻域像素进行加权平均,使得噪声的影响得到抑制。具体来说,就是通过 cv2.GaussianBlur
这样的操作,将图像中的高频噪声去除,让图像变得更加平滑,为后续的边缘检测做准备。
经过高斯平滑后的图像,需要计算其梯度信息,因为边缘通常对应着图像中灰度值变化较大的区域,而梯度可以反映这种变化。一般使用 Sobel 算子分别在水平( x x x 方向)和垂直( y y y 方向)计算梯度。
在计算得到梯度强度和方向后,图像中可能存在很多梯度强度较大的点,但这些点不一定都对应真正的边缘。非极大值抑制的目的是在局部范围内找出梯度强度的极大值点,将非极大值点的梯度值设为 0,从而细化边缘。具体步骤如下:
经过非极大值抑制后,仍然可能存在一些虚假的边缘点。双阈值检测通过设置两个阈值(低阈值 T l o w T_{low} Tlow 和高阈值 T h i g h T_{high} Thigh)来进一步筛选边缘点。具体步骤如下:
import cv2
# 读取图像
image = cv2.imread('example.jpg', 0) # 以灰度模式读取图像
# 进行 Canny 边缘检测
edges = cv2.Canny(image, 100, 200)
# 显示原始图像和边缘检测结果
cv2.imshow('Original Image', image)
cv2.imshow('Canny Edges', edges)
# 等待按键事件
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
cv2.Canny
函数的第二个和第三个参数分别是低阈值和高阈值,你=可以根据实际情况调整这两个参数的值,以获得不同的边缘检测效果。