PYqt5编制电脑客户端控制树莓派小车并通过摄像头获取视频显示并保存到电脑本地

PYqt5编制电脑客户端控制树莓派小车并通过摄像头获取视频显示并保存到电脑本地

计算机端

编制控制界面

此为成品图

在这里插入图片描述

UI部分



#  UI部分
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'car_coutoralmain.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWebEngineWidgets import QWebEngineView

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(835, 555)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(320, 390, 169, 31))
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(320, 350, 169, 28))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(320, 430, 169, 28))
        self.pushButton_2.setObjectName("pushButton_2")
        self.verticalScrollBar = QtWidgets.QScrollBar(self.centralwidget)
        self.verticalScrollBar.setGeometry(QtCore.QRect(70, 329, 81, 161))
        self.verticalScrollBar.setMaximum(2)
        self.verticalScrollBar.setSingleStep(1)
        self.verticalScrollBar.setPageStep(1)
        self.verticalScrollBar.setProperty("value", 1)
        self.verticalScrollBar.setOrientation(QtCore.Qt.Vertical)
        self.verticalScrollBar.setObjectName("verticalScrollBar")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(160, 340, 81, 41))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(20)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(160, 380, 71, 61))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(20)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(160, 440, 91, 41))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(20)
        self.label_4.setFont(font)
        self.label_4.setObjectName("label_4")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(570, 40, 221, 31))
        font = QtGui.QFont()
        font.setFamily("Adobe 黑体 Std R")
        font.setPointSize(11)
        self.lineEdit.setFont(font)
        self.lineEdit.setObjectName("lineEdit")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(530, 40, 31, 31))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(14)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(580, 80, 161, 41))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(14)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setObjectName("pushButton_3")
        self.label_6 = QtWidgets.QLabel(self.centralwidget)
        self.label_6.setGeometry(QtCore.QRect(630, 120, 71, 41))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(14)
        self.label_6.setFont(font)
        self.label_6.setObjectName("label_6")
        self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
        self.spinBox.setGeometry(QtCore.QRect(690, 380, 71, 51))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(14)
        self.spinBox.setFont(font)
        self.spinBox.setMinimum(1)
        self.spinBox.setMaximum(144)
        self.spinBox.setProperty("value", 20)
        self.spinBox.setObjectName("spinBox")
        self.label_7 = QtWidgets.QLabel(self.centralwidget)
        self.label_7.setGeometry(QtCore.QRect(540, 380, 141, 41))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(14)
        self.label_7.setFont(font)
        self.label_7.setObjectName("label_7")
        self.label_8 = QtWidgets.QLabel(self.centralwidget)
        self.label_8.setGeometry(QtCore.QRect(690, 440, 72, 15))
        self.label_8.setObjectName("label_8")
        self.label_9 = QtWidgets.QLabel(self.centralwidget)
        self.label_9.setGeometry(QtCore.QRect(811, 534, 261, 171))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(36)
        self.label_9.setFont(font)
        self.label_9.setObjectName("label_9")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 835, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.qwebengine = QWebEngineView(self.centralwidget)
        self.qwebengine.setGeometry(QtCore.QRect(1, 1, 451, 321))
        self.qwebengine.setAutoFillBackground(False)
        self.qwebengine.setStyleSheet("background-color:rgb(170,170,127);")
        self.qwebengine.setObjectName("qwebengine")
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "录制中...."))
        self.pushButton.setText(_translate("MainWindow", "录制"))
        self.pushButton_2.setText(_translate("MainWindow", "结束"))
        self.label_2.setText(_translate("MainWindow", "前进"))
        self.label_3.setText(_translate("MainWindow", "停止"))
        self.label_4.setText(_translate("MainWindow", "后退"))
        self.lineEdit.setText(_translate("MainWindow", "192.168.1.1"))
        self.label_5.setText(_translate("MainWindow", "IP"))
        self.pushButton_3.setText(_translate("MainWindow", "连接"))
        self.label_6.setText(_translate("MainWindow", "可以啦"))
        self.label_7.setText(_translate("MainWindow", "采集频率设置"))
        self.label_8.setText(_translate("MainWindow", "1-144"))
        self.label_9.setText(_translate("MainWindow", "by西木康"))

