繁体   English   中英

cv2 网络摄像头 stream 仅显示图像的前几行

[英]cv2 webcam stream only showing first few lines of image

嘿,所以我写了一个 Python 脚本到 stream 一个网络摄像头通过 UDP 到另一个设备。 但是当我启动 stream 时,只显示图像的前几行。 即使我使用相同的变量将文件写入磁盘并显示它,我也会得到不同的结果。 因为在保存的图像中颜色是正常的,但在实时图片中颜色是(我认为)反转的。 我已经尝试过的:

  • 在设备之间使用局域网连接
  • 在谷歌上搜索有同样问题的其他人

服务器代码:

import numpy as np
from cv2 import cv2
import socket,json
MESSAGE = [0,0,0]
cap = cv2.VideoCapture(0)
a = 0
class NumpyEncoder(json.JSONEncoder):
    def default(self,obj):
        if isinstance(obj,np.ndarray):
            return obj.tolist()
        return json.JSONEncoder.default(self,obj)
while(True):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow('frame',frame)
    cv2.imwrite("test.jpg",frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    UDP_IP = "192.168.1.147"
    UDP_PORT = 5005
    MESSAGE = json.dumps({"a" : frame[0], "b" : frame[1],"c" : frame[2]}, cls = NumpyEncoder)
    with open("test.txt","w") as f:
        f.write(MESSAGE)
        
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 16384)
    sock = socket.socket(socket.AF_INET, # Internet
                         socket.SOCK_DGRAM) # UDP
    sock.sendto(MESSAGE.encode(),(UDP_IP,UDP_PORT))
# When everything done, release the capture
cap.release()

客户:

import socket,json
from cv2 import cv2
import numpy as np
framecounter = 0
class NumpyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.ndarray):
            return obj.tolist()
        return json.JSONEncoder.default(self, obj)
UDP_IP = "192.168.1.147"
UDP_PORT = 5005

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
    json_dump, addr = sock.recvfrom(65535)
    json_load = json.loads(json_dump.decode())
    new_rgb = np.asarray(json_load["a"]),np.asarray(json_load["b"]),np.asarray(json_load["c"])
    new_rgb = np.float32(new_rgb)
    cv2.imwrite("test.jpg",new_rgb)
    cv2.imshow("frame",new_rgb)
    cv2.resizeWindow("frame",(640,480))
    framecounter = framecounter + 1
    print("frame",framecounter)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.read() 的帧返回值只是 stream 中的一个图像,它是一个大小矩阵(高度、宽度、通道),所以当你执行 frame[0] 时,你只会得到这个的第一行矩阵。 其次,您的编码效率低下,如果您想一次发送一个图像(帧),您可以将图像文件转储到套接字中。

这是我的实现,请注意,由于接收器是单线程的,如果它开始执行缓慢的操作(例如写入磁盘、计算机视觉),它可能会丢失几个数据包。 在这种情况下,您应该创建另一个仅侦听该端口并写入队列的线程。

接收.py

import socket
import cv2
import io
import numpy as np
import traceback

DATAGRAM_SIZE = 1400 #bytes
PORT = 44000
end_bytes = bytes(17)
framecounter = 0

listening_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listening_socket.bind(('', PORT))
while True:
    image_buffer = io.BytesIO() # faster than writing to file
    data, address = listening_socket.recvfrom(DATAGRAM_SIZE)
    while data != end_bytes:
        image_buffer.write(data)
        data, address = listening_socket.recvfrom(DATAGRAM_SIZE)
    image_buffer.seek(0)
    try: # image may be corrupted by loss of UDP packets
        img = cv2.imdecode(np.asarray(bytearray(image_buffer.read()), dtype=np.uint8), cv2.IMREAD_COLOR)
        cv2.imshow("received", img) # If the code gets slow here you may loose packets
    except Exception:
        traceback.print_exc()
    framecounter += 1
    print(framecounter)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

listening_socket.close()

发件人.py

import socket
import cv2
import numpy
import time

DATAGRAM_SIZE = 1400
PORT = 44000
IP = "127.0.0.1"
end_bytes = bytes(17)

cap = cv2.VideoCapture(0)
sending_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while(True):
    ret, frame = cap.read()
    cv2.imshow("sent",frame)
    cv2.imwrite("img_to_send.jpg",frame) # You may use BytesIO
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    with open("img_to_send.jpg", "rb") as f:
        data = f.read(DATAGRAM_SIZE)
        while data:
            sending_socket.sendto(data, (IP, PORT))
            data = f.read(DATAGRAM_SIZE)
        sending_socket.sendto(end_bytes, (IP, PORT))

sending_socket.close()
cap.release()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM