Search code examples
pythonopencvcomputer-visionkalman-filter

Opencv Python Kalman filter prediction outcome query


I've been using Opencv with python, I'm using the kalman filter on a rectangle i've got using background subtraction and MOSSE, then on this I'm going to predict the next location with another rectangle in a different colour. The prediction output comes out offset too much.

strawberry walking

I've edited the different results, the main issue is I'm unsure on the kalman implementation in Opencv as the documentation isn't great, its hard to know what it returns.

This is my Kalman method (I've looked at examples, and I understand the basics, but I've assumed this should work to be honest).

kf = cv2.KalmanFilter(4, 2)
kf.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)
kf.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)

def Estimate(self, coordX, coordY):
    measured = np.array([[np.float32(coordX)], [np.float32(coordY)]])
    self.kf.correct(measured)
    predicted = self.kf.predict()
    return predicted

Then per box found I run this

kalmanPredict = Kalman().Estimate(newbox[0],newbox[1])

kalmanPredict[0] = kalmanPredict[0] + newbox[0]
kalmanPredict[1] = kalmanPredict[1] + newbox[1]

p = np.asarray(self.centralize((p1,p2), (kalmanPredict[0],kalmanPredict[1])))
p = np.int0(p)

kpt1 = p[0],p[1]
kpt2 = p[2],p[3]

cv2.rectangle(frame, kpt1, kpt2, (255,0,0),2)

centralize is a method I tested online that just centers the points.

    def centralize(self, box, c):
        pt1, pt2 = box
        xA, yA = pt1
        xB, yB = pt2
        cx, cy = c
        w = xB - xA
        h = yB - yA
        halfW = int(w/2)
        halfH = int(h/2)
        xA = cx - halfW
        yA = cy - halfH
        xB = xA + w
        yB = yA + h
        return xA, yA, xB, yB

it should take into account position/velocity - but just unsure with these docs, and the resources online. Any help would be much appreciated, thanks.


Solution

  • I think I have solved it, I believe it isn't the center points it returns, it the xy coords of the top left corner of the new rect - so I just addded width and height to the second bounding box x,y coords.

    kalmanPredict = Kalman().Estimate(newbox[0],newbox[1])
    
    kalx1 = kalmanPredict[0] 
    kaly1 = kalmanPredict[1]
    
    kal1 = (kalx1, kaly1)
    
    kalx = kalmanPredict[0] + w
    kaly = kalmanPredict[1] + h
    
    kal2 = (kalx, kaly)
    
    cv2.rectangle(frame, kal1, kal2, (255,0,0),2)