Problems connecting Tello Drone camera in Python for a GUI

907 views Asked by At

I'm a very Python and Tkinter beginner. I've developed a program for Tello Drone in Python 3.6. The program works well but now I'm programming the user interface with Tkinter.

When i use the image from the laptop camera it works well, but when I try to connect drone's camera as I've aready do in all my projects, I've next error:

succes, img = me.get_frame_read().frame
TypeError: 'NoneType' object is not iterable

I know what's a NoneType, but I dont't understand why is getting this value. Looks like the camera have a delay or is not ready when the program starts.

This's a sample of the code:

from tkinter import *
import tkinter as tk
from PIL import ImageTk, Image
import cv2
#img = img3
# Capture from camera
from djitellopy import tello


'''
me = tello.Tello()
me.connect()
print(me.get_battery())
me.send_rc_control(0,0,0,0)
me.streamon()
#'''
w,h = 660, 360
#succes, img = me.get_frame_read().frame
cap = cv2.VideoCapture(0)

if __name__ == '__main__':


    def return_pressed(event):
        print('Return key pressed.')
    root = Tk()
    root.title("Inventory control")
    root.iconbitmap(r'Ico/drone3.ico')

    # Create a frame
    app = Frame(root, bg="white")
    app.grid(row=1, column=0)

    # Create a label in the frame
    lmain = Label(app)
    lmain.grid()


    droneCamera_label = Label(root, text="Drone camera", font=("Arial 20 bold"))
    textBox_label = Label(root, text="Inventory results", font=("Arial 20 bold"))
    textBox_label.grid(row=0, column=2)
    droneCamera_label.grid(row=0, column=0)
    text_box = Text(root, height=25, width=40)
    text_box.grid(row=1, column=2)
    text_box.config(font=("consolas", 12), undo=True, wrap='word')
    text_box.config(borderwidth=3, relief="sunken")
    text_box.insert('end', "Inventory results:", )
    text_box.config(state='disabled')
    scrollb = tk.Scrollbar(command=text_box.yview)
    scrollb.grid(row=1, column=3, sticky='nsew')
    text_box['yscrollcommand'] = scrollb.set


    def manualControl(event):
        global message
        text_box.config(state='normal')
        print(1)
        text_box.insert(tk.INSERT, "l")
        text_box.config(state='disabled')


    # function for video streaming
    def video_stream():
        _, frame = cap.read()
        # succes, frame = me.get_frame_read().frame
        img = cv2.resize(frame, (w, h))
        cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
        img2 = Image.fromarray(cv2image)
        imgtk = ImageTk.PhotoImage(image=img2)
        lmain.imgtk = imgtk
        lmain.configure(image=imgtk)
        lmain.after(1, video_stream)


    root.bind('<Button-1>', manualControl)
    video_stream()

    root.mainloop()

And this's how GUI looks like with the laptop webcam: GUI

1

There are 1 answers

0
Tdiggity On

I belive .frame is a function that turns the tello 'backgroundframeread' type into a cv2/numpy array.

Your tello might be failing to grab the first few groups of frames, if it has no frame then the objects value is NONE. If you attempt to .frame an object you will get TypeError: 'NoneType' object is not iterable.

I think you can solve this by putting a delay between your framecapture and your .frame that is as long as your tello, or camera takes to grab a frame. A time.sleep() is usually a safe bet.

try this:

img = me.get_frame_read()
time.sleep(5)
img = img.frame