自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

目標(biāo)跟蹤器 | Kalman + FAST 預(yù)測(cè)物體運(yùn)動(dòng) | 附代碼

開(kāi)發(fā)
在本文中,我將展示如何使用卡爾曼濾波器和FAST算法來(lái)跟蹤物體并預(yù)測(cè)物體的運(yùn)動(dòng)。

對(duì)于目標(biāo)跟蹤,有諸如FAST、SURF、SIFT和ORB等特征提取算法。在從目標(biāo)物體提取特征后,可以嘗試對(duì)每一幀的這些特征進(jìn)行跟蹤,通過(guò)這種方式,可以創(chuàng)建一個(gè)簡(jiǎn)單的目標(biāo)跟蹤器。但是,如何預(yù)測(cè)物體的運(yùn)動(dòng)呢?可能想知道1秒后目標(biāo)物體將位于何處。僅使用特征提取算法是無(wú)法做到的,但不用擔(dān)心,卡爾曼濾波器非常適合運(yùn)動(dòng)預(yù)測(cè)任務(wù)。在本文中,我將展示如何使用卡爾曼濾波器和FAST算法來(lái)跟蹤物體并預(yù)測(cè)物體的運(yùn)動(dòng)。

紅色圓圈 → 運(yùn)動(dòng)預(yù)測(cè)

卡爾曼濾波器和FAST算法

卡爾曼濾波器使用過(guò)去的數(shù)據(jù)來(lái)預(yù)測(cè)物體的運(yùn)動(dòng)。使用卡爾曼濾波器時(shí),必須跟蹤一個(gè)物體,因?yàn)榭柭鼮V波器需要位置數(shù)據(jù),基于這些位置數(shù)據(jù),它預(yù)測(cè)物體的位置。

使用FAST算法,我將跟蹤物體,提取中心坐標(biāo),并使用這些數(shù)據(jù)與卡爾曼濾波器一起預(yù)測(cè)物體的位置。

NOTE: 關(guān)于FAST算法的文章,后續(xù)我們有機(jī)會(huì)將進(jìn)行詳細(xì)解讀。

代碼/跟蹤和預(yù)測(cè)物體的運(yùn)動(dòng) → FAST + 卡爾曼濾波器

主要有5個(gè)步驟,我將逐一解釋它們。

# Import Necessary Libraries

import cv2
import numpy as np 
import matplotlib.pyplot as plt
import time

1.使用FAST算法提取跟蹤特征:用鼠標(biāo)左鍵在目標(biāo)物體周?chē)?huà)一個(gè)矩形框,將從這個(gè)矩形框中提取特征。

# Path to video  
video_path = r"videos/helicopter3.mp4"
video = cv2.VideoCapture(video_path)

# read only the first frame for drawing a rectangle for the desired object
ret,frame = video.read()

# I am giving  big random numbers for x_min and y_min because if you initialize them as zeros whatever coordinate you go minimum will be zero 
x_min,y_min,x_max,y_max=36000,36000,0,0


def coordinat_chooser(event,x,y,flags,param):
    global go , x_min , y_min, x_max , y_max

    # when you click the right button, it will provide coordinates for variables
    if event==cv2.EVENT_LBUTTONDOWN:
        
        # if current coordinate of x lower than the x_min it will be new x_min , same rules apply for y_min 
        x_min=min(x,x_min) 
        y_min=min(y,y_min)

         # if current coordinate of x higher than the x_max it will be new x_max , same rules apply for y_max
        x_max=max(x,x_max)
        y_max=max(y,y_max)

        # draw rectangle
        cv2.rectangle(frame,(x_min,y_min),(x_max,y_max),(0,255,0),1)


    """
        if you didn't like your rectangle (maybe if you made some misscliks),  reset the coordinates with the middle button of your mouse
        if you press the middle button of your mouse coordinates will reset and you can give a new 2-point pair for your rectangle
    """
    if event==cv2.EVENT_MBUTTONDOWN:
        print("reset coordinate  data")
        x_min,y_min,x_max,y_max=36000,36000,0,0

cv2.namedWindow('coordinate_screen')
# Set mouse handler for the specified window, in this case, "coordinate_screen" window
cv2.setMouseCallback('coordinate_screen',coordinat_chooser)


while True:
    cv2.imshow("coordinate_screen",frame) # show only first frame 
    
    k = cv2.waitKey(5) & 0xFF # after drawing rectangle press ESC   
    if k == 27:
        cv2.destroyAllWindows()
        break

繪制矩形框以定位目標(biāo)

2. 顯示提取的特征:使用FAST算法從矩形框中提取特征。

# take region of interest ( take inside of rectangle )
roi_image=frame[y_min+2:y_max-2,x_min+2:x_max-2]
roi_rgb=cv2.cvtColor(roi_image,cv2.COLOR_BGR2RGB)

# convert roi to grayscale, SIFT Algorithm works with grayscale images
roi_gray=cv2.cvtColor(roi_image,cv2.COLOR_BGR2GRAY) 

# Initialize the FAST detector and BRIEF descriptor extractor
fast = cv2.FastFeatureDetector_create(threshold=1)
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()


