在python中使用socket

时间:2019-02-09 08:45:46

标签: python sockets io stream

我将计算机设置为服务器,将树莓派设置为客户端。在我的树莓派中,我有2个文件:第一个是将视频流发送到我的计算机。第二个是从我的计算机接收命令,以运行直流电动机并操纵伺服电动机。问题是我无法使用服务器同时与两个文件通信。

我已经尝试使用Python套接字模块,但是我不能,但是它不起作用

import numpy as np
import cv2
import serial
import pygame
from pygame.locals import *
import socket
import time
import os


class CollectTrainingData(object):

    def __init__(self, host, port, input_size):

        self.server_socket = socket.socket()
        self.server_socket.bind((host, port))
        self.server_socket.listen(0)


        self.conn = self.server_socket.accept()[0].makefile('rb')

        self.input_size = input_size

    # create labels
        self.k = np.zeros((4, 4), 'float')
        for i in range(4):
            self.k[i, i] = 1

        pygame.init()
        pygame.display.set_mode((250, 250))
        self.send_inst = True


    def right(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "3"
        self.conn.send(data.encode())

    def stop(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "0"
        self.conn.send(data.encode())

    def left(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "4"
        self.conn.send(data.encode())

    def reverse(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "2"
        self.conn.send(data.encode())

    def forward(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "1"
        self.conn.send(data.encode())

    def forward_right(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "5"
        self.conn.send(data.encode())

    def forward_left(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "6"
        self.conn.send(data.encode())

    def reverse_right(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "8"
        self.conn.send(data.encode())

    def reverse_left(self):
        data = self.conn.recv(1024).decode()
        print("from connected Raspi : " + str(data))
        data = "7"
        self.conn.send(data.encode())




    def collect(self):

        saved_frame = 0
        total_frame = 0

        # collect images for training
        print("Start collecting images...")
        print("Press 'q' or 'x' to finish...")
        start = cv2.getTickCount()

        X = np.empty((0, self.input_size))
        y = np.empty((0, 4))

    # stream video frames one by one
        try:
            stream_bytes = b' '
            frame = 1
            while self.send_inst:
                stream_bytes += self.conn.read(1024)
                first = stream_bytes.find(b'\xff\xd8')
                last = stream_bytes.find(b'\xff\xd9')

                if first != -1 and last != -1:
                    jpg = stream_bytes[first:last + 2]
                    stream_bytes = stream_bytes[last + 2:]
                    image = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8), cv2.IMREAD_GRAYSCALE)

                    # select lower half of the image
                    height, width = image.shape
                    roi = image[int(height/2):height, :]  # change it after configuration

                    cv2.imshow('image', image)

                    # reshape the roi image into a vector
                    temp_array = roi

                    frame += 1
                    total_frame += 1

                    # get input from human driver
                    for event in pygame.event.get():
                        if event.type == KEYDOWN:
                            key_input = pygame.key.get_pressed()

                            # complex orders
                            if key_input[pygame.K_UP] and key_input[pygame.K_RIGHT]:
                                self.forward_right()
                                X = np.vstack((X, temp_array))
                                y = np.vstack((y, self.k[1]))
                                saved_frame += 1


                            elif key_input[pygame.K_UP] and key_input[pygame.K_LEFT]:
                                self.forward_left()
                                X = np.vstack((X, temp_array))
                                y = np.vstack((y, self.k[0]))
                                saved_frame += 1


                            elif key_input[pygame.K_DOWN] and key_input[pygame.K_RIGHT]:
                                self.forward_right()


                            elif key_input[pygame.K_DOWN] and key_input[pygame.K_LEFT]:
                                self.forward_right()


                            # simple orders
                            elif key_input[pygame.K_UP]:
                                self.forward()
                                X = np.vstack((X, temp_array))
                                y = np.vstack((y, self.k[2]))
                                saved_frame += 1


                            elif key_input[pygame.K_DOWN]:
                                self.reverse()


                            elif key_input[pygame.K_RIGHT]:
                                self.right()
                                X = np.vstack((X, temp_array))
                                y = np.vstack((y, self.k[1]))
                                saved_frame += 1


                            elif key_input[pygame.K_LEFT]:
                                self.left()
                                X = np.vstack((X, temp_array))
                                y = np.vstack((y, self.k[0]))
                                saved_frame += 1


                            elif key_input[pygame.K_x] or key_input[pygame.K_q]:
                                print("exit")
                                self.send_inst = False
                                break

                        elif event.type == pygame.KEYUP:
                            self.stop()

                    if cv2.waitKey(1) & 0xFF == ord('q'):
                        break
            conn.close()



        # save data as a numpy file
            file_name = str(int(time.time()))
            directory = "training_data"
            if not os.path.exists(directory):
                os.makedirs(directory)
            try:
                np.savez(directory + '/' + file_name + '.npz', train=X, train_labels=y)
            except IOError as e:
                print(e)

            end = cv2.getTickCount()
            # calculate streaming duration
            print("Streaming duration: , %.2fs" % ((end - start) / cv2.getTickFrequency()))

            print(X.shape)
            print(y.shape)
            print("Total frame: ", total_frame)
            print("Saved frame: ", saved_frame)
            print("Dropped frame: ", total_frame - saved_frame)

        finally:
            self.conn.close()

            self.server_socket.close()


if __name__ == '__main__':
    # host, port
    h, p = "192.168.0.102", 8000




    # vector size, half of the image
    s = 320 * 240


    ctd = CollectTrainingData(h, p, s)
    ctd.collect()

我希望能够在计算机上流式传输视频,同时能够将控制命令同时发送到我的树莓派,但是看来我无法使用相同的主机和端口与这两个文件进行通信

0 个答案:

没有答案