gobot.io/x/gobot/v2@v2.1.0/examples/tello_opencv.go (about) 1 //go:build example 2 // +build example 3 4 // 5 // Do not build by default. 6 7 /* 8 You must have ffmpeg and OpenCV installed in order to run this code. It will connect to the Tello 9 and then open a window using OpenCV showing the streaming video. 10 11 How to run 12 13 go run examples/tello_opencv.go 14 */ 15 16 package main 17 18 import ( 19 "fmt" 20 "io" 21 "os/exec" 22 "strconv" 23 "time" 24 25 "gobot.io/x/gobot/v2" 26 "gobot.io/x/gobot/v2/platforms/dji/tello" 27 "gocv.io/x/gocv" 28 ) 29 30 const ( 31 frameX = 960 32 frameY = 720 33 frameSize = frameX * frameY * 3 34 ) 35 36 func main() { 37 drone := tello.NewDriver("8890") 38 window := gocv.NewWindow("Tello") 39 40 ffmpeg := exec.Command("ffmpeg", "-hwaccel", "auto", "-hwaccel_device", "opencl", "-i", "pipe:0", 41 "-pix_fmt", "bgr24", "-s", strconv.Itoa(frameX)+"x"+strconv.Itoa(frameY), "-f", "rawvideo", "pipe:1") 42 ffmpegIn, _ := ffmpeg.StdinPipe() 43 ffmpegOut, _ := ffmpeg.StdoutPipe() 44 45 work := func() { 46 if err := ffmpeg.Start(); err != nil { 47 fmt.Println(err) 48 return 49 } 50 51 drone.On(tello.ConnectedEvent, func(data interface{}) { 52 fmt.Println("Connected") 53 drone.StartVideo() 54 drone.SetVideoEncoderRate(tello.VideoBitRateAuto) 55 drone.SetExposure(0) 56 57 gobot.Every(100*time.Millisecond, func() { 58 drone.StartVideo() 59 }) 60 }) 61 62 drone.On(tello.VideoFrameEvent, func(data interface{}) { 63 pkt := data.([]byte) 64 if _, err := ffmpegIn.Write(pkt); err != nil { 65 fmt.Println(err) 66 } 67 }) 68 } 69 70 robot := gobot.NewRobot("tello", 71 []gobot.Connection{}, 72 []gobot.Device{drone}, 73 work, 74 ) 75 76 // calling Start(false) lets the Start routine return immediately without an additional blocking goroutine 77 robot.Start(false) 78 79 // now handle video frames from ffmpeg stream in main thread, to be macOS/Windows friendly 80 for { 81 buf := make([]byte, frameSize) 82 if _, err := io.ReadFull(ffmpegOut, buf); err != nil { 83 fmt.Println(err) 84 continue 85 } 86 img, _ := gocv.NewMatFromBytes(frameY, frameX, gocv.MatTypeCV8UC3, buf) 87 if img.Empty() { 88 continue 89 } 90 91 window.IMShow(img) 92 if window.WaitKey(1) >= 0 { 93 break 94 } 95 } 96 }