KalmanFilter всегда предсказывает 0,0 в первый раз

Следующий код используется для сканирования изображения снизу вверх. Однако прогноз фильтра Калмана всегда показывает 0,0 в первый раз. Таким образом, он проведет линию снизу до 0,0. Как сделать путь (фильтр Калмана) более похожим на реальный путь?

Следующий код и изображение были обновлены.

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

img = cv2.imread('IMG_4614.jpg',1)
img = cv2.resize(img, (600, 800))
hsv_image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
low_yellow = np.array([18, 94, 140])
up_yellow = np.array([48, 255, 255])
hsv_mask = cv2.inRange(hsv_image, low_yellow, up_yellow)
hls_image = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)
low_yellow = np.array([0, 170, 24])
up_yellow = np.array([54, 255, 255])
hls_mask = cv2.inRange(hls_image, low_yellow, up_yellow)
mask = np.logical_or(hsv_mask,hls_mask)

offset = 100
height, width, _ = img.shape
previousPos = h
currentPos = h - offset
finalImg = img.copy()
is_first = True

initState = np.array([[np.float32(int(width/2))], [np.float32(h)]], np.float32)
last_measurement = current_measurement = initState
last_prediction = current_prediction = np.array((2, 1), np.float32)
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)


while currentPos >= 0:
    histogram = np.sum(mask[currentPos:previousPos,:], axis=0)
    areas = np.where(histogram > 40)
    if areas[0].size >= 2:
        bottomLeft = areas[0][0]
        topRight = areas[0][-1]

        x = int((topRight-bottomLeft) / 2 + bottomLeft)
        y = int((previousPos - currentPos) / 2 + currentPos)
        last_prediction = current_prediction
        last_measurement = current_measurement 
        current_measurement = np.array([[np.float32(x)], [np.float32(y)]], np.float32)
        lmx, lmy = last_measurement[0], last_measurement[1]
        cmx, cmy = current_measurement[0], current_measurement[1]

        cv2.rectangle(finalImg, (bottomLeft,previousPos), (topRight,currentPos), (0,255,0), 5)
        cv2.circle(finalImg,(x,y), 5, (0,0,255), -1)
        cv2.line(finalImg, (lmx, lmy), (cmx, cmy), (255, 0, 0),5) #actual path




        kalman.correct(current_measurement-initState)
        current_prediction = kalman.predict()

        lpx, lpy = last_prediction[0] + initState[0], last_prediction[1] + initState[1]
        cpx, cpy = current_prediction[0] + initState[0], current_prediction[1] + initState[1]
        cv2.line(finalImg, (lpx, lpy), (cpx, cpy), (255, 0, 255),5) # predict path  



        plt.figure(figsize=(10,10))  
        plt.imshow(cv2.cvtColor(finalImg, cv2.COLOR_BGR2RGB))
        plt.show()


    previousPos = currentPos
    currentPos = currentPos - offset

KalmanFilter всегда предсказывает 0,0 в первый разKalmanFilter всегда предсказывает 0,0 в первый раз

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
649
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

На это уже был дан ответ здесь: Фильтр Калмана всегда предсказывает происхождение

Реализация фильтра Калмана OpenCV не позволяет вам установить начальное состояние. Вы должны сохранить свое начальное состояние, а затем, когда вы вызываете kalman.correct, вы должны вычесть начальное состояние. И когда вы вызываете kalman.predict, вам нужно добавить свое начальное состояние.

Что-то вроде этого псевдокода:

initialState = (y,x)
....

kalman.correct(current_measurement - initialState)
...
prediction = kalman.predict()
prediction[0] = prediction[0] + initState[0]
prediction[1] = prediction[1] + initState[1]

Если вы разместите где-нибудь свой полный код (и такие ресурсы, как изображения), я могу попробовать исправить ваш код.

Fred Guth 13.07.2018 17:26

Я не понимаю, что вы имеете в виду getMeasurement (...)

SinLok 13.07.2018 17:55

Я изменил псевдокод. Посмотрите, понимаете ли вы это.

Fred Guth 13.07.2018 17:58

Я действительно не знаю, как это реализовать. Приведенный выше код был обновлен. Не могли бы вы помочь мне это исправить? Спасибо

SinLok 14.07.2018 04:23

ок, исправил сам. Однако можно ли сделать прогноз без измерений? То есть программа может найти путь автоматически после первого измерения.

SinLok 14.07.2018 06:31

Нет. Идея фильтра калмана состоит в том, что во время 1 он предсказывает состояние, во время 2 вы измеряете реальность, а затем вызываете kalman.correct. После этого в правильном () Калман увидит, насколько ошибочными были его предположения, и соответственно изменит вес фильтра. Так что абсолютно необходимо подправить фильтр, насколько это возможно.

Fred Guth 15.07.2018 05:48

Мне удалось изменить начальное состояние, изменив statePost и statePre. В инициализации:

self.KF = cv2.KalmanFilter(nmbStateVars, nmbMeasts, nmbControlInputs)

A = self.KF.statePost
A[0:4] = self.measurement.reshape((4, 1))
# A[4:8] = 0.0
self.KF.statePost = A
self.KF.statePre = A

Затем обновите как обычно

self.updatedMeasts = self.KF.correct(self.measurement)

Другие вопросы по теме