计算每秒 opencv 发送的帧数的问题
Issue in calculating frames sent per second opencv
我有以下代码,我正在计算每秒从客户端向服务器发送帧所花费的时间,基本上是计算帧丢失率的百分比和响应所花费的时间,并且通信模式是异步的。
现在我在计算这两个指标时遇到了一些问题,为了响应所花费的时间,我将延迟设置为超过 5 秒,因为由于网络和服务器的处理速度,将结果发送回客户端需要时间,因此,延迟更长, 但对于每秒帧数,我需要计算每秒从客户端发送到服务器的帧数,我将如何在 data_rate 方法中计算它。两个指标都需要不同的时间延迟,我不能对两个指标使用相同的时间延迟。非常感谢有关如何在代码中定义它的帮助。
IMAGE_FOLDER = "videoframe"
FPS = 5
SERVER_A_ADDRESS = "tcp://localhost:5555"
ENDPOINT_HANDLER_ADDRESS = "tcp://*:5553"
SERVER_A_TITLE = "SERVER A"
SERVER_B_TITLE = "SERVER B"
context = zmq.Context()
socket_server_a = context.socket(zmq.PUSH)
socket_server_endpoint = context.socket(zmq.PULL)
socket_server_a.connect(SERVER_A_ADDRESS)
socket_server_endpoint.bind(ENDPOINT_HANDLER_ADDRESS)
destination = {
"currentSocket": socket_server_a,
"currentServersTitle": SERVER_A_TITLE,
"currentEndpoint": SERVER_B_TITLE,}
running = True
endpoint_responses = 0
frame_requests = 0
filenames = [f"{IMAGE_FOLDER}/frame{i}.jpg" for i in range(1, 2522)]
def handle_endpoint_responses():
global destination, running, endpoint_responses
while running:
endpoint_response = socket_server_endpoint.recv().decode()
endpoint_responses += 1
def data_rate():
global destination, running, endpoint_responses, frame_requests
while running:
before_received = endpoint_responses ###
time.sleep(5)
after_received = endpoint_responses
before_sent = frame_requests
time.sleep(1)
after_sent = frame_requests ###
print(25 * "#")
print(f"{time.strftime('%H:%M:%S')} ( i ) : receiving model results: {round((after_received - before_received) / 5, 2)} per second.")
print(f"{time.strftime('%H:%M:%S')} ( i ) : sending frames: {round((after_sent - before_sent) / 1, 2)} per second.")
print(25 * "#")
def send_frame(frame, frame_requests):
global destination, running
try:
frame = cv2.resize(frame, (224, 224))
encoded, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
destination["currentSocket"].send(jpg_as_text)
except Exception as Error:
running = False
def main():
global destination, running, frame_requests
interval = 1 / FPS
while running:
for img in filenames:
frame = cv2.imread(img)
frame_requests += 1
threading.Thread(target=send_frame, args=(frame, frame_requests)).start()
time.sleep(interval)
destination["currentSocket"].close()
if __name__ == "__main__":
threading.Thread(target=handle_endpoint_responses).start()
threading.Thread(target=data_rate).start()
main()
不仅是服务器时间,打开图片也需要时间,使用sleep interval = 1/FPS也可能导致掉帧,即产生的帧数比可能的少(离线播放也是如此)。对于播放,如果完成睡眠,间隔可以更短,并且可以在循环中检查当前时间,如果时间合适 - 发送下一帧,如果不合适 - 等待。延迟也可以是自适应的,并且该时间可能提前于线性周期,以补偿传输延迟,如果目标是服务器端在实际帧时间显示或对图像进行某些操作。
我认为你必须每次 synchronize/measure 客户端和服务器的时钟差异与初始握手或作为交易的一部分,并包括和记录时间sending/receiving 在 transactions/log.
这样你就可以测量传输的一些平均延迟。
另一件可能给出提示的事情是最初播放图像而不发送它们。这将显示 cv2.imread(...) 和预处理需要多少时间。
即commenting/adding 另一个没有目标的函数["currentSocket"].send(jpg_as_text)
我有以下代码,我正在计算每秒从客户端向服务器发送帧所花费的时间,基本上是计算帧丢失率的百分比和响应所花费的时间,并且通信模式是异步的。 现在我在计算这两个指标时遇到了一些问题,为了响应所花费的时间,我将延迟设置为超过 5 秒,因为由于网络和服务器的处理速度,将结果发送回客户端需要时间,因此,延迟更长, 但对于每秒帧数,我需要计算每秒从客户端发送到服务器的帧数,我将如何在 data_rate 方法中计算它。两个指标都需要不同的时间延迟,我不能对两个指标使用相同的时间延迟。非常感谢有关如何在代码中定义它的帮助。
IMAGE_FOLDER = "videoframe"
FPS = 5
SERVER_A_ADDRESS = "tcp://localhost:5555"
ENDPOINT_HANDLER_ADDRESS = "tcp://*:5553"
SERVER_A_TITLE = "SERVER A"
SERVER_B_TITLE = "SERVER B"
context = zmq.Context()
socket_server_a = context.socket(zmq.PUSH)
socket_server_endpoint = context.socket(zmq.PULL)
socket_server_a.connect(SERVER_A_ADDRESS)
socket_server_endpoint.bind(ENDPOINT_HANDLER_ADDRESS)
destination = {
"currentSocket": socket_server_a,
"currentServersTitle": SERVER_A_TITLE,
"currentEndpoint": SERVER_B_TITLE,}
running = True
endpoint_responses = 0
frame_requests = 0
filenames = [f"{IMAGE_FOLDER}/frame{i}.jpg" for i in range(1, 2522)]
def handle_endpoint_responses():
global destination, running, endpoint_responses
while running:
endpoint_response = socket_server_endpoint.recv().decode()
endpoint_responses += 1
def data_rate():
global destination, running, endpoint_responses, frame_requests
while running:
before_received = endpoint_responses ###
time.sleep(5)
after_received = endpoint_responses
before_sent = frame_requests
time.sleep(1)
after_sent = frame_requests ###
print(25 * "#")
print(f"{time.strftime('%H:%M:%S')} ( i ) : receiving model results: {round((after_received - before_received) / 5, 2)} per second.")
print(f"{time.strftime('%H:%M:%S')} ( i ) : sending frames: {round((after_sent - before_sent) / 1, 2)} per second.")
print(25 * "#")
def send_frame(frame, frame_requests):
global destination, running
try:
frame = cv2.resize(frame, (224, 224))
encoded, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
destination["currentSocket"].send(jpg_as_text)
except Exception as Error:
running = False
def main():
global destination, running, frame_requests
interval = 1 / FPS
while running:
for img in filenames:
frame = cv2.imread(img)
frame_requests += 1
threading.Thread(target=send_frame, args=(frame, frame_requests)).start()
time.sleep(interval)
destination["currentSocket"].close()
if __name__ == "__main__":
threading.Thread(target=handle_endpoint_responses).start()
threading.Thread(target=data_rate).start()
main()
不仅是服务器时间,打开图片也需要时间,使用sleep interval = 1/FPS也可能导致掉帧,即产生的帧数比可能的少(离线播放也是如此)。对于播放,如果完成睡眠,间隔可以更短,并且可以在循环中检查当前时间,如果时间合适 - 发送下一帧,如果不合适 - 等待。延迟也可以是自适应的,并且该时间可能提前于线性周期,以补偿传输延迟,如果目标是服务器端在实际帧时间显示或对图像进行某些操作。
我认为你必须每次 synchronize/measure 客户端和服务器的时钟差异与初始握手或作为交易的一部分,并包括和记录时间sending/receiving 在 transactions/log.
这样你就可以测量传输的一些平均延迟。
另一件可能给出提示的事情是最初播放图像而不发送它们。这将显示 cv2.imread(...) 和预处理需要多少时间。
即commenting/adding 另一个没有目标的函数["currentSocket"].send(jpg_as_text)