将无人车安装好之后,对于无人车最关键的组件,属于无人驾驶领域的眼睛:摄像头或相机,看下有哪些相关操作
首先初始化摄像头,宽高为224
from jetbotmini import Camera
camera = Camera.instance(width=224, height=224)
不出意外的情况,可能出现下面的运行时错误:
RuntimeError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/jetbotmini-0.4.0-py3.6.egg/jetbotmini/camera.py in __init__(self, *args, **kwargs)
29 if not re:
---> 30 raise RuntimeError('Could not read image from camera.')
31
RuntimeError: Could not read image from camera.
During handling of the above exception, another exception occurred:
RuntimeError Traceback (most recent call last)in
1 from jetbotmini import Camera
----> 2 camera = Camera.instance(width=224, height=224)
/usr/local/lib/python3.6/dist-packages/traitlets/config/configurable.py in instance(cls, *args, **kwargs)
410 # Create and save the instance
411 if cls._instance is None:
--> 412 inst = cls(*args, **kwargs)
413 # Now make sure that the instance will also be returned by
414 # parent classes' _instance attribute.
/usr/local/lib/python3.6/dist-packages/jetbotmini-0.4.0-py3.6.egg/jetbotmini/camera.py in __init__(self, *args, **kwargs)
35 self.stop()
36 raise RuntimeError(
---> 37 'Could not initialize camera. Please see error trace.')
38
39 atexit.register(self.stop)
RuntimeError: Could not initialize camera. Please see error trace.
我们先来看下这个OpenCV库的版本。OpenCV是一个开源的计算机视觉库,使用很广泛,这里就不多做解释了
import cv2
print(cv2.__version__)#4.1.1
所以这里不是版本低的问题。
由于在安装好了之后,我使用iPad可以正常控制无人车的操作,摄像头也是正常打开拍摄状态,所以摄像头的安装是没有问题
那我们来到终端输入命令:ls /dev 列表里面也有video0设备,说明终端也是正确连接着摄像头的
如何连接到无人车系统?我们使用前面介绍的VNC-Viewer来远程操作:
远程连接VNC-Viewer与安全传输WinSCP软件
那就试着重启Kernel,点击JupyterLab菜单的"Kernel",点击"Shut Down All Kernels..."
点击"Restart Kernel and Clear All Outputs..."重启之后,重新运行代码即可,如果还是报错,那就将无人车重启下。
还有一种情况就是摄像头在使用中或者直接关闭.ipynb页面,重新执行另一个.ipynb来初始化摄像头也同样报上面的错误,所以说这个只需要重启即可
#打印看下
print(camera)
说明摄像头已经正常初始化了。
# 通过widgets小组件来显示图片
import ipywidgets.widgets as widgets
image = widgets.Image(format='jpeg', width=224, height=224)
display(image)
实时更新相机画面至组件显示
我们通过traitlets来绑定两个数据对象进行数据的实时刷新,由于我们组件显示的图像格式是JPEG格式,而我们从摄像头相机获取的数据是bgr8,所以我们需要利用jetbotmini里的bgr8_to_jpeg方法才能正确将我们从相机捕获到的数据进行实时显示。
from jetbotmini import bgr8_to_jpeg
import traitlets
camera_link = traitlets.dlink((camera, 'value'), (image, 'value'), transform=bgr8_to_jpeg)
不出意外的话,摄像头就会正常捕获画面并实时显示在上面的wiggets的Image部件里面了。
我们来看下widgets组件模块,里面有很多的控件可以使用
import ipywidgets.widgets as widgets
print(dir(widgets))
#['Accordion', 'AppLayout', 'Audio', 'BoundedFloatText', 'BoundedIntText', 'Box', 'Button', 'ButtonStyle', 'CallbackDispatcher', 'Checkbox', 'Color', 'ColorPicker', 'Combobox', 'Controller', 'CoreWidget', 'DOMWidget', 'DatePicker', 'Datetime', 'Dropdown', 'FileUpload', 'FloatLogSlider', 'FloatProgress', 'FloatRangeSlider', 'FloatSlider', 'FloatText', 'GridBox', 'GridspecLayout', 'HBox', 'HTML', 'HTMLMath', 'Image', 'IntProgress', 'IntRangeSlider', 'IntSlider', 'IntText', 'Label', 'Layout', 'NumberFormat', 'Output', 'Password', 'Play', 'RadioButtons', 'Select', 'SelectMultiple', 'SelectionRangeSlider', 'SelectionSlider', 'SliderStyle', 'Style', 'Tab', 'Text', 'Textarea', 'ToggleButton', 'ToggleButtons', 'ToggleButtonsStyle', 'TwoByTwoLayout', 'VBox', 'Valid', 'ValueWidget', 'Video', 'Widget', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'docutils', 'domwidget', 'fixed', 'interact', 'interact_manual', 'interaction', 'interactive', 'interactive_output', 'jsdlink', 'jslink', 'register', 'trait_types', 'util', 'valuewidget', 'widget', 'widget_bool', 'widget_box', 'widget_button', 'widget_color', 'widget_controller', 'widget_core', 'widget_date', 'widget_description', 'widget_float', 'widget_int', 'widget_layout', 'widget_link', 'widget_media', 'widget_output', 'widget_selection', 'widget_selectioncontainer', 'widget_serialization', 'widget_string', 'widget_style', 'widget_templates', 'widget_upload']
这种交互式的小部件都是基于HTML,因为JupyterLab本身就是基于浏览器而开发的,所以跟Web前端是很相似的,我们来看几个小例子,显示一些常见的组件看下:
import ipywidgets as widgets
from IPython.display import display
btn=widgets.Button(description="确认")
display(btn)
left=widgets.FloatSlider(desciption="left",min=-10,max=10)
right=widgets.FloatSlider(desciption="left",min=-1,max=1)
container=widgets.HBox([widgets.Label(value="交互式小部件"), left,right])
display(container)
还可以进行交互式的操作,点击按钮看下效果:
def btn_click(sender):
print('点击了按钮:%s' % sender.description)
btn.on_click(btn_click)
display(btn)
#点击了按钮:确认
下拉框的选择:
drpbx = widgets.Dropdown(options=[("湖南省", 1), ("广东省", 2), ("江西省", 3)], index=0, value=1, label="广东省")
def chosen(_):
print("选择的索引:{}, 值:{}, 标签:{}".format(drpbx.index, drpbx.value, drpbx.label))
drpbx.observe(chosen, names="value")
display(drpbx)
这里默认指定显示广东省
比如选择湖南省
#选择的索引:0, 值:1, 标签:湖南省
选择江西省
#选择的索引:2, 值:3, 标签:江西省
另外既然是基于WEB的,很明显HTML的样式也是可以直接拿过来用,比如设置按钮颜色:
btn.style.button_color = 'lightblue'
还有一些预定义的常见按钮
from ipywidgets import Button, HBox
display(HBox([
Button(description='确认', button_style='primary'),
Button(description='成功', button_style='success'),
Button(description='信息', button_style='info'),
Button(description='警告', button_style='warning'),
Button(description='错误', button_style='danger')
]))
这里是对一些常见的小部件做了介绍,更多信息可以查阅相关资料,有什么疑问与错误,欢迎指正交流,共同学习进步!