|
| 1 | +import time |
| 2 | + |
| 3 | +import cv2 |
| 4 | +import socket |
| 5 | +import numpy as np |
| 6 | +import struct |
| 7 | + |
| 8 | + |
| 9 | +class Camera(object): |
| 10 | + # 摄像头类,采集视频,发送到服务器 |
| 11 | + |
| 12 | + # 创建类时打开摄像头 |
| 13 | + def __init__(self, dest_ip, dest_port): |
| 14 | + # 打开摄像头 |
| 15 | + self.myVC = cv2.VideoCapture(0) |
| 16 | + |
| 17 | + # 创建套接字(用于主机与服务器端通讯) |
| 18 | + self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
| 19 | + |
| 20 | + # 连接服务器 |
| 21 | + self.client_socket.connect((dest_ip, dest_port)) |
| 22 | + |
| 23 | + # 定义了压缩后图片的绝对大小,160x120 |
| 24 | + self.resolution = (1024, 720) |
| 25 | + |
| 26 | + def run(self): |
| 27 | + try: |
| 28 | + # 循环发送图片 |
| 29 | + while True: |
| 30 | + # 采集摄像头 |
| 31 | + # 参数check为是否捕获成功,参数img为捕获影像 |
| 32 | + # myVC.read()返回两个值 |
| 33 | + check, img = self.myVC.read() |
| 34 | + |
| 35 | + # 压缩图片 |
| 36 | + |
| 37 | + # 重置图片大小(防止摄像头拍出来的图片默认大小不同) |
| 38 | + img = cv2.resize(img, self.resolution) |
| 39 | + # 将img图片压缩为jpg格式(_, 指的是他第一个返回值用不上,丢弃了) |
| 40 | + _, img_encode = cv2.imencode('.jpg', img) |
| 41 | + # 转换为numpy格式数据 |
| 42 | + img_code = np.array(img_encode) |
| 43 | + # 生成对应的二进制数据 |
| 44 | + img_date = img_code.tobytes() |
| 45 | + |
| 46 | + # 打印传输图片的数据大小 |
| 47 | + print("Transmitting image data size:", len(img_date)) |
| 48 | + |
| 49 | + # 发送到服务器 |
| 50 | + # i 表示4个字节,h 表示2个字节 |
| 51 | + # ihh表示 1 2 3 个参数分别为 4 2 2 字节 |
| 52 | + # 参数1传图片大小,参数2传图片宽度,参数3传图片高度,参数4传图片本身 |
| 53 | + # struct是python提供的传定长数据(在此处为了让服务端分开哪到哪的数据为一张图片 |
| 54 | + # 这里为什么要try呢?因为发送的图片过大会导致发送失败 |
| 55 | + try: |
| 56 | + self.client_socket.send( |
| 57 | + struct.pack("ihh", len(img_date), self.resolution[0], self.resolution[1]) + img_date) |
| 58 | + except Exception as e: |
| 59 | + print("Error sending data:", e) |
| 60 | + continue # 继续当前循环 |
| 61 | + # time.sleep(0.1) |
| 62 | + except KeyboardInterrupt: |
| 63 | + # 按下按键退出程序 |
| 64 | + pass |
| 65 | + |
| 66 | + def __del__(self): |
| 67 | + # 释放摄像头资源 |
| 68 | + self.myVC.release() |
| 69 | + |
| 70 | + # 关闭套接字 |
| 71 | + self.client_socket.close() |
| 72 | + |
| 73 | + |
| 74 | +# 定义主函数 |
| 75 | +def main(): |
| 76 | + # 1. 获取链接的tcp服务器的IP |
| 77 | + dest_ip = input("请输入服务器IP:") |
| 78 | + dest_ip = dest_ip if dest_ip else "127.0.0.1" |
| 79 | + |
| 80 | + # 2. 获取tcp服务器的端口 |
| 81 | + dest_port = input("请输入服务器的端口:") |
| 82 | + dest_port = int(dest_port) if dest_port else 54609 |
| 83 | + |
| 84 | + # 3. 创建Camera对象 |
| 85 | + camera = Camera(dest_ip, dest_port) |
| 86 | + |
| 87 | + # 4. 调用对象run方法,为服务器传送摄像头数据 |
| 88 | + camera.run() |
| 89 | + |
| 90 | + pass |
| 91 | + |
| 92 | + |
| 93 | +if __name__ == '__main__': |
| 94 | + main() |
0 commit comments