환경 세팅
TelloPy
tellopy는 pip 설치가 돼 있다면 터미널에서 아래 명령을 쳐서 쉽게 받을 수 있다.
pip3 install tellopy
설치 뒤에는 import tellopy를 통해 패키지를 사용할 수 있다.
VSC에서 다음과 같이 tello 프로젝트를 진행할 폴더를 생성하자.
필자는 TelloProjects라고 이름을 지어서 폴더를 생성해주었다.
여기서 위 과정을 따라 tellopy 라이브러리를 설치하고 import tellopy를 했음에도 불구하고 라이브러리를 사용할 수 없는 경우에는 tellopy를 직접 빌드하여 설치하는 해결 방법이 있다.
git clone <https://github.com/hanyazou/TelloPy.git>
cd TelloPy
python setup.py bdist_wheel
pip install dist/tellopy-*.dev*.whl
위 명령어를 통해 깃허브에서 클론을 받으면 아래와 같은 파일들이 디렉토리(TelloProjects) 내부에 생성된다.
examples 디렉토리에 우리가 tello 조종을 위해 직접적으로 사용할 예제 파일들이 저장되어 있다.
- joystick_and_video.py: 조이스틱 조종기와 비디오 예제
- keyboard_and_video.py: 키보드 활용 조종기와 비디오 예제
- record_log.py: log 데이터 저장 예제
- simple_takeoff.py: 간단한 이착륙 하는 예제
- video_effect.py: tello가 촬영하고 있는 비디오를 pc에서 스트리밍 하는 예제
여기서 simple_takeoff.py와 video_effect.py에 작성된 예제들이 앞으로 우리가 사용할 Python으로 Tello를 조작하는 방법론에 대한 시발점이다. 따라서 이번 메뉴얼에서는 이 두 파일을 집중적으로 공부해보자.
Python으로 Tello 조종하기
1) simple_takeoff.py
[간단한 이착륙 코드]
from time import sleep
import sys
sys.path.append("/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages")
import tellopy
def handler(event, sender, data, **args):
drone = sender
if event is drone.EVENT_FLIGHT_DATA:
print(data)
def test():
drone = tellopy.Tello()
try:
drone.subscribe(drone.EVENT_FLIGHT_DATA, handler)
drone.connect()
drone.wait_for_connection(60.0)
drone.takeoff()
sleep(5)
drone.down(50)
sleep(5)
drone.land()
sleep(5)
except Exception as ex:
print(ex)
finally:
drone.quit()
if __name__ == '__main__':
test()
- drone = tellopy.Tello()
- tellopy 내부에 정의 되어있는 Tello를 drone이라는 객체로 선언한다.
- drone.connect
- 선언한 drone 객체의 connect 메소드를 활용하여 tello에 connection을 요청한다.
- drone.takeoff
- takeoff 메소드를 통해 이륙 명령을 내린다.
- drone.land
- land 메소드를 통해 착륙 명령을 내린다.
- sleep
- 몇 초동안 기다리게 하는 함수이다.
2. video_effect.py
해당 코드를 사용하기 위해서는 ac, opencv, image 패키지를 다운 받아야 한다.
[패키지 다운로드 명령어]
pip install av
pip install opencv-python
pip install image
python -m tellopy.examples.video_effect
- av: python으로 오디오 및 비디오 파일 CRUD를 위한 라이브러리이다.
- open: 비디오 or 비디오 파일 열기
- av 라이브러리를 사용하기 위해서는 FFmpeg 설치 필수
- opencv: 이미지 및 비디오 처리, 컴퓨터 비전 작업, 기계 학습 등에 사용되는 오픈 소스 컴퓨터 비전 라이브러리이다. 실시간 컴퓨터 비전 애플리케이션 개발에 널리 활용된다.
[Tello-비디오 스트림 출력 코드]
import sys
import traceback
import tellopy
import av
import cv2 # for avoidance of pylint error
import numpy
import time
def main():
drone = tellopy.Tello()
try:
drone.connect()
drone.wait_for_connection(60.0)
retry = 3
container = None
while container is None and 0 < retry:
retry -= 1
try:
container = av.open(drone.get_video_stream())
except av.AVError as ave:
print(ave)
print('retry...')
# skip first 300 frames
frame_skip = 300
while True:
for frame in container.decode(video=0):
if 0 < frame_skip:
frame_skip = frame_skip - 1
continue
start_time = time.time()
image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
cv2.imshow('Original', image)
cv2.imshow('Canny', cv2.Canny(image, 100, 200))
cv2.waitKey(1)
if frame.time_base < 1.0/60:
time_base = 1.0/60
else:
time_base = frame.time_base
frame_skip = int((time.time() - start_time)/time_base)
except Exception as ex:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, exc_traceback)
print(ex)
finally:
drone.quit()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
- container = av.open(drone.get_video_stream()) : 비디오 스트림을 저장하기 위한 AVContainer 변수를 선언한다. av.open 메소드를 통해 해당 파일을 연다.
- #skip first 300 frames 코드를 살펴보자.frame_skip은 비디오 프레임을 건너뛸 횟수를 나타내는 변수이다. 이 변수를 300으로 초기화하여 처음 300 개의 프레임을 건너뛴다. 초기 스트림의 시작 부분에는 보통 초기화되는 노이즈 또는 불안정한 프레임이 포함될 수 있으므로 시작 300 부분을 건너뛰고, 정상적인 비디오 프레임부터 처리하기 위해 처리해주는 코드이다.
- # skip first 300 frames frame_skip = 300 while True: for frame in container.decode(video=0): if 0 < frame_skip: frame_skip = frame_skip - 1 continue
- 비디오 처리를 위한 무한 루프
- 위 코드는 while 루프 내에서 OpenCV를 사용하여 비디오 프레임을 처리하고 화면에 표시하는 방식으로 영상 프레임을 조작한다. 비디오는 정적 이미지의 연속된 파일이라고 생각하면 되기에 정적 이미지를 연속적으로 처리하기 위해 무한 루프를 사용한다.
- image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR): Tello에서 받아온 프레임을 이미지로 변환한 후, 이미지를 Numpy(파이썬 라이브러리) 배열로 변환한다. 이후 cv2.cvtColort 메소드를 사용하여 이미지의 컬러 채널 순서를 RGB → BGR로 변경하는 역할을 한다.
- numpy.array로 변환한 이미지는 기본적으로 RGB 컬러 순서를 가지고 있지만, OpenCV에서는 기본적으로 BGR 컬러 순서를 사용하기 때문에 cv2.COLOR_RGB2BGR로 컬러 채널 순서를 변경해준다.
- cv2.imshow(’Original’, image): 받아온 이미지를 화면에 띄우는 메소드이다. Original은 영상을 띄울 창의 이름이고 image는 띄울 이미지(ndarray)이다.
'ML > OpenCV' 카테고리의 다른 글
[자율주행] djitellopy & opencv Object Detection - (2) (1) | 2023.08.06 |
---|---|
[자율주행] djitellopy & opencv Object Detection - (1) (0) | 2023.08.06 |
[자율주행] OpenCV와 영상처리 | 필터링 | 영상 잡음 전처리 (0) | 2023.07.31 |