携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
最近我被 SLAM 这门技术深深所吸引,从开始好奇到今天的沉迷,已经到了不能自拔的地步。通过一段时间的学习,我放弃了一口吃成胖子的想法,想踏踏实实一步一个脚印地学习 SLAM。SLAM 之所以具有这样魅力,可能正是其涉及到知识的广度和难度吧。可能还有就是 SLAM 现在实实在在许多方面的应用,例如扫地机器人和无人驾驶。
有一天能够靠 SLAM 维持生计固然好,即使不能,作为一门爱好也是不错选择。
以后可能会分享许多枯燥数学方面的知识,为了让自己维持学习的动力,
我一次应该是我记得的第 3 次来尝试自己跟着 george hotz 的分享来做 python 版本的 SLAM,希望会有所突破。清楚记得第一次放弃是因为自己多多视图几何方面基础知识太匮乏,仅是跟着 coding,总是以一头雾水,不知其所以然,为什么这么做。第二次是放弃就是因为对 c++ 方面是完全门外汉,特别是遇到编译错误,根本是无从下手。这一次有备而来,希望能跟着 george hotz 分享走远一点,希望大家多多支持。
环境
先简单介绍一个环境,这个环境并不是最终环境,随时在改变
- sys ubuntu 18.4
- python 3.6.9
IDE
- vscode 1.68.1
depencies
- opencv 3.4.2.16
- opencv-contrib-python 3.4.2.16
- pysdl2-0.9.11
- pysdl2-dll-2.0.20
显示驾驶视频
这里一段采集驾驶视频来做研究对象,这里采用 opencv 来读取视频
import cv2
if __name__ == "__main__":
cap = cv2.VideoCapture("./videos/test_countryroad.mp4")
while cap.isOpened():
ret, frame = cap.read()
if ret:
print(frame.shape)
(1080, 1920, 3)
def process_frame(img):
pass
if __name__ == "__main__":
cap = cv2.VideoCapture("./videos/test_countryroad.mp4")
while cap.isOpened():
ret, frame = cap.read()
if ret == True:
print(frame.shape)
process_frame(frame)
else:
break
W = 1920//2
H = 1080//2
def process_frame(img):
img = cv2.resize(img,(W,H))
sdl2 display
sdl2 是用来开发游戏框架,原为支持 c++ 语言用于开发游戏的库,这里 sdl 来将视频显示在屏幕上
ImportError: could not find any library for SDL2 (PYSDL2_DLL_PATH: unset)
import sdl2
import sdl2.ext
class Display:
def __init__(self,W,H,window_name) -> None:
self.W = W
self.H = H
sdl2.ext.init()
self.window = sdl2.ext.Window(window_name,size=(W,H),position=(100,100))
self.window.show()
def show(self,img):
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
exit(0)
self.surf = sdl2.ext.pixels3d(self.window.get_surface())
self.surf[:,:,0:3] = img.swapaxes(0,1)
self.window.refresh()
想要把视频每一帧图像绘制到屏幕上,首先会初始化 window 就是在屏幕上创建一个窗口,然后获取窗口 surface 可以理解为画布,然后将 opencv 读取到图像绘制到获取到画布上,这样一来就将视频帧图像绘制到屏幕上。
import cv2
from display import Display
W = 1920//2
H = 1080//2
display = Display(W,H,'slam')
def process_frame(frame):
img = cv2.resize(frame,(W,H))
display.show(img)
if __name__ == "__main__":
cap = cv2.VideoCapture("./videos/test_countryroad.mp4")
while cap.isOpened():
ret, frame = cap.read()
if ret == True:
print(frame.shape)
process_frame(frame)
else:
break
手上并没点云这样密集点的数据,有的自由图像。那么自然的想法就是利用图像上特征点,来找两帧之间同一个特征点来进行构建 3 维场景。
import cv2
from display import Display
W = 1920//2
H = 1080//2
display = Display(W,H,'slam')
orb = cv2.ORB_create()
def process_frame(frame):
img = cv2.resize(frame,(W,H))
#features extraction ,base on feature
kp, des = orb.detectAndCompute(img,None)
for p in kp:
u,v = map(lambda x:int(round(x)),p.pt)
print(u,v)
display.show(img)