第十三篇【传奇开心果系列】Python的OpenCV库技术点案例示例:光流估计

提取关键点和其对应的光流向量

prev_pts = optical_flow[0].reshape(-1, 1, 2)
next_pts = optical_flow[1].reshape(-1, 1, 2)

绘制光流轨迹

for i, (prev_pt, next_pt) in enumerate(zip(prev_pts, next_pts)):
x0, y0 = prev_pt.ravel()
x1, y1 = next_pt.ravel()
cv2.line(prev_frame, (x0, y0), (x1, y1), (0, 255, 0), 2)
cv2.circle(prev_frame, (x1, y1), 5, (0, 0, 255), -1)

显示结果图像

cv2.imshow(‘Optical Flow’, prev_frame)
cv2.waitKey(0)
cv2.destroyAllWindows()


以上代码中,首先读取了两幅相邻的图像,并将其转换为灰度图。然后定义了Lucas-Kanade算法的参数,包括窗口大小、金字塔层数和迭代终止条件。接下来使用`calcOpticalFlowPyrLK`函数计算光流,得到关键点的光流向量。最后,根据光流向量绘制光流轨迹,并展示结果图像。


通过这个示例代码,你可以了解Lucas-Kanade光流算法的基本实现方式,并在自己的项目中进行进一步的应用和调整。注意,代码中的图像路径需要根据实际情况进行修改。


### 三、Horn-Schunck光流介绍和示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/e88a3c6df6c54cad863547a3735903ba.jpg)Horn-Schunck光流是一种经典的光流估计算法,用于估计图像序列中物体的运动。该算法基于光流连续性假设和平滑性约束,通过最小化误差函数来计算像素的位移向量。


Horn-Schunck光流算法的基本思想是,在整个图像区域内,假设像素在两幅相邻图像中的亮度值变化可以由像素位移引起。通过建立一个方程组,可以利用最小二乘法求解得到位移向量。


以下是一个示例代码,展示了如何使用OpenCV实现Horn-Schunck光流算法:



import cv2
import numpy as np

读取两幅相邻图像

prev_frame = cv2.imread(‘previous_frame.jpg’)
next_frame = cv2.imread(‘next_frame.jpg’)

将图像转换为灰度图

prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)

定义Horn-Schunck参数

alpha = 1 # 平滑度权重
iterations = 100 # 迭代次数
epsilon = 0.01 # 终止条件

计算光流

flow = cv2.createOptFlow_HornSchunck()
u, v = flow.calc(prev_gray, next_gray, None, alpha, iterations, epsilon)

绘制光流向量

