600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 树莓派小车————远程控制

树莓派小车————远程控制

时间:2022-12-21 07:15:49

相关推荐

树莓派小车————远程控制

这里所说的远程控制,是指一台PC通过一个界面可以达到控制并监视小车的目的。当然你也可以设计红外遥控,蓝牙等方式。

在设计界面时我选择了python自带的GUI工具————Tkinter。

选择Tkinter是因为它简单,写完直接运行就行。我们只需要通过VNC或者Windows远程桌面连接到树莓派,运行代码,就可以在PC上控制小车。

你自己也可以选择HTML来完成。做一个web页面。相关的自己可以去搜索。控制界面带一个视频传输的接口,在这次我选择了用OpenCV调用树莓派摄像头来实现实时的视频传输。代码如下:

#coding=utf-8import RPi.GPIO as GPIOimport timefrom Tkinter import *from PIL import Image,ImageTkimport tkFileDialog as filedialogimport cv2import threading#控制界面函数def ConInterface():#播放本地视频的函数def playLocalVideo():moviePath=filedialog.askopenfilename() #文件对话框,用来打开文件夹,选择文件print(moviePath)playBtn.place_forget() #隐藏播放按钮movie=cv2.VideoCapture(moviePath)waitTime= 1000/movie.get(5) #获取每帧需要的时间print(waitTime)movieTime = (movie.get(7) / movie.get(5))/60 #用视频文件的总帧数除以视频文件的帧速率得到视频的总时长,并换算成分钟print(movieTime)playSc.config(to=movieTime)while movie.isOpened():ret,readyFrame=movie.read() #read()返回两个值,ret 表示帧是否为空,readyFrame表示当前帧if ret==True:movieFrame=cv2.cvtColor(readyFrame,cv2.COLOR_BGR2RGBA) #校正颜色newImage=Image.fromarray(movieFrame).resize((675,360)) #调整大小newCover=ImageTk.PhotoImage(image=newImage)video.configure(image=newCover) #将图像加入到video标签中video.image=newCovervideo.update()cv2.waitKey(int(waitTime)) #播放完每帧等待的时间else:break#使用opencv调用树莓派摄像头def playVideo():playBtn.place_forget() #点击播放按钮之后开始播放视频,隐藏按钮movie=cv2.VideoCapture(0) #打开摄像头movie_fps=movie.get(5) #得到画面的帧速率print(movie_fps)waitTime=int(1000/movie_fps)print(waitTime)while movie.isOpened():#读取帧,返回布尔值和当前帧,ret 表示帧是否为空,readyFrame表示当前帧ret,readyFrame=movie.read()if ret==True:#校正图像颜色movieFrame=cv2.cvtColor(readyFrame,cv2.COLOR_BGR2RGBA)#设置图像大小newImage=Image.fromarray(movieFrame).resize((675,360))#将照片设置成和tkinter兼容的图像newCover=ImageTk.PhotoImage(image=newImage)#将图像放入Label中video.configure(image=newCover)video.image=newCovervideo.update()cv2.waitKey(20)else:breakmovie.release() #释放资源#设置线程执行播放视频程序def Thread_playVideo():thread_playVideo=threading.Thread(target=playVideo)thread_playVideo.start()root=Tk() #初始化tkroot.title("控制界面")#设置标题root.geometry("1080x720") #设置窗口大小root['bg']="#333333" #设置窗口背景颜色#root.iconbitmap('/home/pi/ZRcode/go.ico')root.resizable(width=False,height=False) #设置窗口长和宽是否可以变化#分别设置三个Frame 模块用于存放Label,Buttonvideof=Frame(root,height=360,width=675,cursor="cross")videof.place(x=199,y=0)f1=Frame(root,height=270,width=540,cursor="circle",bg="#333333")f1.place(x=269,y=359)f2=Frame(root,height=180,width=540,cursor="plus",bg="#333333")f2.place(x=269,y=629)#视频窗口movieImage=Image.open('/home/pi/ZRcode/raspberry.jpg').resize((675,360))cover=ImageTk.PhotoImage(image=movieImage)video=Label(videof,width=675,height=360,bd=0,bg="pink",image=cover)video.place(x=0,y=0)#播放按钮的布局iconImag=Image.open('/home/pi/ZRcode/play.ico').resize((32,32))icoBtn=ImageTk.PhotoImage(image=iconImag)playBtn=Button(videof,image=icoBtn,cursor="hand2",command=Thread_playVideo,relief="groove")playBtn.place(x=319,y=159)#playSc=Scale(videof,from_=0,to=90,length=675,orient=HORIZONTAL,resolution=0.2,showvalue=0,bd=0,cursor="hand2",troughcolor="white")#playSc.place(x=0,y=310)#控制按钮up=Button(f1,text="前进",command=lambda:turn_up(20,1),activeforeground="green",activebackground="yellow",height=1,width=4)up.place(x=267,y=39)left=Button(f1,text="左转",command=lambda:turn_left(20,1),activeforeground="green",activebackground="yellow",height=1,width=4)left.place(x=132,y=134)right=Button(f1,text="右转",command=lambda:turn_right(20,1),activeforeground="green",activebackground="yellow",height=1,width=4)right.place(x=412,y=134)back=Button(f1,text="后退",command=lambda:turn_back(20,1),activeforeground="green",activebackground="yellow",height=1,width=4)back.place(x=267,y=230)stop=Button(f1,text="停止",command=car_stop,activeforeground="green",activebackground="yellow",height=1,width=4)stop.place(x=267,y=134)xunji=Button(f2,text="循迹",command=Thread_track,activeforeground="green",activebackground="yellow",height=1,width=4)xunji.place(x=68,y=44)bz=Button(f2,text="避障",command=Thread_bizhang,activeforeground="green",activebackground="yellow",height=1,width=4)bz.place(x=461,y=44)over=Button(f2,text="OVER",command=Thread_gpio_clean,activeforeground="green",activebackground="yellow",height=1,width=6)over.place(x=263,y=44)root.mainloop()

为什么要导入threading?

写完界面运行之后我发现,当你点击一个按钮之后,其他的按钮在程序执行时是不可以点击的。这就存在问题,我们需要在循迹或者避障的同时要摄像头传输视频,所以我们需要将程序设计成多线程的,它们才能并行。当然并行主要是循迹和视频传输,避障和视频传输。循迹和避障当然是不用并行。循迹功能中可以加入避障,但这不属于并发。导入的PIL和CV2

这两个都是计算机视觉和图像处理的库。我也只是使用了部分功能,并没有深入了解。最终运行效果图

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。