逻辑部分





#coding=gbk
'''
from PyQt5.QtWebEngineWidgets import QWebEngineView
        self.qwebengine = QWebEngineView(self.centralwidget)
        self.qwebengine.setGeometry(QtCore.QRect(1, 1, 451, 321))
        self.qwebengine.setAutoFillBackground(False)
        self.qwebengine.setStyleSheet("background-color:rgb(170,170,127);")
        self.qwebengine.setObjectName("qwebengine")
'''
import json
import os
import re
import hashlib
import datetime
import _thread
import time

import cv2
import sys
import socket
from PyQt5.QtCore import QUrl, QFileInfo
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QMainWindow,QGraphicsOpacityEffect,QWidget
from car_coutoralmain import Ui_MainWindow



IP = '192.168.2.17'
dremm = 'http://{}:8080/?action=stream'.format(IP)
Date_send = {"staus": '1' }
Date_countral = {"vedio": False,"Path":'./vio/',"Patn_s":'202205200853',"times": 1,"ffp_time": 50}
def sent_msg(msg):  # 创建 socket 对象

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = IP
        port = 6666
        s.connect((host, port))

        #print(msg)
        msg = json.dumps(msg)
        s.sendall(msg.encode('utf-8'))
        s.close()

        print("发送成功")

    except:
        print("发送失败")


def vedio():
    print("kaishi")
    cap = cv2.VideoCapture(dremm)
    while(cap.isOpened()):

        ret, frame = cap.read()
        if frame is None:  # 防止后面卡死 或 视频最后为空
            break

        if Date_countral['vedio']:
            if os.path.exists(Date_countral["Path"]):
                pass
            else:
                os.mkdir(Date_countral["Path"])
            if os.path.exists(Date_countral["Path"] +  Date_countral["Patn_s"]):
                pass
            else:
                os.mkdir(Date_countral["Path"] +  Date_countral["Patn_s"])

            pathss = Date_countral["Path"] +  Date_countral["Patn_s"]+ '/{}.jpg'.format(Date_countral["times"])
            cv2.imwrite(pathss, frame)
            Date_countral["times"] += 1
        c = cv2.waitKey(Date_countral["ffp_time"])
        if c == 27:
            break

    cap.release()
    cv2.destroyAllWindows()
class Wepapp(QMainWindow):

    def __init__(self , parent = None):
        super().__init__(parent)
        self.__ui = Ui_MainWindow()
        self.__ui.setupUi(self)
        #load(QUrl(QFileInfo("base.html").absoluteFilePath()))
        #self.__ui.qwebengine.load(QUrl(QFileInfo("base.html").absoluteFilePath()))
        #self.pushButton_3.setGraphicsEffect(op)
        self.__ui.qwebengine.load(QUrl(r"http://192.168.2.17:8080/?action=stream"))
        self.__ui.label.setVisible(False)
        self.__ui.label_6.setVisible(False)
        self.__ui.pushButton_3.clicked.connect(self.reset_self)
        self.__ui.pushButton.clicked.connect(self.luzhi)
        self.__ui.pushButton_2.clicked.connect(self.tingzhi)
        self.__ui.verticalScrollBar.valueChanged.connect(self.movewhile)
        self.__ui.spinBox.valueChanged.connect(self.set_fft)


    def reset_self(self):
        IP = self.__ui.lineEdit.text()
        _thread.start_new_thread(vedio, ())
        self.__ui.label_6.setVisible(True)
    def luzhi(self):
        Date_countral["Patn_s"] = time.strftime("%Y%m%d%H%M%S", time.localtime())
        Date_countral["times"] = 1
        Date_countral["vedio"] = True
        self.__ui.label.setVisible(True)

    def tingzhi(self):
        Date_countral["vedio"] = False
        self.__ui.label.setVisible(False)


    def movewhile(self):
        Date_send["staus"] = self.__ui.verticalScrollBar.value()
        print(Date_send["staus"])
        sent_msg(Date_send)
    def set_fft(self):
        Date_countral["ffp_time"] = int(1000/self.__ui.spinBox.value())