step = 16 # 绘制间隔
h, w = prev_gray.shape[:2]
y, x = np.mgrid[step//2:h:step, step//2:w:step].reshape(2, -1).astype(int)
fx, fy = u[y, x], v[y, x]
lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
lines = np.int32(lines + 0.5)

绘制光流箭头

flow_img = cv2.cvtColor(prev_gray, cv2.COLOR_GRAY2BGR)
cv2.polylines(flow_img, lines, isClosed=False, color=(0, 255, 0), thickness=1, lineType=cv2.LINE_AA)
for (x1, y1), (x2, y2) in lines:
cv2.arrowedLine(flow_img, (x1, y1), (x2, y2), (0, 255, 0), 2, cv2.LINE_AA, 0, 0.4)

显示结果图像

cv2.imshow(‘Optical Flow’, flow_img)
cv2.waitKey(0)
cv2.destroyAllWindows()


以上代码中,首先读取了两幅相邻的图像,并将其转换为灰度图。然后定义了Horn-Schunck算法的参数,包括平滑度权重、迭代次数和终止条件。接下来使用`createOptFlow_HornSchunck`函数创建光流对象,并利用`calc`方法计算光流,得到位移向量。最后,根据位移向量绘制光流箭头,并展示结果图像。


通过这个示例代码,你可以了解Horn-Schunck光流算法的基本实现方式,并在自己的项目中进行进一步的应用和调整。注意,代码中的图像路径需要根据实际情况进行修改。


### 四、cv::calcOpticalFlowPyrLK()函数实现光流估计介绍和示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/42ae8c533acd42dda7edcd732c5307f4.jpg)cv::calcOpticalFlowPyrLK()函数是OpenCV中用于实现Lucas-Kanade光流算法的函数。它通过金字塔法处理图像,并使用KLT(Kanade-Lucas-Tomasi)算法进行光流估计。


该函数的基本使用方式如下:



#include <opencv2/opencv.hpp>

int main()
{
cv::Mat prev_frame, next_frame;
// 读取两幅相邻图像

cv::Mat prev_gray, next_gray;
cv::cvtColor(prev_frame, prev_gray, cv::COLOR_BGR2GRAY);
cv::cvtColor(next_frame, next_gray, cv::COLOR_BGR2GRAY);
// 将图像转换为灰度图

std::vector<cv::Point2f> prev_pts, next_pts;
// 定义特征点的容器

std::vector<uchar> status;
std::vector<float> error;
// 定义状态和误差容器

cv::Size win\_size(15, 15);
int max_level = 2;
cv::TermCriteria criteria(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 10, 0.03);
// 定义Lucas-Kanade参数

cv::calcOpticalFlowPyrLK(prev_gray, next_gray, prev_pts, next_pts, status, error, win_size, max_level, criteria);
// 计算光流

// 处理光流结果

return 0;

}


上述代码中,首先需要读取两幅相邻的图像,并将其转换为灰度图。然后定义了特征点的容器,用于存储光流计算的结果。接下来定义了状态和误差的容器,用于存储每个特征点的状态和误差信息。然后设置Lucas-Kanade算法的参数,包括窗口大小、金字塔层数和迭代终止条件。最后调用cv::calcOpticalFlowPyrLK()函数计算光流。


函数的输入参数包括两幅灰度图像prev\_gray和next\_gray,以及先前帧的特征点prev\_pts。函数的输出参数包括下一帧的特征点next\_pts,每个特征点的状态status(1表示成功,0表示失败),以及每个特征点的误差error。


通过处理光流结果,你可以根据需要进行进一步的分析和应用,比如绘制光流轨迹或进行目标跟踪等。


注意,以上示例代码仅展示了cv::calcOpticalFlowPyrLK()函数的基本使用方式,实际应用中可能还需要进行参数调优和异常处理等操作。另外,需要包含OpenCV的头文件,并确保正确链接OpenCV库。


### 五、光流估计用于运动分析任务介绍和示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/98f4489066a84b52a11a1a306d6320ec.jpg)光流估计在运动分析任务有着广泛的应用。通过分析图像序列物体的运动情况,可以获取关于运动速度、方向和轨迹等信息,从而实现对运动的分析和理解。


在运动分析任务中,光流估计可以帮助实现以下几个方面的功能:


1. 运动检测:通过比较相邻帧之间的光流向量,可以检测到图像中发生的运动,并将静态和动态部分进行区分。
2. 运动跟踪:利用光流估计的结果,可以实现目标的跟踪。通过追踪目标在图像中的位置变化,可以实时获取目标的运动轨迹。
3. 运动分割:光流估计可以用于将图像分割为具有相似运动的区域。通过聚类光流向量,可以将具有相似运动模式的像素分组到一起,从而实现对图像的运动分割。


下面是一个示例代码,展示了如何使用OpenCV进行运动分析:



import cv2

读取两幅相邻图像

prev_frame = cv2.imread(‘previous_frame.jpg’)
next_frame = cv2.imread(‘next_frame.jpg’)

将图像转换为灰度图

prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)

定义光流估计参数

lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

计算光流

optical_flow = cv2.calcOpticalFlowPyrLK(prev_gray, next_gray, None, None, **lk_params)

提取关键点和其对应的光流向量

prev_pts = optical_flow[0].reshape(-1, 1, 2)
next_pts = optical_flow[1].reshape(-1, 1, 2)

绘制光流轨迹

for i, (prev_pt, next_pt) in enumerate(zip(prev_pts, next_pts)):
x0, y0 = prev_pt.ravel()
x1, y1 = next_pt.ravel()
cv2.line(prev_frame, (x0, y0), (x1, y1), (0, 255, 0), 2)
cv2.circle(prev_frame, (x1, y1), 5, (0, 0, 255), -1)

显示结果图像

cv2.imshow(‘Optical Flow’, prev_frame)
cv2.waitKey(0)
cv2.destroyAllWindows()


以上代码中,首先读取了两幅相邻的图像,并将其转换为灰度图。然后定义了光流估计的参数。接下来使用`calcOpticalFlowPyrLK()`函数计算光流,得到关键点的光流向量。最后,根据光流向量绘制光流轨迹,并展示结果图像。


