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

aij0ehis  于 2023-05-07  发布在  Python
关注(0)|答案(1)|浏览(195)

bounty还有6天到期。回答此问题可获得+500声望奖励。S Andrew希望引起更多关注这个问题。

使用光流,我试图检测连接到电机的线圈的运动。当电机启动时,线圈运行平稳,但有时会开始振动。我需要探测到这种震动。我不确定光流是否是正确的方法,但当测试与稳定的运动与振动,我可以看到一些颜色显示在振动。随附图片:
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()

当有运动时,光流以颜色的形式显示它,所以我猜必须有某种方法来找出阈值。有没有人能帮我一下,或者给我指个方向?

x6yk4ghg

x6yk4ghg1#

我认为使用平均幅度应该适用于阈值振动。cv2.calcOpticalFlowFarneback()返回
使用算法找到每个prev像素的光流,使得prev(y,x)next(y+flow(y,x),x+flow(y,x)[0])
因此,当我们将其移动到极坐标并获得幅度和Angular 时,Angular 显示流动的方向,幅度显示像素移动了多少。
下面的代码是平均每个帧的幅度,并按时间绘制它,这样你就可以看到平均幅度如何通过线圈振动变化。

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秒视频样本的情节。

相关问题