使用 python 3.4 opencv 3.2 使用 usbcam 进行套接字编程
Socket programming with usbcam using python 3.4 opencv 3.2
我正在做一个项目,需要在服务器端使用 USB 网络摄像头 在客户端直播视频。
我正在使用 (Opencv 3.2.0 + python 3.4.3).
下面给出的代码工作正常,我想知道这段代码实际如何工作以及它如何将帧传输到客户端。
此代码存在延迟,以及如何克服该延迟。我试图设置分辨率,但它在客户端给出错误,如([错误]:新数组的总大小必须不变)。我将它设置为默认分辨率(即640*480)它工作正常。
Help me
1. to set the resolution. -answered
2. why dtype uint8 is used? -answered
3. what is role fileDescriptor? -answered
更新问题:
- 在服务器端 - 我遇到类似的问题(需要按两次 ctrl+c 才能停止服务器 - 为什么会这样) - new
- 服务器是或者运行成功(即,对于第一个 未连接,第二 连接,第三时间越来越停止,第四时间运行好-为什么它发生了吗? - new
- 如何减少延迟? - 新
让我们看看谁会回答所有这些问题!!!
服务器:
import cv2
import time
import json
import socket
import base64
import numpy as np
from threading import Thread
SERVER_IP = "x.x.x.x"
SERVER_PORT = xxxx
MAX_NUM_CONNECTIONS = 20
DEVICE_NUMBER = 0
class ConnectionPool(Thread):
def __init__(self, ip_, port_, conn_, device_):
Thread.__init__(self)
self.ip = ip_
self.port = port_
self.conn = conn_
self.device = device_
print("[+] New server socket thread started for " + self.ip + ":" +str(self.port))
def run(self):
try:
while True:
ret, frame = self.device.read()
a = b'\r\n'
data = frame.tostring()
da = base64.b64encode(data)
self.conn.sendall(da + a)
except Exception as e:
print("Connection lost with " + self.ip + ":" + str(self.port) +"\r\n[Error] " + str(e.message))
self.conn.close()
if __name__ == '__main__':
cap = cv2.VideoCapture(DEVICE_NUMBER)
print("Waiting connections...")
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
connection.bind((SERVER_IP, SERVER_PORT))
connection.listen(MAX_NUM_CONNECTIONS)
while True:
(conn, (ip, port)) = connection.accept()
thread = ConnectionPool(ip, port, conn, cap)
thread.start()
connection.close()
cap.release()
客户:
import cv2
import socket
import base64
import numpy as np
IP_SERVER = "x.x.x.x"
PORT_SERVER = xxxx
TIMEOUT_SOCKET = 10
SIZE_PACKAGE = 4096
IMAGE_HEIGHT = 480
IMAGE_WIDTH = 640
COLOR_PIXEL = 3 # RGB
if __name__ == '__main__':
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
connection.settimeout(TIMEOUT_SOCKET)
connection.connect((IP_SERVER, PORT_SERVER))
while True:
try:
fileDescriptor = connection.makefile(mode='rb')
result = fileDescriptor.readline()
fileDescriptor.close()
result = base64.b64decode(result)
frame = np.fromstring(result, dtype=np.uint8)
frame_matrix = np.array(frame)
frame_matrix = np.reshape(frame_matrix, (IMAGE_HEIGHT, IMAGE_WIDTH,COLOR_PIXEL))
cv2.imshow('Window title', frame_matrix)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print("[Error] " + str(e))
connection.close()
- to set the resolution.
您必须在服务器端和客户端这两个地方进行更改。您遇到的错误很可能来自 reshape
函数。此函数将从图像中获取数据并对其进行整形,这意味着数据将保持不变,只有大小会发生变化......在这种情况下,它用于将一维数据数组更改为二维矩阵 3 通道矩阵(但是数据顺序不变)。怎么改,得先在server部分改。
它说的地方
ret, frame = self.device.read()
之后可以添加OpenCV的resize功能:
frame = cv2.resize(frame ,(width/2, height/2), interpolation = cv2.INTER_LINEAR )
这将减半。现在在客户端你可以减少到:
IMAGE_HEIGHT = 480 / 2
IMAGE_WIDTH = 640 / 2
- why dtype uint8 is used?
这来自OpenCV (BGR) 默认使用的图像表示,这意味着每个像素颜色由 3 个通道表示,蓝绿色和红色。每个通道的值都在 0-255 之间,这意味着它可以用 8 位表示,这就是 dtype uint8 的原因。稍后函数 reshape 将从 3 个连续值(COLOR_PIXEL 值)创建像素。
在这部分中,代码读取一行文本,这是图像数据并将其放入一维数组中。这将表明该行的每个 8 位都是一个值,应该被视为一个整数。
- what is role fileDescriptor?
这是一种从套接字读取数据的方法。参见documentation。这样你就可以使用 readline,并获得由换行符限制的数据块。在你的情况下 '\r\n'
。查看行:
a = b'\r\n'
data = frame.tostring()
da = base64.b64encode(data)
self.conn.sendall(da + a)
a
是return字符,在整个图像数据以字符串表示并用base 64编码后发送。
我正在做一个项目,需要在服务器端使用 USB 网络摄像头 在客户端直播视频。
我正在使用 (Opencv 3.2.0 + python 3.4.3).
下面给出的代码工作正常,我想知道这段代码实际如何工作以及它如何将帧传输到客户端。
此代码存在延迟,以及如何克服该延迟。我试图设置分辨率,但它在客户端给出错误,如([错误]:新数组的总大小必须不变)。我将它设置为默认分辨率(即640*480)它工作正常。
Help me
1. to set the resolution. -answered
2. why dtype uint8 is used? -answered
3. what is role fileDescriptor? -answered
更新问题:
- 在服务器端 - 我遇到类似的问题(需要按两次 ctrl+c 才能停止服务器 - 为什么会这样) - new
- 服务器是或者运行成功(即,对于第一个 未连接,第二 连接,第三时间越来越停止,第四时间运行好-为什么它发生了吗? - new
- 如何减少延迟? - 新
让我们看看谁会回答所有这些问题!!!
服务器:
import cv2
import time
import json
import socket
import base64
import numpy as np
from threading import Thread
SERVER_IP = "x.x.x.x"
SERVER_PORT = xxxx
MAX_NUM_CONNECTIONS = 20
DEVICE_NUMBER = 0
class ConnectionPool(Thread):
def __init__(self, ip_, port_, conn_, device_):
Thread.__init__(self)
self.ip = ip_
self.port = port_
self.conn = conn_
self.device = device_
print("[+] New server socket thread started for " + self.ip + ":" +str(self.port))
def run(self):
try:
while True:
ret, frame = self.device.read()
a = b'\r\n'
data = frame.tostring()
da = base64.b64encode(data)
self.conn.sendall(da + a)
except Exception as e:
print("Connection lost with " + self.ip + ":" + str(self.port) +"\r\n[Error] " + str(e.message))
self.conn.close()
if __name__ == '__main__':
cap = cv2.VideoCapture(DEVICE_NUMBER)
print("Waiting connections...")
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
connection.bind((SERVER_IP, SERVER_PORT))
connection.listen(MAX_NUM_CONNECTIONS)
while True:
(conn, (ip, port)) = connection.accept()
thread = ConnectionPool(ip, port, conn, cap)
thread.start()
connection.close()
cap.release()
客户:
import cv2
import socket
import base64
import numpy as np
IP_SERVER = "x.x.x.x"
PORT_SERVER = xxxx
TIMEOUT_SOCKET = 10
SIZE_PACKAGE = 4096
IMAGE_HEIGHT = 480
IMAGE_WIDTH = 640
COLOR_PIXEL = 3 # RGB
if __name__ == '__main__':
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
connection.settimeout(TIMEOUT_SOCKET)
connection.connect((IP_SERVER, PORT_SERVER))
while True:
try:
fileDescriptor = connection.makefile(mode='rb')
result = fileDescriptor.readline()
fileDescriptor.close()
result = base64.b64decode(result)
frame = np.fromstring(result, dtype=np.uint8)
frame_matrix = np.array(frame)
frame_matrix = np.reshape(frame_matrix, (IMAGE_HEIGHT, IMAGE_WIDTH,COLOR_PIXEL))
cv2.imshow('Window title', frame_matrix)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print("[Error] " + str(e))
connection.close()
- to set the resolution.
您必须在服务器端和客户端这两个地方进行更改。您遇到的错误很可能来自 reshape
函数。此函数将从图像中获取数据并对其进行整形,这意味着数据将保持不变,只有大小会发生变化......在这种情况下,它用于将一维数据数组更改为二维矩阵 3 通道矩阵(但是数据顺序不变)。怎么改,得先在server部分改。
它说的地方
ret, frame = self.device.read()
之后可以添加OpenCV的resize功能:
frame = cv2.resize(frame ,(width/2, height/2), interpolation = cv2.INTER_LINEAR )
这将减半。现在在客户端你可以减少到:
IMAGE_HEIGHT = 480 / 2
IMAGE_WIDTH = 640 / 2
- why dtype uint8 is used?
这来自OpenCV (BGR) 默认使用的图像表示,这意味着每个像素颜色由 3 个通道表示,蓝绿色和红色。每个通道的值都在 0-255 之间,这意味着它可以用 8 位表示,这就是 dtype uint8 的原因。稍后函数 reshape 将从 3 个连续值(COLOR_PIXEL 值)创建像素。
在这部分中,代码读取一行文本,这是图像数据并将其放入一维数组中。这将表明该行的每个 8 位都是一个值,应该被视为一个整数。
- what is role fileDescriptor?
这是一种从套接字读取数据的方法。参见documentation。这样你就可以使用 readline,并获得由换行符限制的数据块。在你的情况下 '\r\n'
。查看行:
a = b'\r\n'
data = frame.tostring()
da = base64.b64encode(data)
self.conn.sendall(da + a)
a
是return字符,在整个图像数据以字符串表示并用base 64编码后发送。