code:
import cv2
from filterpy.kalman import KalmanFilter
from ultralytics import YOLO
import numpy as np
import pandas as pd
from sktime.datatypes._panel._convert import from_2d_array_to_nested
from pickle import load
from sktime.datatypes._panel._convert import from_nested_to_2d_array

model = YOLO('/Users/surabhi/Documents/kalman/best.pt')

kf = KalmanFilter(dim_x=4, dim_z=2)
kf.x = np.array([0, 0, 0, 0]) # initial state estimate
kf.P = np.eye(4) * 1000 # initial error covariance matrix
kf.F = np.array([[1, 0, 1, 0],
                 [0, 1, 0, 1],
                 [0, 0, 1, 0],
                 [0, 0, 0, 1]]) # state transition matrix
kf.H = np.array([[1, 0, 0, 0],
                 [0, 1, 0, 0]]) # measurement matrix
kf.R = np.diag([0.1, 0.1]) # measurement noise covariance matrix
kf.Q=  np.diag([0.1, 0.1, 0.1, 0.1])
dt = 1.0
u = np.zeros((4, 1))

cap = cv2.VideoCapture("1_1.mp4")
frame_num = 0
predicted_points = []
bounce_detected = False 
last_bounce_frame = -5
test_df = pd.DataFrame(columns=[ 'x', 'y', 'V'])

