gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: x, y, w,
h = cv2.boundingRect(cnt)
这几行代码的作用是将捕获的图像转换为灰度图像、进行二值化处理、找到数字区域的轮廓,并遍历每个数字轮廓。其中:
- cv2.cvtColor()函数用于将图像从一种颜色空间转换为另一种颜色空间,这里将图像转换为灰度图像。
- cv2.threshold()函数用于将图像进行二值化处理,将图像中的数字部分变为白色,背景部分变为黑色。这里使用自适应阈值算法进行二值化。
- cv2.findContours()函数用于查找图像中的轮廓。第一个参数是二值化后的图像,第二个参数是轮廓的查找方式,第三个参数是轮廓的近似方式。
- cv2.boundingRect()函数用于获取轮廓的矩形框,即数字所在区域的位置和大小。
利用cv2.findContours绘制的轮廓进行光流追踪
使用 cv2.findContours
和光流追踪
为了实现在使用 cv2.findContours
绘制轮廓基础上的光流跟踪,可以按照以下方法操作:
图像预处理
在进行光流追踪之前,通常需要先对图像进行预处理。这一步骤包括将彩色图像转换为灰度图像并应用阈值化或边缘检测来获取二值图像。
import cv2
import numpy as np
cap = cv2.VideoCapture('video.mp4')
ret, frame1 = cap.read()
prvs_frame_gray = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY)
# 对首帧执行轮廓查找
ret, thresh = cv2.threshold(prvs_frame_gray, 127, 255, 0)
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[^1]
hsv = np.zeros_like(frame1)
hsv[...,1] = 255
光流计算
接着利用 Lucas-Kanade 方法或其他适合的方法来进行光流估计。这里采用的是稠密光流法(Dense Optical Flow),该方法能够提供更丰富的运动信息。
while(1):
ret, frame2 = cap.read()
if not ret:
break
next_frame_gray = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(prvs_frame_gray,next_frame_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = ang*180/np.pi/2
hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
rgb = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
# 将当前帧中的轮廓也画出来以便对比观察
current_thresh = cv2.threshold(next_frame_gray, 127, 255, 0)[1]
current_contours, _ = cv2.findContours(current_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_image = frame2.copy()
cv2.drawContours(contour_image, current_contours, -1, (0,255,0), 2)
combined_view = np.hstack((frame2, contour_image, rgb))
cv2.imshow('Combined View',combined_view)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
elif k == ord('s'):
cv2.imwrite('opticalfb.png',frame2)
cv2.imwrite('opticalhsv.png',rgb)
prvs_frame_gray = next_frame_gray
cv2.destroyAllWindows()
cap.release()
上述代码展示了如何结合 cv2.findContours
函数与光流技术一起工作。通过这种方式不仅可以识别目标对象的位置还可以捕捉其移动方向和速度[^4]。
cv2 视频 生成模糊背景
使用OpenCV实现视频中的背景模糊效果
为了实现在视频中应用背景模糊的效果,可以采用多种方法。一种常见的方式是通过边缘保留滤波器来平滑图像并减少噪声,从而达到模糊背景的目的[^1]。
下面是一个完整的Python代码示例,展示了如何读取视频文件、逐帧处理每一帧以创建带有模糊背景的新版本:
import cv2
import numpy as np
def apply_background_blur(frame, kernel_size=(15, 15)):
# 将彩色空间转换为灰度图以便后续操作更简单
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 应用高斯模糊到整个画面
blurred_gray = cv2.GaussianBlur(gray_frame, ksize=kernel_size, sigmaX=0)
# 创建掩码用于区分前景对象和背景区域
_, mask = cv2.threshold(blurred_gray, thresh=80, maxval=255, type=cv2.THRESH_BINARY_INV)
# 对原始色彩图像也做同样的模糊化处理
blurred_color = cv2.GaussianBlur(frame, ksize=kernel_size, sigmaX=0)
# 结合原图与经过模糊化的图片,仅当对应位置像素值大于零时才显示未被遮挡部分
result = np.where(mask[:, :, None], frame, blurred_color)
return result
video_capture = cv2.VideoCapture('input_video.mp4')
while True:
ret, frame = video_capture.read()
if not ret:
break
output_frame = apply_background_blur(frame)
cv2.imshow('Blurred Background Video', output_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
此脚本首先定义了一个apply_background_blur()
函数,该函数接收一帧作为输入参数,并返回已处理过的同一帧,在其中只有背景部分变得模糊而前景保持清晰可见。接着设置了一个循环用来连续获取来自摄像头或预录好的视频流的数据;对于每一张捕获到的画面都会调用上述自定义的方法来进行实时编辑,最后展示给用户观看直到按下键盘上的 'q' 键停止程序运行[^2]。
值得注意的是,这里使用的阈值(即 thresh=80
)可能需要根据具体应用场景调整优化,因为不同的光照条件会影响最佳设定值的选择。此外还可以考虑引入更加复杂的算法比如语义分割模型来提高分离精度[^3]。
相关推荐