if __name__ == '__main__':
    #_thread.start_new_thread(vedio, ())
    app = QApplication(sys.argv)
    MainWindow = Wepapp()
    MainWindow.show()
    sys.exit(app.exec_())

解析

'''
from PyQt5.QtWebEngineWidgets import QWebEngineView
        self.qwebengine = QWebEngineView(self.centralwidget)
        self.qwebengine.setGeometry(QtCore.QRect(1, 1, 451, 321))
        self.qwebengine.setAutoFillBackground(False)
        self.qwebengine.setStyleSheet("background-color:rgb(170,170,127);")
        self.qwebengine.setObjectName("qwebengine")
'''
想要把视频显示出来,就需要一个窗口,此段代码创建一个用于驱动网页的窗口,通过绑定树莓派摄像头的IP地址可以实时播放。

def sent_msg(msg):  # 创建 socket 对象

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = IP
        port = 6666
        s.connect((host, port))

        #print(msg)
        msg = json.dumps(msg)
        s.sendall(msg.encode('utf-8'))
        s.close()

        print("发送成功")

    except:
        print("发送失败")
通过socket发送用于控制车辆运动的指令。
def vedio():
    print("kaishi")
    cap = cv2.VideoCapture(dremm)
    while(cap.isOpened()):

        ret, frame = cap.read()
        if frame is None:  # 防止后面卡死 或 视频最后为空
            break

        if Date_countral['vedio']:
            if os.path.exists(Date_countral["Path"]):
                pass
            else:
                os.mkdir(Date_countral["Path"])
            if os.path.exists(Date_countral["Path"] +  Date_countral["Patn_s"]):
                pass
            else:
                os.mkdir(Date_countral["Path"] +  Date_countral["Patn_s"])

            pathss = Date_countral["Path"] +  Date_countral["Patn_s"]+ '/{}.jpg'.format(Date_countral["times"])
            cv2.imwrite(pathss, frame)
            Date_countral["times"] += 1
        c = cv2.waitKey(Date_countral["ffp_time"])
        if c == 27:
            break
用于编写将摄像头的图像存于计算机本地,相关动作受UI按键的影响,以实现可控的录制。
    def reset_self(self):
        IP = self.__ui.lineEdit.text()
        _thread.start_new_thread(vedio, ())
        self.__ui.label_6.setVisible(True)
    def luzhi(self):
        Date_countral["Patn_s"] = time.strftime("%Y%m%d%H%M%S", time.localtime())
        Date_countral["times"] = 1
        Date_countral["vedio"] = True
        self.__ui.label.setVisible(True)

    def tingzhi(self):
        Date_countral["vedio"] = False
        self.__ui.label.setVisible(False)


    def movewhile(self):
        Date_send["staus"] = self.__ui.verticalScrollBar.value()
        print(Date_send["staus"])
        sent_msg(Date_send)
    def set_fft(self):
        Date_countral["ffp_time"] = int(1000/self.__ui.spinBox.value())
将按键事件的触发执行相关动作

效果图

在这里插入图片描述

客户端

import json

import RPi.GPIO as GPIO
import time
import datetime,socket
from multiprocessing import Process,Pool
import threading
from threading import Lock,Thread


IPhost = '192.168.2.17'



#############################






PWMA = 18
AIN1 = 22
AIN2 = 27

PWMB = 23
BIN1 = 25
BIN2 = 24
Date = {"staus": "1" }

def Update():
    global Date

    host = IPhost
    port = 6666
    serversocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind((host, port))
    serversocket.listen(5)
    while True:
        try:
            clientsocket, addr = serversocket.accept()
            rec_msg = clientsocket.recv(1024).decode('utf-8')
            Date = json.loads(rec_msg)
        except:
            #Date =  {'car':'stop','camero':'off','arm':'stop'}
            Date['staus'] = '1'