while True:
    ret, frame = cap.read()
    if ret is False:
        break
    bbox = model(frame, show=True)
    frame_num += 1
    for boxes_1 in bbox:
        result = boxes_1.boxes.xyxy
        if len(result) == 0:
            print("not detected")
        else:
            cx = int((result[0][0] + result[0][2]) / 2)
            cy = int((result[0][1] + result[0][3]) / 2)
            centroid = np.array([cx, cy])
            kf.predict()
            kf.update(centroid)
            next_point = (kf.x).tolist()
            predicted_points.append((int(next_point[0]), int(next_point[1])))
            if len(predicted_points) > 2:
                p1 = np.array(predicted_points[-2])
                p2 = np.array(predicted_points[-1])
                ball_vector = p2 - p1
                ball_speed = np.linalg.norm(ball_vector)
                if ball_speed > 0:
                    ball_direction = ball_vector / ball_speed
                    frame_boundary = np.array([frame.shape[1], frame.shape[0]])
                    to_boundary = (frame_boundary - p2) / ball_direction
                    bounce_point = p2 + ball_direction * to_boundary.min()
                    if not np.all(frame_boundary > bounce_point) or not np.all(bounce_point > 0):
                        bounce_point = p2
                    print("Bounce Point:", tuple(map(int, bounce_point)))
                    cv2.circle(frame, tuple(map(int, bounce_point)), 5, (0, 0, 0), 10)
            V=np.sqrt(kf.x[2]**2 + kf.x[3]**2)
            test_df = test_df.append({ 'x': next_point[0], 'y': next_point[1], 
                                                    'V': np.sqrt(kf.x[2]**2 + kf.x[3]**2)}, 
                                                   ignore_index=True)
            print(test_df)
            print("ENTER LOOP")
            for i in range(20, 0, -1): 
                test_df[f'lagX_{i}'] = test_df['x'].shift(i, fill_value=0)
                for i in range(20, 0, -1): 
                    test_df[f'lagY_{i}'] = test_df['y'].shift(i, fill_value=0)
                for i in range(20, 0, -1): 
                    test_df[f'lagV_{i}'] = test_df['V'].shift(i, fill_value=0)

            test_df.drop(['x', 'y', 'V'], 1, inplace=True)
            print(test_df)

            Xs = test_df[['lagX_20', 'lagX_19', 'lagX_18', 'lagX_17', 'lagX_16',
            'lagX_15', 'lagX_14', 'lagX_13', 'lagX_12', 'lagX_11', 'lagX_10',
            'lagX_9', 'lagX_8', 'lagX_7', 'lagX_6', 'lagX_5', 'lagX_4', 'lagX_3',
            'lagX_2', 'lagX_1']]
            Xs = from_2d_array_to_nested(Xs.to_numpy())

            Ys = test_df[['lagY_20', 'lagY_19', 'lagY_18', 'lagY_17',
                    'lagY_16', 'lagY_15', 'lagY_14', 'lagY_13', 'lagY_12', 'lagY_11',
                    'lagY_10', 'lagY_9', 'lagY_8', 'lagY_7', 'lagY_6', 'lagY_5', 'lagY_4',
                    'lagY_3', 'lagY_2', 'lagY_1']]
            Ys = from_2d_array_to_nested(Ys.to_numpy())

            Vs = test_df[['lagV_20', 'lagV_19', 'lagV_18',
                    'lagV_17', 'lagV_16', 'lagV_15', 'lagV_14', 'lagV_13', 'lagV_12',
                    'lagV_11', 'lagV_10', 'lagV_9', 'lagV_8', 'lagV_7', 'lagV_6', 'lagV_5',
                    'lagV_4', 'lagV_3', 'lagV_2', 'lagV_1']]
            Vs = from_2d_array_to_nested(Vs.to_numpy())

            X = pd.concat([Xs, Ys, Vs], 1)
            X_2d = from_nested_to_2d_array(X)
            # load the pre-trained classifier  
            clf = load(open('clf.pkl', 'rb'))

            predcted = clf.predict(X_2d)
            idx = list(np.where(predcted == 1)[0])
            print("**************************************")
            print(idx)
            idx = np.array(idx) - 10
            print(idx)
                        

            if len(predicted_points) > 10:
                predicted_points.pop(0)

            if not bounce_detected and frame_num - last_bounce_frame > 10:
                if round(V)==19 or round(V)==22 : # If Y acceleration is less than the negative threshold, say -15
                    bounce_detected = True
                    last_bounce_frame = frame_num
                    print("Bounce detected")
                    
            print("next_point", next_point)
            print("frame_number", frame_num)
            cv2.putText(frame, f'Frame: {frame_num}', (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            cv2.circle(frame, (cx, cy), 5, (0,0,255), 5)
            cv2.circle(frame, (int(next_point[0]), int(next_point[1])), 5, (255, 0, 0), 10)
            for i, p in enumerate(predicted_points):
                color = (255,255,255)
                cv2.circle(frame, p, 5, color, 2)
            if bounce_detected:
                cv2.putText(frame, 'Bounce Detected', (10, 350), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            if kf.x[3] > 0: # After a bounce is detected, wait until acceleration is above the threshold, say -5, to detect the bounce again
                bounce_detected = False
        
           # test_df_1=pd.DataFrame({'frame': frame_num , 'x': next_point[0], 'y':next_point[1], 'vx':vx,'vy':vy ,'V': V}, index=[0])
            #test_df.concat(test_df_1)
            #test_df=pd.concat([test_df,test_df_1], ignore_index=True)
            #test_df.to_csv('file.csv')
            cv2.imshow('raw', frame)
            #test_df=pd.DataFrame()
           # test_df=pd.concat([test_df,test_df_1], ignore_index=True)
           # print(trajectory_df)
            test_df.to_csv('file.csv')
            #test_df_1=pd.DataFrame({'frame': frame_num , 'x': next_point[0], 'y':next_point[1], 'vx':vx,'vy':vy ,'V': V}, index=[0])
            # Uncomment the following lines to save the output video
            # out.write(frame)
            # if cv2.waitKey(1) & 0xFF == ord('q'):
            #     break
cap.release()
cv2.destroyAllWindows()
error:
TypeError: X must be in an sktime compatible format, of scitype Series, Panel or Hierarchical, for instance a pandas.DataFrame with sktime compatible time indices, or with MultiIndex and last(-1) level an sktime compatible time index. Allowed compatible mtype format specifications are: ['pd.Series', 'pd.DataFrame', 'np.ndarray', 'nested_univ', 'numpy3D', 'pd-multiindex', 'df-list', 'pd_multiindex_hier'] . See the data format tutorial examples/AA_datatypes_and_datasets.ipynb. If you think the data is already in an sktime supported input format, run sktime.datatypes.check_raise(data, mtype) to diagnose the error, where mtype is the string of the type specification you want. Error message for checked mtypes, in format [mtype: message], as follows: [pd.DataFrame: X must have unique column indices, but found Index(['0__0', '0__1', '0__2', '0__3', '0__4', '0__5', '0__6', '0__7', '0__8',
       '0__9', '0__10', '0__11', '0__12', '0__13', '0__14', '0__15', '0__16',
       '0__17', '0__18', '0__19', '0__0', '0__1', '0__2', '0__3', '0__4',
       '0__5', '0__6', '0__7', '0__8', '0__9', '0__10', '0__11', '0__12',
       '0__13', '0__14', '0__15', '0__16', '0__17', '0__18', '0__19', '0__0',
       '0__1', '0__2', '0__3', '0__4', '0__5', '0__6', '0__7', '0__8', '0__9',
       '0__10', '0__11', '0__12', '0__13', '0__14', '0__15', '0__16', '0__17',
       '0__18', '0__19'],
      dtype='object')]  [pd.Series: X must be a pandas.Series, found <class 'pandas.core.frame.DataFrame'>]  [np.ndarray: X must be a numpy.ndarray, found <class 'pandas.core.frame.DataFrame'>]  [df-list: X must be list of pd.DataFrame, found <class 'pandas.core.frame.DataFrame'>]  [numpy3D: X must be a numpy.ndarray, found <class 'pandas.core.frame.DataFrame'>]  [pd-multiindex: X must have a MultiIndex, found <class 'pandas.core.indexes.range.RangeIndex'>]  [nested_univ: X All columns must be object, found <class 'pandas.core.frame.DataFrame'>]  [pd_multiindex_hier: X must have a MultiIndex, found <class 'pandas.core.indexes.range.RangeIndex'>]