UDP 将帧从 OpenCv 发送到 EmguCv

UDP Sending frames from OpenCv to EmguCv

我有一个 Raspberry Pi 处理来自其 raspicam 的带有 Python 模块的图像。 为了简化,我删除了图像处理块代码。

from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
from socket import *
import socket
import numpy as np
import sys

class Cam():
    def __init__(self,ip,port):
        self._s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        self._address = (ip,port)
        self._quality=[int(cv2.IMWRITE_JPEG_QUALITY),80]


    def run(self):
        self._cam= PiCamera()
        self._cam.resolution = (640, 480)
        self._cam.framerate = 32
        self._capturer = PiRGBArray(self._cam, size=(640, 480))
        time.sleep(2)

        for frame in self._cam.capture_continuous(self._capturer, format="bgr", use_video_port=True):
            try:
                image = frame.array

                # processing

                result, imgencode = cv2.imencode('.jpg', image, self._quality)
                data = np.array(imgencode)

                stringData = data.tostring()
                self._s.sendto(stringData,self._address)
                self._capturer.truncate(0)

            except KeyboardInterrupt:
                self._cam.close()
                break

之后,树莓派通过数据报套接字 (udp) 将图像发送到我在 PC 上托管的 C# 程序。 我向您展示了从套接字接收字节并将它们绑定到 EmguCv Image :

的方法
    private void ReadFrame()
    {
        using (UdpClient socket = new UdpClient(this.camPort))
        {
            try
            {

                while (!end)
                {
                    var remoteEP = new IPEndPoint(IPAddress.Any, this.camPort);
                    byte[] data = socket.Receive(ref remoteEP);

                    this.Frame = new Image<Bgr, byte>(640,480);
                    // Until here it works, and data is correctly received

                    this.Frame.Bytes = data;

                }
            }
            catch (SocketException)
            {
                throw;
            }
        }
    }

它一直有效,直到我尝试将字节数组绑定到 EmguCv Image 对象。 在那条线上我得到:

An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in Emgu.CV.World.dll

因为 data 长度低于 Frame.Bytes 的预期长度。

我应该如何从字节构建 EmguCv 图像?

我也愿意接受其他方法来实现这一目标。

好吧,套接字架构还不错。 试了又试,找到了解决办法

为了未来的访问者提出相同的想法:

不要使用 EmguCv 的 Image 对象。您最好使用 Opencv 本机 Mat 对象。就我而言,我将其实例化为:

this.Mat = new Mat(new Size(640, 480), Emgu.CV.CvEnum.DepthType.Cv8U, 3);

还有我遗漏的明显部分,使用 Imdecode 本机方法解码数据。 Python 代码的结果与我 post 在问题 post 上编辑的结果相同,但 C# 方法会导致以下结果:

private void ReadFrame()
{
    using (UdpClient socket = new UdpClient(this.camPort))
    {
        try
        {
            while (!end)
            {
                var remoteEP = new IPEndPoint(IPAddress.Any, this.camPort);
                byte[] data = socket.Receive(ref remoteEP);
                Emgu.CV.CvInvoke.Imdecode(data, Emgu.CV.CvEnum.ImreadModes.ReducedColor8, this.Mat);
            }
        }
        catch (SocketException)
        {
            throw;
        }
    }
}