def t_up(speed):
    L_Motor.ChangeDutyCycle(speed)
    GPIO.output(AIN2, False)  # AIN2
    GPIO.output(AIN1, True)  # AIN1

    R_Motor.ChangeDutyCycle(speed)
    GPIO.output(BIN2, False)  # BIN2
    GPIO.output(BIN1, True)  # BIN1
 


def t_stop():
    L_Motor.ChangeDutyCycle(0)
    GPIO.output(AIN2, False)  # AIN2
    GPIO.output(AIN1, False)  # AIN1

    R_Motor.ChangeDutyCycle(0)
    GPIO.output(BIN2, False)  # BIN2
    GPIO.output(BIN1, False)  # BIN1
 


def t_down(speed):
    L_Motor.ChangeDutyCycle(speed)
    GPIO.output(AIN2, True)  # AIN2
    GPIO.output(AIN1, False)  # AIN1

    R_Motor.ChangeDutyCycle(speed)
    GPIO.output(BIN2, True)  # BIN2
    GPIO.output(BIN1, False)  # BIN1
 




GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(AIN2, GPIO.OUT)
GPIO.setup(AIN1, GPIO.OUT)
GPIO.setup(PWMA, GPIO.OUT)

GPIO.setup(BIN1, GPIO.OUT)
GPIO.setup(BIN2, GPIO.OUT)
GPIO.setup(PWMB, GPIO.OUT)

L_Motor = GPIO.PWM(PWMA, 100)
L_Motor.start(0)

R_Motor = GPIO.PWM(PWMB, 100)
R_Motor.start(0)





def Run_car():
    global Date
    print("kaishi")
    while True:

        rec_msg = Date['staus']
        print(rec_msg)
        if rec_msg == 1:
            t_stop()

        elif rec_msg == 2:
            t_down(50)

        elif rec_msg == 0:
            t_up(50)
        else :
            t_stop()
        
        

            
        #clientsocket.close()

if __name__ == "__main__":
    print("project is running")
    t1 = threading.Thread(target=Update)
    t2 = threading.Thread(target=Run_car)
    t1.setDaemon(True)
    t2.setDaemon(True)
    t1.start()
    t2.start()
    print("end")
    

讲解

此段程序较为简单,暂无介绍

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是可以使用的PyQt5代码: ```python import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtMultimedia import * from PyQt5.QtMultimediaWidgets import * class CameraWidget(QWidget): def __init__(self, parent=None): super(CameraWidget, self).__init__(parent) # 创建Camera对象 self.camera = QCamera(self) # 创建显示相机画面的QCameraViewfinder对象 self.viewfinder = QCameraViewfinder(self) self.viewfinder.show() # 设置相机给QCameraViewfinder self.camera.setViewfinder(self.viewfinder) # 创建用于捕捉图像的QCameraImageCapture对象 self.imageCapture = QCameraImageCapture(self.camera) # 定义拍照按钮 self.captureButton = QPushButton("拍照") self.captureButton.clicked.connect(self.captureImage) # 创建水平布局 layout = QHBoxLayout() layout.addWidget(self.viewfinder) layout.addWidget(self.captureButton) self.setLayout(layout) def captureImage(self): # 定义用于保存照片的文件名 filename = QDateTime.currentDateTime().toString("yyyyMMddhhmmsszzz.jpg") # 定义照片保存路径 filepath = "./" + filename # 拍照并保存图片到指定路径 self.imageCapture.capture(filepath) # 显示拍摄的照片 image = QImage(filepath) pixmap = QPixmap.fromImage(image) scaledPixmap = pixmap.scaled(self.viewfinder.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.viewfinder.setPixmap(scaledPixmap) if __name__ == '__main__': app = QApplication(sys.argv) widget = CameraWidget() widget.show() sys.exit(app.exec_()) ``` 这段代码将创建一个窗口,其中包括一个显示电脑摄像头拍摄的画面的区域、一个拍照按钮和一个用于保存拍照的照片的文件名的文件路径。当用户点击拍照按钮时,程序会拍摄照片并在窗口中显示该照片。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值