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