我是靠谱客的博主 花痴溪流,最近开发中收集的这篇文章主要介绍树莓派通过socket传输图片流-Python,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

树莓派通过socket传输图片流的Python实现

socket设置

客户端

这里将树莓派当做socket的客户端。代码如下:

"""set ip address"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.1.1', 8000))

服务器端

服务器端socket设置如下:

host = '0.0.0.0'
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 定义socket类型
s.bind((host, port))  # 绑定需要监听的Ip和端口号,tuple格式
s.listen(5)

host设置空表示接受所有ip的访问。
listen()值表示等待的资源池为5。

具体实现

客户端

# -*- coding: UTF-8 -*-
import socket, os, struct
import time
from picamera import  PiCamera

"""set ip address"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.123.174', 8000))

"""set camera"""
camera = PiCamera()
camera.resolution = (1920,1080)
camera.framerate = 60

"""get opencv-classifier"""
face_cascade = cv2.CascadeClassifier('/home/pi/opencv-3.3.0/data/lbpcascades/lbpcascade_frontalface.xml' )

while True:
    camera.capture('/home/pi/class/0.jpg')
    filepath = '/home/pi/class/0.jpg'
    image = cv2.imread(filepath)
    gray = cv2.cvtColor( image, cv2.COLOR_BGR2GRAY )
    faces = face_cascade.detectMultiScale( gray )
    if os.path.isfile(filepath) and len(faces):
        fileinfo_size = struct.calcsize('128sl')  # 定义打包规则
        # 定义文件头信息,包含文件名和文件大小
        fhead = struct.pack('128sl', os.path.basename(filepath), os.stat(filepath).st_size)
        s.send(fhead)
        print('client filepath: ', os.path.basename(filepath), os.stat(filepath).st_size)

        # with open(filepath,'rb') as fo: 这样发送文件有问题,发送完成后还会发一些东西过去
        fo = open(filepath, 'rb')
        while True:
            filedata = fo.read(1024)
            if not filedata:
                break
            s.send(filedata)
        #time.sleep(0.5)
        fo.close()
        print('send over...')
    #time.sleep(0.5)
        # s.close()

服务器端实现

import socket, time, struct, os, threading
import sqlite3

host = '0.0.0.0'
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 定义socket类型
s.bind((host, port))  # 绑定需要监听的Ip和端口号,tuple格式
s.listen(5)


def conn_thread(connection, address):
    con = sqlite3.connect('test.db')
    location = ''
    i = 0
    while True:
        try:
            connection.settimeout(600)
            fileinfo_size = struct.calcsize('128sl')
            buf = connection.recv(fileinfo_size)
            #print(buf)
            if buf:  # 如果不加这个if,第一个文件传输完成后会自动走到下一句
                filename, filesize = struct.unpack('128sl', buf)
                print("照片大小:"+str(filesize))
                if filesize< 0 or filesize > 2432075:
                    # da = connection.recv()
                    continue
                filename = filename.decode().strip('0')
                # print(filename)
                #filename = os.path.join('e:\', ('new_' + filename))
                print('file new name is %s, filesize is %s' % (filename, filesize))

                # 获取当前时间
                localtime = time.time()
                # 获取地址
                # if(address == ''):
                #     location = 'netlab_530'
                location = 'netlab_530'
                # 构造文件路径
                filepath = './face/netlab_530-'+ str(i) + '.jpg'
                # 将文件名加入链表
                cur = con.cursor()
                for t in [(location,localtime)]:
                    cur.execute("INSERT INTO image (location,localtime) 
                              VALUES (?,?)",t)
                con.commit()
                file = open(filepath,'wb')
                # file = open('./face/'+filename, 'wb')
                print('stat receiving...filesize:' + str(filesize))
                recvd_size = 0  # 定义接收了的文件大小
                while recvd_size != filesize:
                    if filesize - recvd_size >= 1024:
                        rdata = connection.recv(1024)
                        recvd_size += len(rdata)
                    elif filesize - recvd_size <1024 and filesize - recvd_size > 0:
                        print(filesize - recvd_size)
                        rdata = connection.recv(filesize - recvd_size)
                        recvd_size += len(rdata)
                    file.write(rdata)
                file.close()
                print('receive done')
                # connection.close()
            i += 1
        except socket.timeout:
            connection.close()
            con.close()



def main():
    while True:
        print("开始接收图片")
        connection, address = s.accept()
        print('Connected by ', address)
        thread = threading.Thread(target=conn_thread, args=(connection, address))  # 使用threading也可以
        thread.start()
        # threading.start_new_thread(conn_thread, (connection, address))

    s.close()


if __name__ == '__main__':
    main()

出现问题

在实现中会出现一开始传输正常但是后面会出现问题,debug了很久才发现是服务器端接收的时候对图片尺寸的计算有些逻辑错误造成的。

最后

以上就是花痴溪流为你收集整理的树莓派通过socket传输图片流-Python的全部内容,希望文章能够帮你解决树莓派通过socket传输图片流-Python所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部