python socket实现视频传输,服务端加上了目标跟踪,初试帧,手动框选框,后续的跟踪结果会传到socket的client端

首选需要再python里安装socket包,自行百度,网上很多。然后复制上代码之后,看看还缺啥,安装上就先行。

该部分借鉴的博客:

python实现opencv+scoket网络实时图传:https://blog.csdn.net/T_infinity/article/details/79893318

使用OpenCV实现单目标跟踪:https://blog.csdn.net/LuohenYJ/article/details/89029816

 

我修改的后的代码,实测可运行的:

1、server.py端:(对了用的OpenCV的包比较特殊一点,看一下上面提供的第二个博客,进行安装)

# 服务端
import socket
import threading
import struct
import time
import cv2
import numpy
import random

class Carame_Accept_Object:
    def __init__(self, S_addr_port=("", 8880)):
        self.resolution = (640, 480)  # 分辨率
        self.img_fps = 15  # 每秒传输多少帧数
        self.addr_port = S_addr_port
        self.Set_Socket(self.addr_port)

    # 设置套接字
    def Set_Socket(self, S_addr_port):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 端口可复用
        self.server.bind(S_addr_port)
        self.server.listen(5)
        # print("the process work in the port:%d" % S_addr_port[1])


def check_option(object, client):
    # 按格式解码,确定帧数和分辨率
    info = struct.unpack('lhh', client.recv(8))
    if info[0] > 888:
        object.img_fps = int(info[0]) - 888  # 获取帧数
        object.resolution = list(object.resolution)
        # 获取分辨率
        object.resolution[0] = info[1]
        object.resolution[1] = info[2]
        object.resolution = tuple(object.resolution)
        return 1
    else:
        return 0


def RT_Image(object, client, tracker):
    if check_option(object, client) == 0:
        return
    camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    img_param = [int(cv2.IMWRITE_JPEG_QUALITY), object.img_fps]  # 设置传送图像格式、帧数
    first_frame = True
    while True:
        time.sleep(0.1)  # 推迟线程运行0.1s
        _, object.img = camera.read()  # 读取视频每一帧
        object.img = cv2.resize(object.img, object.resolution)  # 按要求调整图像大小(resolution必须为元组)
        if first_frame:
            bbox = cv2.selectROI(object.img, False, False)
            # bbox = (287, 23, 86, 320)
            tracker.init(object.img, bbox)
            first_frame = False
            cv2.destroyAllWindows()
        else:
            ok, bbox = tracker.update(object.img)
            p1 = (int(bbox[0]), int(bbox[1]))
            p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
            cv2.rectangle(object.img, p1, p2, (255, 0, 0), 2, 1)
        _, img_encode = cv2.imencode('.jpg', object.img, img_param)  # 按格式生成图片
        img_code = numpy.array(img_encode)  # 转换成矩阵
        object.img_data = img_code.tostring()  # 生成相应的字符串
        try:
            # 生成伪坐标
            x = random.uniform(50.0, 100.0)
            y = random.uniform(100.0, 150.0)
            # 按照相应的格式进行打包发送图片
            client.send(struct.pack("lhhff", len(object.img_data), object.resolution[0], object.resolution[1], x, y) + object.img_data)
        except:
            camera.release()  # 释放资源
            return


if __name__ == '__main__':
    tracker_types = ['KCF', 'CSRT', 'BOOSTING', 'MIL', 'TLD', 'MEDIANFLOW', 'MOSSE']
    tracker_type = tracker_types[1]
    if tracker_type == 'BOOSTING':
        tracker = cv2.TrackerBoosting_create()
    if tracker_type == 'MIL':
        tracker = cv2.TrackerMIL_create()
    if tracker_type == 'KCF':
        tracker = cv2.TrackerKCF_create()
    if tracker_type == 'TLD':
        tracker = cv2.TrackerTLD_create()
    if tracker_type == 'MEDIANFLOW':
        tracker = cv2.TrackerMedianFlow_create()
    if tracker_type == "CSRT":
        tracker = cv2.TrackerCSRT_create()
    if tracker_type == "MOSSE":
        tracker = cv2.TrackerMOSSE_create()

    object = Carame_Accept_Object()

    while True:
        client, D_addr = object.server.accept()
        clientThread = threading.Thread(None, target=RT_Image, args=(object, client, tracker))
        clientThread.start()

2、client.py端:

# 客户端
import socket
import cv2
import threading
import struct
import numpy

class Camera_Connect_Object:
    def __init__(self, D_addr_port=["", 8880]):
        self.resolution = [640, 480]
        self.addr_port = D_addr_port
        self.src = 888 + 15  # 双方确定传输帧数,(888)为校验值
        self.interval = 0  # 图片播放时间间隔
        self.img_fps = 15  # 每秒传输多少帧数

    def Set_socket(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def Socket_Connect(self):
        self.Set_socket()
        self.client.connect(self.addr_port)
        print("IP is %s:%d" % (self.addr_port[0], self.addr_port[1]))

    def RT_Image(self):
        # 按照格式打包发送帧数和分辨率
        self.name = self.addr_port[0] + " Camera"
        self.client.send(struct.pack("lhh", self.src, self.resolution[0], self.resolution[1]))
        while True:
            info = struct.unpack("lhhff", self.client.recv(16))
            print(info)
            buf_size = info[0]  # 获取读的图片总长度
            if buf_size:
                try:
                    self.buf = b""  # 代表bytes类型
                    temp_buf = self.buf
                    while buf_size:  # 读取每一张图片的长度
                        temp_buf = self.client.recv(buf_size)
                        buf_size -= len(temp_buf)
                        self.buf += temp_buf  # 获取图片
                        data = numpy.fromstring(self.buf, dtype='uint8')  # 按uint8转换为图像矩阵
                        self.image = cv2.imdecode(data, 1)  # 图像解码
                        cv2.imshow(self.name, self.image)  # 展示图片
                except:
                    pass
                finally:
                    if cv2.waitKey(10) == 27:  # 每10ms刷新一次图片,按‘ESC’(27)退出
                        self.client.close()
                        cv2.destroyAllWindows()
                        break

    def Get_Data(self, interval):
        showThread = threading.Thread(target=self.RT_Image)
        showThread.start()

if __name__ == '__main__':
    camera = Camera_Connect_Object()
    camera.addr_port[0] = "127.0.0.1"
    camera.addr_port = tuple(camera.addr_port)
    camera.Socket_Connect()
    camera.Get_Data(camera.interval)

 

3、完毕。

你可能感兴趣的:(Python)