卡尔曼滤波实例——预测橘子的轨迹
目录
流程
step1:获取橘子的检测框 step2:求取橘子的质心 step3:将质心送入卡尔曼滤波器,获取到预测的下一次橘子的质心位置
一、采用轮廓的方式检测橘子位置
步骤: 采用OpenCV滚动条来确定阈值 设置高低阈值,利用inRange函数,将图像转为二值图,为方便之后的轮廓提取 使用findContours函数,提取二值图中所有的轮廓,并采用cv2.RETR_TREE,建立轮廓等级树 等级树初始是升序,我们要获取最大的那个轮廓,那么就进行sort降序排序 最后,第一个轮廓的最小外边框的参数就可以用boundingRect获取到了
(一)滚动条获取阈值
代码
import cv2 import numpy as np def nothing(x): pass cv2.namedWindow(image) cv2.createTrackbar(a,image,0,255,nothing) cv2.createTrackbar(b,image,0,255,nothing) cv2.createTrackbar(c,image,0,255,nothing) cv2.createTrackbar(d,image,0,255,nothing) cv2.createTrackbar(e,image,0,255,nothing) cv2.createTrackbar(f,image,0,255,nothing) frame = cv2.imread(orange.jpg) frame = cv2.resize(frame,(700,400)) while True: a = cv2.getTrackbarPos(a, image) b = cv2.getTrackbarPos(b, image) c = cv2.getTrackbarPos(c, image) d = cv2.getTrackbarPos(d, image) e = cv2.getTrackbarPos(e, image) f = cv2.getTrackbarPos(f, image) hsv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) low_orange = np.array([a, b, c]) high_orange = np.array([d, e, f]) mask = cv2.inRange(hsv_img, low_orange, high_orange) cv2.imshow(image,mask) k = cv2.waitKey(1)&0xff if k==27: break
(二)获取到图像中的包围橘子对应的白色图形的最小矩形框的信息
检测橘子轮廓最小外边框代码
import cv2 import numpy as np class OrangeDetector: def __init__(self): self.low_orange = np.array([10, 152, 89]) self.high_orange = np.array([180, 255, 255]) def detect(self, frame): hsv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv_img, self.low_orange, self.high_orange) contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=lambda x: cv2.contourArea(x), reverse=True) box = (0, 0, 0, 0) for cnt in contours: (x, y, w, h) = cv2.boundingRect(cnt) box = (x, y, x + w, y + h) break return box
二、获取橘子检测框的质心
od = OrangeDetector() orange_bbox = od.detect(frame) x, y, x2, y2 = orange_bbox cx = int((x + x2) / 2) cy = int((y + y2) / 2)
三、将质心送入卡尔曼滤波器,获取下一次的质心位置
predicted = kf.predict(cx, cy)
四、绘图质心中心的圆圈,让效果直观显示出来
卡尔曼滤波预测代码
import cv2 from orange_detector import OrangeDetector from kalmanfilter import KalmanFilter cap = cv2.VideoCapture("orange.mp4") od = OrangeDetector() kf = KalmanFilter() while True: ret, frame = cap.read() if ret is False: break orange_bbox = od.detect(frame) x, y, x2, y2 = orange_bbox cx = int((x + x2) / 2) cy = int((y + y2) / 2) predicted = kf.predict(cx, cy) cv2.circle(frame, (cx, cy), 20, (0, 0, 255), 4) cv2.circle(frame, (predicted[0], predicted[1]), 20, (255, 0, 0), 4) cv2.imshow("Frame", frame) key = cv2.waitKey(10) if key == 27: break