Python 2.7 使用opencv python计算直线中的截距点
我正在使用opencv和python编程进行车辆计数,我已经完成了以下步骤: 1.使用背景减法或MOG2检测移动车辆 2.在上面画一个矩形,然后点一个它的质心 3.画一条线(表示计数的时间) 如果质心与直线相交,我想数一。但在我的代码中,有时会添加有时不。以下是行代码:Python 2.7 使用opencv python计算直线中的截距点,python-2.7,opencv,video-processing,Python 2.7,Opencv,Video Processing,我正在使用opencv和python编程进行车辆计数,我已经完成了以下步骤: 1.使用背景减法或MOG2检测移动车辆 2.在上面画一个矩形,然后点一个它的质心 3.画一条线(表示计数的时间) 如果质心与直线相交,我想数一。但在我的代码中,有时会添加有时不。以下是行代码: cv2.line(帧,(0170),(300170),(200200,0),2) 还有质心: if w > 20 and h > 25: cv2.rectangle(frame, (x,y), (x+w,y
cv2.line(帧,(0170),(300170),(200200,0),2)
还有质心:
if w > 20 and h > 25:
cv2.rectangle(frame, (x,y), (x+w,y+h), (180, 1, 0), 1)
x1=w/2
y1=h/2
cx=x+x1
cy=y+y1
centroid=(cx,cy)
cv2.circle(frame,(int(cx),int(cy)),4,(0,255,0),-1)
我的计数代码:
if cy==170:
counter=counter+1
有人能帮我吗。请谢谢你的建议 假设质心将假定位置170(在x或y中)是错误的,因为视频通常以30 fps的速度工作,这意味着每秒将获得30个质心位置,这意味着即使物体穿过直线,也可能永远不会是170 为了解决这个问题,可以使用的一种方法是定义行边距。这意味着现在在实际行(y=170)之前有一个行边距x,在行边距之后有一个行边距x
因此,如果对象落在边距的任何位置,可以增加计数器。现在,下一个重要部分将是制作一个跟踪机制,在该机制中,您可以收集每个对象的点列表,并检查它是否落在边距中。以下是我的方法,它将独立于视频帧速率。假设您能够在每一帧跟踪一辆车的质心,我将保存最后两个质心的位置(
last_centroid
和centroid
,在我的代码中),并按如下方式处理:
最后一个_质心
和质心
导入cv2
将numpy作为np导入
导入集合
Params=collections.namedtuple('Params',['a','b','c'])#用于存储直线的方程式
def calcParams(点1,点2):#直线方程参数计算
如果点2[1]-点1[1]==0:
a=0
b=-1.0
elif点2[0]-点1[0]==0:
a=-1.0
b=0
其他:
a=(点2[1]-点1[1])/(点2[0]-点1[0])
b=-1.0
c=(-a*点1[0])-b*点1[1]
返回参数(a、b、c)
def areLinesIntersecting(参数1、参数2、点1、点2):
det=params1.a*params2.b-params2.a*params1.b
如果det==0:
返回False#直线平行
其他:
x=(params2.b*-params1.c-params1.b*-params2.c)/det
y=(params1.a*-params2.c-params2.a*-params1.c)/det
如果x=min(点1[0],点2[0]),y=min(点1[1],点2[1]):
打印(“相交于:”,x,y)
cv2.圆(帧,(int(x),int(y)),4,(0,0255),-1)#交点
返回真值#直线在线段内相交
其他:
返回False#直线相交但在线段之外
cv2.namedWindow(‘框架’)
帧=np.0((240320,3),np.uint8)
最后一个_形心=(200200)#t-1处汽车的形心
质心=(210180)#t处汽车的质心
线参数=calcParams(最后一个质心,质心)
截距线参数=calcParams((0170),(300170))
打印(“参数:”,行参数a,行参数b,行参数c)
而(一):
cv2.圆(帧,最后一个质心,4,(0255,0),-1)#最后一个质心
cv2.圆(帧,质心,4,(0255,0),-1)#当前质心
cv2.线(框架,最后一个_质心,质心,(0,0255),1)#t-1和t处车辆质心之间的线段
cv2.线路(帧,(0170),(300170),(200200,0),2)#截取线路
打印(“AreLinesIntersecting:”,AreLinesIntersecting(截距线参数,线参数,最后一个质心,质心))
cv2.imshow(“帧”,帧)
如果cv2.waitKey(15)&0xFF==ord('q'):
打破
cv2.destroyAllWindows()
以下是一些结果:
图一。线段与直线相交(截取蓝色中的直线——在红色中的
最后一个质心
和质心
之间的线段)
图二。线段与直线不相交 N.B.我找到了计算交点的公式
我希望我的方法将有助于解决您的问题。车辆是否总是朝同一方向行驶?如果是这样的话,您可以更改您的检查,以测试车辆是否已越过线路。例如,
if cy@user3510227:谢谢你的回答。对不起,我已经试过代码了,如果是cy,车辆将朝哪个方向行驶?你能上传一个截图或绘图来帮助显示问题吗?@user3510227:谢谢你的帮助,如果我不上传截图,请在中打开。谢谢你的帮助我似乎无法访问你的上传,你能编辑你的答案并把它放在那里吗?首先感谢你的伟大的方法和精彩的解释。那么,如何应用这种方法来检测穿过由鼠标单击事件绘制的切线或斜线的质心呢。
import cv2
import numpy as np
import collections
Params = collections.namedtuple('Params', ['a','b','c']) #to store equation of a line
def calcParams(point1, point2): #line's equation Params computation
if point2[1] - point1[1] == 0:
a = 0
b = -1.0
elif point2[0] - point1[0] == 0:
a = -1.0
b = 0
else:
a = (point2[1] - point1[1]) / (point2[0] - point1[0])
b = -1.0
c = (-a * point1[0]) - b * point1[1]
return Params(a,b,c)
def areLinesIntersecting(params1, params2, point1, point2):
det = params1.a * params2.b - params2.a * params1.b
if det == 0:
return False #lines are parallel
else:
x = (params2.b * -params1.c - params1.b * -params2.c)/det
y = (params1.a * -params2.c - params2.a * -params1.c)/det
if x <= max(point1[0],point2[0]) and x >= min(point1[0],point2[0]) and y <= max(point1[1],point2[1]) and y >= min(point1[1],point2[1]):
print("intersecting in:", x,y)
cv2.circle(frame,(int(x),int(y)),4,(0,0,255), -1) #intersecting point
return True #lines are intersecting inside the line segment
else:
return False #lines are intersecting but outside of the line segment
cv2.namedWindow('frame')
frame = np.zeros((240,320,3), np.uint8)
last_centroid = (200,200) #centroid of a car at t-1
centroid = (210,180) #centroid of a car at t
line_params = calcParams(last_centroid, centroid)
intercept_line_params = calcParams((0,170), (300,170))
print("Params:", line_params.a,line_params.b,line_params.c)
while(1):
cv2.circle(frame,last_centroid,4,(0,255,0), -1) #last_centroid
cv2.circle(frame,centroid,4,(0,255,0), -1) #current centroid
cv2.line(frame,last_centroid,centroid,(0,0,255),1) #segment line between car centroid at t-1 and t
cv2.line(frame,(0,170),(300,170),(200,200,0),2) #intercepting line
print("AreLinesIntersecting: ",areLinesIntersecting(intercept_line_params,line_params,last_centroid,centroid))
cv2.imshow('frame',frame)
if cv2.waitKey(15) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()