Counting the point which intercept in a line with opencv python

ぐ巨炮叔叔 提交于 2019-12-25 01:48:16

问题


I am working in vehicle counting with opencv and python programming, I already complete step: 1. Detect moving vehicle with BackgroundSubtractorMOG2 2. Draw rectangle on it, then poin a centroid of that 3. Draw a line (to indicate of the counting)

if that centroid accros/intercept with the line I want count that 1. but in my code sometime it add sometime no. Here the line code:

cv2.line(frame,(0,170),(300,170),(200,200,0),2)

and there the centroid:

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)

my counting code:

 if cy==170:   
     counter=counter+1

Can anyone help me. please. for your advice thankyou!


回答1:


To assume that the centroid will assume a position 170 (in x or y) is wrong, because videos generally works at 30 fps, that mean you will get 30 centroid locations per second which means even if there the object crosses the line, it may never be 170!

To counter this, one method that can be used is defining a line margin. This means now you have a line margin x before actual line (y = 170) and x after the line margin.

So if your object falls anywhere in the margin, you can increment the counter. Now the next big part would be to make a tracking mechanism wherein you collect the list of point for each object and check if it fell in the margin.




回答2:


Here is my approach that would work independently of the video frame rate. Assuming that you are able to track a car's centroid at each frame, I would save the last two centroids' position (last_centroid and centroid in my code) and process as follows:

  1. compute the intercepting line equation's parameters ( (a,b,c) from aX + bY + c = 0)
  2. compute the equation's parameters of the segment line between last_centroid and centroid
  3. find if the two lines are intersecting
  4. if so, increment your counter

Here is how I implemented it in OpenCV (Python):

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

And here are some results:


Fig1. Segment is intersecting the line (intercepting line in blue - segment line between last_centroid and centroid in red)


Fig2. Segment is NOT intersecting the line

N.B. I found the formulas to calculate the intersection point here.

I hope my approach will help to address your problem.



来源:https://stackoverflow.com/questions/29791075/counting-the-point-which-intercept-in-a-line-with-opencv-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!