通过这个示例代码,你可以实现简单的运动分析,如光流轨迹的绘制。根据实际需求,你还可以进一步扩展代码,实现更复杂的运动分析任务,比如运动检测、运动跟踪和运动分割等。


### 六、光流估计用于视频稳定任务介绍和示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/f12f44190db84a3087130677b2bd88d8.jpg)光流估计在视频稳定任务中有着重要的应用。通过分析图像序列中物体的运动情况,可以实现对视频中的抖动和晃动进行校正,从而达到视频稳定的效果。


在视频稳定任务中,光流估计的基本思想是通过计算相邻帧之间的光流向量,推断出物体的运动轨迹,并将其应用于视频帧的校正。一种常见的方法是使用光流向量来估计相机的运动,然后通过图像变换来校正视频帧。


以下是一个示例代码,展示了如何使用OpenCV进行视频稳定:



import cv2
import numpy as np

读取视频文件

cap = cv2.VideoCapture(‘input_video.mp4’)

获取第一帧图像

ret, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)

设置视频输出参数

output_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
output_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*‘mp4v’)
out = cv2.VideoWriter(‘output_video.mp4’, fourcc, fps, (output_width, output_height))

while True:
# 读取当前帧图像
ret, next_frame = cap.read()
if not ret:
break

next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)

# 计算光流
lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
optical_flow = cv2.calcOpticalFlowPyrLK(prev_gray, next_gray, None, None, \*\*lk_params)

# 提取关键点和其对应的光流向量
prev_pts = optical_flow[0].reshape(-1, 1, 2)
next_pts = optical_flow[1].reshape(-1, 1, 2)

# 计算平均光流向量
mean_x = np.mean(next_pts[:, :, 0] - prev_pts[:, :, 0])
mean_y = np.mean(next_pts[:, :, 1] - prev_pts[:, :, 1])

# 构建仿射矩阵
affine_matrix = np.float32([[1, 0, mean_x], [0, 1, mean_y]])

# 对当前帧进行校正
stabilized_frame = cv2.warpAffine(next_frame, affine_matrix, (output_width, output_height))

# 写入输出视频
out.write(stabilized_frame)

# 更新前一帧图像和关键点
prev_gray = next_gray.copy()

释放资源

cap.release()
out.release()
cv2.destroyAllWindows()


以上代码中,首先读取输入视频文件,并获取第一帧图像。然后通过循环读取每一帧图像,将其转换为灰度图像。接下来使用`calcOpticalFlowPyrLK()`函数计算光流,得到关键点的光流向量。然后计算光流向量的平均值,并构建仿射矩阵进行校正。最后将校正后的帧写入输出视频文件。


通过这个示例代码,你可以实现简单的视频稳定功能。需要注意的是,实际应用中可能需要根据视频的特点和需求进行参数调优和异常处理等操作。另外,需要安装OpenCV库,并确保正确读取和写入视频文件。


### 七、光流估计用于目标跟踪任务介绍和示例代码


![在这里插入图片描述](https://img-blog.csdnimg.cn/4457ad967b374112aaae997fd75475ff.jpg)光流估计在目标跟踪任务中有着广泛的应用。通过分析图像序列中物体的运动情况,可以实现对目标的位置变化进行估计和预测,从而实现目标的跟踪。


在目标跟踪任务中,光流估计可以帮助实现以下几个方面的功能:


1. 目标定位:通过计算相邻帧之间的光流向量,可以推断出目标的位置变化,并将其用于目标的定位。
2. 目标预测:利用光流估计的结果,可以预测目标在未来帧中的位置,从而实现目标的预测和预警。
3. 目标匹配:通过比较不同帧之间的光流向量,可以找到具有相似运动模式的像素点,从而实现目标的匹配和关联。


以下是一个示例代码,展示了如何使用OpenCV进行目标跟踪:



import cv2

读取视频文件

cap = cv2.VideoCapture(‘input_video.mp4’)

创建Tracker对象

tracker = cv2.TrackerKCF_create()

读取第一帧图像

ret, frame = cap.read()
bbox = cv2.selectROI(‘Select Object’, frame, False)
tracker.init(frame, bbox)

while True:
# 读取当前帧图像
ret, frame = cap.read()
if not ret:
break

文末有福利领取哦~

👉一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。img

👉二、Python必备开发工具

img
👉三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
img

👉 四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
img

👉五、Python练习题

检查学习结果。
img

👉六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
img

img

👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值