如何在 Python OpenCV 的光流中找到阈值数

问题描述 投票:0回答:1

使用光流,我试图检测连接到电机的线圈的运动。电机启动时,线圈运行平稳,但有时会开始振动。我需要检测这种振动。我不确定光流是否是正确的方法,但是当用稳定的运动与振动进行测试时,我可以看到在振动过程中显示出一些颜色。附上图片:

stable (running smoothly)

Vibration

在完整的视频帧上做光流是行不通的,所以我裁剪了线圈的角,当它开始振动时你可以看到很多颜色显示,因为当它平稳运行时,看不到太多运动,但当它开始振动时振动,运动是可见的,因此它在光流中被拾取。

现在我正试图找出某种阈值,以便我可以在它开始振动、低振动和高振动时进行打印。

使用以下代码:

import cv2
import numpy as np

cap = cv2.VideoCapture("Coil.mp4")
ret, frame1 = cap.read()
frame1 = frame1[284: 383, 498:516]
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[..., 1] = 255


while cap:
    ret, frame2 = cap.read()
    frame2 = frame2[284: 383, 498:516]
    next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    flow = cv2.calcOpticalFlowFarneback(prvs, next, 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)

    cv2.imshow('Optical Flow', rgb)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
    prvs = next

cap.release()
cv2.destroyAllWindows()

当有运动时,光流以颜色的形式显示它,所以我猜必须有某种方法来找出阈值。谁能帮我指出正确的方向?

python-3.x opencv opticalflow
1个回答
0
投票

我认为使用平均幅度应该适用于阈值振动。 cv2.calcOpticalFlowFarneback() 返回一个向量

使用算法找到每个前一个像素的光流,以便 prev(y,x)∼next(y+flow(y,x),x+flow(y,x)[0])

所以当我们将它移动到极坐标并获得大小和角度时,角度显示流的方向,大小显示像素移动了多少。

下面的代码对每一帧的幅度进行平均,并按时间绘制它,这样你就可以看到线圈振动的平均幅度是如何变化的。

import cv2
import numpy as np
import matplotlib.pyplot as plt

cap = cv2.VideoCapture("Coil.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
ret, frame1 = cap.read()
frame1 = frame1[284: 383, 498:516]
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

mags = []
while True:
    ret, frame2 = cap.read()
    if not ret:
        break
    frame2 = frame2[284: 383, 498:516]
    next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
    mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
    mag_mean = cv2.mean(mag)
    mags.append(mag_mean)
    prvs = next

mags_arr = np.array(mags)
time_arr = np.arange(len(mags)) / fps
plt.plot(time_arr, mags_arr)
plt.savefig("vibrate-time.png")

最后你有振动/时间图表,你可以选择高振动和低振动的阈值。

这是我测试过的 12 秒示例视频的情节。

© www.soinside.com 2019 - 2024. All rights reserved.