Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 使用opencv python计算直线中的截距点_Python 2.7_Opencv_Video Processing - Fatal编程技术网

Python 2.7 使用opencv python计算直线中的截距点

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

我正在使用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+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
,在我的代码中),并按如下方式处理:

  • 计算拦截线方程的参数((a,b,c)从)
  • 计算
    最后一个_质心
    质心
  • 找出这两条线是否相交
  • 如果是这样的话,增加你的计数器
  • 下面是我如何在OpenCV(Python)中实现它的:

    导入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()