大家好,又见面了,我是你们的朋友全栈君。
一直想玩无人机,之前租了一个大疆的发现禁飞。好在最近发现了Tello,买来过了一把瘾。顺便试了下集成条形码扫描功能。现在有很多仓储管理会用到无人机来扫码做库存盘点。
Python 3控制Tello无人机
DJI的官方GitHub仓库里已经放了示例代码dji-sdk/Tello-Python
。不过这份代码只能支持Python 2.7,而且也好久无人维护。要在Python 3上运行这份代码需要做些修改。
首先获取源码:
代码语言:javascript复制git clone https://github.com/dji-sdk/Tello-Python.git
在vscode中打开工程,通过全局查找替换以下部分:
代码语言:javascript复制# 2.7
import Tkinter
# 3.7
import tkinter
# 2.7
print ""
# 3.7
print()
# 2.7
packet_data = ""
# 3.7
packet_data = bytes()
另外,h264解码库需要重新编译成Python 3的版本。我的环境是Windows,首先下载编译vcpkg
:
git clone https://github.com/microsoft/vcpkg
cd vcpkg
bootstrap-vcpkg.bat
然后通过vcpkg安装ffmpeg
:
vcpkg.exe install ffmpeg:x64-windows
接下来编译h264解码库的Python模块:
代码语言:javascript复制git clone https://github.com/DaWelter/h264decoder.git
cd h264decoder
python setup.py build_ext --cmake-args="-DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake"
现在可以用Python 3正常运行Tello的示例代码了:
代码语言:javascript复制python3 main.py
集成Python条形码识别SDK
条形码识别会占用CPU,如果运行在Python的线程中,由于Python的GIL会导致视频流卡顿。用Dynamsoft Python条形码识别SDK可以避免这种情况。因为提供的视频流解码接口是运行在C/C 线程上的:
- start_video_mode()
- append_video_frame()
- stop_video_mode()
安装Python barcode SDK:
代码语言:javascript复制pip install dbr
在tello.py
文件中创建BarcodeReader
对象:
from dbr import *
self.reader = BarcodeReader()
self.reader.init_license('LICENSE-KEY') # 获取license: https://www.dynamsoft.com/customer/license/trialLicense
设置参数以及回调函数:
代码语言:javascript复制parameters = self.reader.init_frame_decoding_parameters()
self.frameWidth = 640 # max: 960
self.frameHeight = 480 # max: 720
self.results = None
parameters.image_pixel_format = EnumImagePixelFormat.IPF_RGB_888
parameters.max_queue_length = 2
parameters.max_result_queue_length = 2
parameters.width = self.frameWidth
parameters.height = self.frameHeight
parameters.stride = self.frameWidth * 3
parameters.auto_filter = 1
self.reader.start_video_mode(parameters, self.on_barcode_result)
已知Tello的摄像头是720P的。我准备把得到的图像缩小到640×480。
在回调函数中保存结果,用于UI绘制:
代码语言:javascript复制def on_barcode_result(self, data):
self.results = data
找到视频流接收函数_receive_video_thread()
。把获得的帧缩小并放到解码队列里:
for frame in self._h264_decode(packet_data):
self.frame = cv2.resize(frame, (self.frameWidth, self.frameHeight))
try:
ret = self.reader.append_video_frame(self.frame)
except:
pass
最后在析构函数中调用stop_video_mode()
:
def __del__(self):
self.reader.stop_video_mode()
测试
我在办公室里做了测试。从显示效果来看,不是很理想,在光线较差的环境中,图像没有对焦:
此外,悬停也会出现问题。Tello无人机在办公室里悬停会漂移。
源码
https://github.com/yushulx/tello-drone
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170561.html原文链接:https://javaforall.cn