PC电脑实时接收树莓派摄像头图像数据并显示(Python实现)

目录

一、任务概述

二、环境安装

三、实现

3.1 上位机端(PC服务器端)

3.2 树莓派端(客户请求端)

四、运行效果


一、任务概述

最近在做一个树莓派自动驾驶小车,上位机使用windows10 PC电脑,下位机小车采用树莓派4B,树莓派上安装了USB免驱摄像头。上位机通过SSH来控制和分析树莓派小车。树莓派上使用python版的opencv读取摄像头图像数据。

实验时发现,上位机通过SSH控制树莓派时会自发的将远程图像数据也显示过来(调用cv2.imshow的时候),但是这种通过SSH传输图像的方式会造成SSH卡顿,导致视频图像卡、下位机机电控制卡。但是在小车运行的时候它上面的树莓派不方便连接显示器,而我们又需要实时反馈运动中的小车图像给上位机来调试分析。因此,需要一种高效的在树莓派和PC之间通过无线局域网的视频图像传输方案。

网上方法有很多,这里介绍一种自己亲身试验过并且相对比较简单的方法。

二、环境安装

首先确保上位机(PC电脑)和下位机(树莓派)均安装好了python版的opencv和numpy。

接下来在上下位机均安装帧传输模块zmq:

sudo pip3 install zmq

然后在上下位机均安装帧编解码库pybase64:

sudo pip3 install pybase64

到这里环境安装结束。

三、实现

3.1 上位机端(PC服务器端)

import cv2
import zmq
import base64
import numpy as np

def main():
    '''
    主函数
    '''
    context = zmq.Context()
    footage_socket = context.socket(zmq.PAIR)
    footage_socket.bind('tcp://*:5555')
    cv2.namedWindow('Stream',flags=cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)


    while True:
        print("监听中")
        frame = footage_socket.recv_string() #接收TCP传输过来的一帧视频图像数据
        img = base64.b64decode(frame) #把数据进行base64解码后储存到内存img变量中
        npimg = np.frombuffer(img, dtype=np.uint8) #把这段缓存解码成一维数组
        source = cv2.imdecode(npimg, 1) #将一维数组解码为图像source
        cv2.imshow("Stream", source) #把图像显示在窗口中
        cv2.waitKey(5) #延时等待,防止出现窗口无响应

 
if __name__ == '__main__':
    '''
    程序入口
    '''
    main()

然后在上位机上运行上述脚本代码。

3.2 树莓派端(客户请求端)

import cv2
import zmq
import base64


def main():
    '''
    主函数
    '''
    IP = '192.168.2.148' #上位机视频接受端的IP地址

    # 创建并设置视频捕获对象
    cap = cv2.VideoCapture(0)
    print("摄像头是否已经打开 ? {}".format(cap.isOpened()))
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)  # 设置图像宽度
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)  # 设置图像高度

    # 建立TCP通信协议
    contest = zmq.Context()
    footage_socket = contest.socket(zmq.PAIR)
    footage_socket.connect('tcp://%s:5555'%IP)

    while True:
        # 读取图像
        ret, frame = cap.read()

        # 转换为流数据并编码
        encoded, buffer = cv2.imencode('.jpg', frame) 
        jpg_as_test = base64.b64encode(buffer) #把内存中的图像流数据进行base64编码

        # 发送数据
        footage_socket.send(jpg_as_test) #把编码后的流数据发送给视频的接收端
        cv2.waitKey(5) #延时等待,防止出现窗口无响应


if __name__ == '__main__':
    '''
    程序入口
    '''
    main()

在下位机端运行上述脚本代码。

四、运行效果

 整体运行还是比较顺畅的,解决了上下位机图像实时显示的问题。

来源:钱彬 (Qian Bin)

物联沃分享整理
物联沃-IOTWORD物联网 » PC电脑实时接收树莓派摄像头图像数据并显示(Python实现)

发表评论