1、程序语言:python
2、主要功能包:socket、opencv
3、主要思想思路:服务端和客户端都建立受发双线程
4、用处:可用于深度学习,树莓派接收视频数据传到电脑处理数据,之后再返
回结果给树莓派

电脑端(服务器)

导入相应的包

import socket
import cv2 as cv
import time
from threading import Thread

收线程(接收视频流)

# define the receiving threading
class Receive(Thread):
    def __init__(self,re):
        Thread.__init__(self)
        self.pi = re

    # save the image in the t_image queue
    def run(self):
        while True:
            image = self.read_image()
            if not t_image.full():
                print("only put")
                t_image.put(image)
            else:
                print("clear and put")
                t_image.get_nowait()           # take image from origin queue and send the new image to it.
                t_image.put(image)


    # reading image in this function
    def read_image(self):
        image_binary = b''
        sign = self.pi.recv(8)
        if sign[:4].decode('utf-8') == "send":
            image_len = int.from_bytes(sign[4:8], byteorder='little')
            rec_len = 0
            max = 1024
            while rec_len < image_len:
                image_binary += self.pi.recv(max)
                rec_len = len(image_binary)
                if (rec_len+max)>image_len:
                    max = (image_len - rec_len)
        image_np = np.frombuffer(image_binary, np.uint8)  # transform image to np.uint8 format
        image = cv.imdecode(image_np, cv.IMREAD_COLOR)  # decode image to the type of opencv

        return image

发线程(返回结果)

class Send(Thread):
    def __init__(self, pi):
        Thread.__init__(self)
        self.send = pi
    def run(self) -> None:
        time.sleep(13)
        print("start sending thread")
        while True:
            if len(temp) > 9:
                self.send.send("true".encode('utf-8'))
            else:                   #如果没有else,进程会卡死在if上,导致传输有问题???反正不加else就出事...
                time.sleep(3)

定义套件字和开启线程

    host_ip = "此处输入你电脑的ip,如果不知道,下面教你怎么查"
    host_port = 8888
    host_arr = (host_ip, host_port)
    tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp.bind(host_arr)
    tcp.listen(5)   # support five devices connecting
    # waiting connecting
    while True:
        print("waiting connecting ..........")
        pi, address = tcp.accept()
        print("connect {0} sueccssful !".format(address))
        break
    send = Send(pi)
    send.start()
 

打开电脑命令窗口(cmd),输入ipconfig -all,找到Ipv4就是你要输入的ip了。

客户端(树莓派)

导入相应的包

import socket
import cv2 as cv
import time
from threading import Thread

发送视频流线程

# define sending thread
def Send():
    cap = cv.VideoCapture(0)
    while cap.isOpened():
        _, img = cap.read()
        # print("client sending thread")
        img_encode = cv.imencode('.jpg', img, [cv.IMWRITE_JPEG_QUALITY, 70])[1]
        image_binary = img_encode.tobytes()  # transform bytes stream
        send_data = "send".encode('utf-8') + (len(image_binary)).to_bytes(4, byteorder='little') + image_binary
        sock.sendall(send_data)

接收返回的结果线程

# define a receiving thread
def Receive():
    time.sleep(6)
    print("start receiving thread")
    while True:
        temp = sock.recv(4).decode('utf-8')
        print(temp)

连接线程(主线程)

SERVER_IP, SERVER_PORT = "此处输入电脑的ip", 8888
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = (SERVER_IP, SERVER_PORT)
    while True:
        try:
            print("Connecting to server @ %s:%d..." % (SERVER_IP, SERVER_PORT))
            sock.connect(server_address)
            print("connect successful !")
            break
        except Exception:
            print("Can't connect to server,try it latter!")
            time.sleep(1.5)
            continue
    Thread(target=Send).start()
    Thread(target=Receive).start()

树莓派-Opencv

树莓派opencv镜像文件在此,烧入完成后进行更新。

链接:https://pan.baidu.com/s/1XaB1CaMw3K6yXumMCs6l_A
提取码:1234

使用指南(必看)

sudo apt-get update&&upgrade
#解决文件夹闪退问题
sudo apt full-upgrade --fix-missing

写在最后

这篇文章呈现的代码有一些小问题。第一关于t_image的定义问题,其实它是一个queue(队列),用于存放图片数据。可以通过以下代码定义一下。

from queue import Queue
t_image = Queue(maxsize=5)

另一个问题就是temp的定义问题。由于这些代码是我当时在做的一个深度学习项目的一小部分,而我写这篇文章的时候把它们囫囵吞枣的截取下来,导致这个变量在这里显得没头没尾。但时过境迁,我既找不到当时的源码,也忘记这个变量是做什么的。。。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