# detect keypoints
keypoints_1 = fast.detect(roi_gray, None)
# descriptors
keypoints_1, descriptors_1 = brief.compute(roi_gray, keypoints_1)

# draw keypoints for visualizing
keypoints_image = cv2.drawKeypoints(roi_rgb, keypoints_1, outImage=None, color=(23, 255, 10))
# display keypoints
plt.imshow(keypoints_image,cmap="gray")

提取的特征

3.創(chuàng)建一個(gè)提取目標(biāo)物體中心位置的函數(shù)

# matcher object
bf = cv2.BFMatcher()

def detect_target_fast(frame):
    # convert frame to gray scale 
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Detect keypoints using FAST
    keypoints_2 = fast.detect(frame_gray, None)

    # Compute descriptors using BRIEF
    keypoints_2, descriptors_2 = brief.compute(frame_gray, keypoints_2)

    """
    Compare the keypoints/descriptors extracted from the 
    first frame (from target object) with those extracted from the current frame.
    """
    if descriptors_2 is not None:
        matches = bf.match(descriptors_1, descriptors_2)
        
        if matches:
            # Initialize sums for x and y coordinates
            sum_x = 0
            sum_y = 0
            match_count = 0
            
            for match in matches:
                # .trainIdx gives keypoint index from current frame 
                train_idx = match.trainIdx
                
                # current frame keypoints coordinates
                pt2 = keypoints_2[train_idx].pt
                
                # Sum the x and y coordinates
                sum_x += pt2[0]
                sum_y += pt2[1]
                match_count += 1
            
            # Calculate average of the x and y coordinates
            avg_x = sum_x / match_count
            avg_y = sum_y / match_count
            
    return int(avg_x),int(avg_y)

4.初始化卡爾曼濾波器

# Initialize Kalman filter parameters
kalman = cv2.KalmanFilter(4, 2)   
 
kalman.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)
kalman.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)
kalman.processNoiseCov = np.eye(4, dtype=np.float32) * 0.03  # Process noise
kalman.measurementNoiseCov = np.eye(2, dtype=np.float32) * 0.5  # Measurement noise

5.讀取視頻并使用卡爾曼濾波器和FAST算法

# Startcapturing the video from file
cap = cv2.VideoCapture(video_path)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # Predict the new position of the ball
    predicted = kalman.predict()
    predicted_x, predicted_y = int(predicted[0]), int(predicted[1])
    predicted_dx, predicted_dy = predicted[2], predicted[3]  # Predicted velocity

    print(predicted_x, predicted_y )
    print(f"Predicted velocity: (dx: {predicted_dx}, dy: {predicted_dy})")

    
    # Detect the ball in the current frame
    ball_position = detect_target_fast(frame)
    
    if ball_position:
        measured_x, measured_y = ball_position
        # Correct the Kalman Filter with the actual measurement
        kalman.correct(np.array([[np.float32(measured_x)], [np.float32(measured_y)]]))
        # Draw the detected ball
        cv2.circle(frame, (measured_x, measured_y), 6, (0, 255, 0), 2) # green --> correct position
    
    # Draw the predicted position (Kalman Filter result)
    cv2.circle(frame, (predicted_x, predicted_y), 8, (0, 0, 255), 2) # red --> predicted position

    # Show the frame
    cv2.imshow("Kalman Ball Tracking", frame)
    
    # Break on 'q' key press
    if cv2.waitKey(30) & 0xFF == ord('q'):  # 30 ms delay for smooth playback
        break

cap.release()
cv2.destroyAllWindows()

終端輸出

跟蹤和預(yù)測(cè)飛機(jī)

責(zé)任編輯:趙寧寧 來(lái)源: 小白玩轉(zhuǎn)Python
相關(guān)推薦

2024-12-19 08:00:00

FAST算法OpenCV目標(biāo)跟蹤

2024-11-20 16:51:00

目標(biāo)檢測(cè)模型

2019-06-06 15:00:10

2022-05-27 10:06:17

DuckDuckGo用戶隱私微軟

2020-08-29 18:38:11

物聯(lián)網(wǎng) LPWAN資產(chǎn)跟蹤器

2022-06-10 10:24:02

JavaScriptCOVID-19前端

2011-01-18 13:50:20

路由跟蹤tcptracerou

2021-03-02 09:42:25

跟蹤器密碼管理器密碼

2018-03-13 11:38:14

2015-01-09 09:41:16

HTTPSHTTPS安全COOKIE

2022-01-05 09:00:00

加密貨幣數(shù)據(jù)技術(shù)

2023-03-02 08:32:27

2019-05-14 09:53:31

代碼開(kāi)發(fā)工具

2011-09-15 15:38:48

Android應(yīng)用Endomondo運(yùn)動(dòng)

2025-02-17 07:00:00

ORB對(duì)象跟蹤器計(jì)算機(jī)視覺(jué)

2025-01-23 08:47:50

2023-06-06 06:26:26

2010-03-18 11:26:46

無(wú)線傳感器網(wǎng)絡(luò)多目標(biāo)跟

2024-10-31 11:03:06

C#橢圓運(yùn)動(dòng)緩沖

2024-07-30 14:45:08

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)