有什么方法可以跟踪一根辐条的运动?
我之所以这样问,是因为我没有视频处理经验。因此,任何建议都将有所帮助!我在追踪什么?从阅读的内容来看,通常我必须先检测要跟踪的对象。我为此使用了转角检测算法,例如goodfeaturestotrack
。但是,如何确定检测到正确的辐条等?
一些其他信息:视频的帧速率为30fps。车轮仅沿顺时针方向旋转。而且,当我逐帧单击视频时,很明显,一根辐条在两个辐条之间(从一帧到另一帧)的移动角度不超过一半。 另外:轮子的半径是5厘米。
我现在已经尝试了马克的答案。我已经将Tmax
和帧的时间戳记入了txt文件中,然后编写了以下代码来计算相应的速度:
ListOfVelocities = []
for idx in range(1,len(ListOfAngles)):
if ListOfAngles[idx] < ListOfAngles[idx-1]:
rotation = (360-ListOfAngles[idx]) + ListOfAngles[idx-1]
else:
rotation = ListOfAngles[idx] - ListOfAngles[idx-1]
timePassed = VideoTimestamp[idx]-VideoTimestamp[idx-1]
velocity = 2*np.pi/360 * rotation * RADIUS * timePassed
ListOfVelocities.append(velocity)
答案 0 :(得分:2)
我真的不认为这是一个跟踪问题,因为车轮受到约束,因此无法在整个框架上移动,只能改变角度位置,因此您只需要真正知道它在一帧中,下一帧旋转了多少。然后,您就知道了帧速率,即帧之间的时间,就可以计算出速度。
因此,问题是如何辨别与您在上一帧中测量的辐条相同。由于辐条后面的区域很暗,因此您希望轻辐条能很好地形成对比,以便轻松找到它。因此,我将四个辐条涂成黑色,然后您只想在深色背景上寻找一个浅色的辐条。我还考虑将轮子的中心涂成红色(或其他饱和色),以便您可以轻松找到中间。
现在,在处理开始时,通过寻找红色来找到车轮的中心,并在图像中获取其x,y坐标。现在,选择一个半径(以像素为单位),您以后可以更改,并在以红色点为中心并围绕红色点的圆周上计算出x,y坐标的列表,例如360点(每度1个)。这些点和所有正弦/余弦将不会在您的整个处理过程中发生变化,因此请在您的主要视频处理循环之外进行更改。
现在在每个帧处,使用索引来获取360个点中每个点的亮度,并且至少最初将最亮的一个作为辐条。
所以,我在您的图像上粗暴地画了画,所以中心是红色,只有一个辐是白色:
现在代码看起来像这样:
#!/usr/bin/env python3
import math
import numpy as np
from PIL import Image
# Open image and make Numpy version of it too
im = Image.open('wheel.png')
imnp = np.array(im)
# Find centre by looking for red pixels
# See https://stackoverflow.com/a/52183666/2836621
x, y = 193, 168
# Set up list of 360 points on a circle centred on red dot outside main processing loop
radius = 60
# List of X values and Y values on circumference
Xs = []
Ys = []
for theta in range(360):
thetaRad = math.radians(theta)
dx = int(radius * math.sin(thetaRad))
dy = int(radius * math.cos(thetaRad))
Xs.append(x+dx)
Ys.append(y+dy)
# Your main loop processing frames starts here
# Make greyscale Numpy version of image
grey = np.array(im.convert('L'))
sum = 0
Bmax = 0
Tmax = 0
for theta in range(360):
brightness=grey[Ys[theta],Xs[theta]]
sum += brightness
if brightness > Bmax:
Bmax = brightness
Tmax = theta
print(f"theta: {theta}: brightness={brightness}")
# Calculate mean
Mgrey = sum/len(Xs)
print(f"Mean brightness on circumf: {Mgrey}")
# Print peak brightness and matching theta
print(f"Peak brightness: {Bmax} at theta: {Tmax}")
输出如下:
theta: 0: brightness=38
theta: 5: brightness=38
theta: 10: brightness=38
theta: 15: brightness=38
theta: 20: brightness=38
theta: 25: brightness=38
theta: 30: brightness=38
theta: 35: brightness=45
theta: 40: brightness=38
theta: 45: brightness=33
theta: 50: brightness=30
theta: 55: brightness=28
theta: 60: brightness=28
theta: 65: brightness=31
theta: 70: brightness=70
theta: 75: brightness=111
theta: 80: brightness=130
theta: 85: brightness=136
theta: 90: brightness=139 <--- peak brightness at 90 degrees to vertical as per picture - thankfully!
theta: 95: brightness=122
theta: 100: brightness=82
theta: 105: brightness=56
theta: 110: brightness=54
theta: 115: brightness=49
theta: 120: brightness=43
theta: 125: brightness=38
theta: 130: brightness=38
theta: 135: brightness=38
theta: 140: brightness=38
theta: 145: brightness=38
theta: 150: brightness=38
theta: 155: brightness=38
theta: 160: brightness=38
theta: 165: brightness=38
theta: 170: brightness=38
theta: 175: brightness=38
theta: 180: brightness=31
theta: 185: brightness=33
theta: 190: brightness=38
theta: 195: brightness=48
theta: 200: brightness=57
theta: 205: brightness=38
theta: 210: brightness=38
theta: 215: brightness=38
theta: 220: brightness=38
theta: 225: brightness=38
theta: 230: brightness=38
theta: 235: brightness=38
theta: 240: brightness=38
theta: 245: brightness=38
theta: 250: brightness=52
theta: 255: brightness=47
theta: 260: brightness=36
theta: 265: brightness=35
theta: 270: brightness=32
theta: 275: brightness=32
theta: 280: brightness=29
theta: 285: brightness=38
theta: 290: brightness=38
theta: 295: brightness=38
theta: 300: brightness=38
theta: 305: brightness=38
theta: 310: brightness=38
theta: 315: brightness=38
theta: 320: brightness=39
theta: 325: brightness=40
theta: 330: brightness=42
theta: 335: brightness=42
theta: 340: brightness=40
theta: 345: brightness=36
theta: 350: brightness=35
theta: 355: brightness=38
Mean brightness on circumf: 45.87222222222222
Peak brightness: 142 at theta: 89
如果在下一帧中峰值亮度现在与垂直方向成100度,那么您知道轮子已经以1 /(frames_per_second)旋转了10度。
您可能需要改变半径以获得最佳效果-实验!图像上显示的白色半径对应于代码中60个像素的半径。
您可能不希望获取峰值亮度,而是要查找圆周上360像素的亮度的均值和标准偏差,然后将角度作为亮度大于某个数量的角度的平均角度。高于平均值的标准偏差。这取决于您需要的分辨率/精度。
您还可以将由theta索引的圆周围的所有亮度收集到单个360元素数组中,如下所示:
brightnessByTheta = grey[Ys[:],Xs[:]]
您将获得:
array([ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 43, 49, 47, 46, 45, 44, 43, 43,
40, 38, 36, 34, 33, 33, 33, 32, 31, 31, 29, 30, 28,
29, 29, 29, 28, 28, 27, 29, 28, 28, 27, 28, 28, 29,
31, 36, 42, 51, 60, 70, 81, 89, 98, 105, 111, 117, 122,
126, 128, 130, 131, 132, 133, 135, 136, 138, 139, 141, 142, 139,
136, 133, 129, 124, 122, 119, 113, 104, 93, 82, 72, 65, 60,
59, 56, 56, 55, 55, 54, 54, 53, 52, 52, 50, 49, 47,
46, 45, 44, 43, 42, 40, 39, 38, 38, 37, 38, 38, 37,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 34, 31, 31, 31, 31,
31, 31, 32, 33, 34, 35, 36, 37, 38, 42, 43, 44, 45,
48, 49, 50, 51, 55, 57, 60, 64, 65, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 52, 56, 46, 46, 47, 47, 38, 39, 40, 40,
36, 36, 36, 36, 36, 35, 35, 34, 34, 34, 32, 33, 33,
33, 33, 32, 32, 31, 30, 29, 29, 28, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 40, 40, 39, 38, 39, 39, 39,
40, 40, 41, 41, 42, 42, 42, 41, 41, 42, 42, 41, 40,
39, 40, 40, 38, 39, 38, 37, 36, 36, 35, 34, 33, 35,
38, 38, 38, 38, 38, 38, 38, 38, 38], dtype=uint8)
答案 1 :(得分:1)
对于提供的框架,不可能跟踪单个辐条,因为所有辐条的形状和颜色都相同。跟踪一个的实际方法是对辐条进行物理标记。然后,只要您的相机移动了,就需要image registration来对齐框。之后追踪辐条并不难。
编辑:物理标记可以是辐条上的彩色斑点(为简单起见,请使用图像中唯一的颜色)。然后使用thresholding技术选择颜色。然后,您可能需要进行一些增强以消除噪音。
答案 2 :(得分:0)
卢克,马苏德(Masoud)解释的是,您要亲自标记方向盘。这可能是一个小的白色贴纸或一团油漆。如果要转换为灰度,则IMO将是白色的最佳选择。如果是我,我会使用Hough Circle和阈值法找到轮子。装好轮子后,创建一个遮罩以删除背景。剩下的只是轮子。一旦您找到了最亮的点(应该是白色贴纸,油漆斑点或使用的任何东西),请记录下它的位置,最好是中心,并且对于每个框架都执行相同的过程并测量位置的变化并使用找出角动量。
道格