我有一个Raspberry Pi使用python模块处理其raspicam中的图像。
为了简化,我将删除图像处理块代码。

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#程序。
我向您展示了从套接字接收字节并将其绑定(bind)到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;
            }
        }
    }

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



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

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

我也欢迎实现此目的的其他方法。

最佳答案

好了,套接字体系结构还可以。
经过测试和测试,我找到了解决方案。

为了将来的访客提出相同的想法:

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

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

而且我错过的明显部分是使用Imdecode本机方法解码数据。
Python代码的结果与我在问题帖子上发布的结果相同,但是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;
        }
    }
}

关于c# - UDP从OpenCv向EmguCv发送帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49906779/

10-10 18:38