UDP从OpenCv发送帧到EmguCv

时间:2018-04-18 18:37:07

标签: c# python-2.7 opencv udp 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对象时才有效。 在那一行,我得到:

  

未处理的类型&#39; System.ArgumentOutOfRangeException&#39;发生在Emgu.CV.World.dll

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

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

我也愿意接触其他方法。

1 个答案:

答案 0 :(得分:0)

好吧,socket架构还可以。 经过测试和测试,我找到了解决方案。

为了未来的访客提出同样的想法:

不要使用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;
        }
    }
}