opencv-webcam流不能接收到另一个进程通过命名的fifo - opencv-webcam stream cannot be received by another process via named fifo

- 此内容更新于:2015-12-20
主题:

你好我想模拟一个客户机-服务器程序。都是独立的过程。客户端监听图像数据(mat.data)写在一个名叫fifo由服务器(从摄像头读取图像帧和写它们namedfifo)我的服务器端和客户端工作完美,如果我在客户端创建一个简单的垫对象,把它写在fifo,读它在服务器并重新创建它在服务器端。然而,当我试着写一个连续流的帧从摄像头,服务器为核心转储,分割的错。服务器端代码如下所示。writefifo函数如下客户端是我知道有错误的服务器程序的指针。但是我不能算出。请告诉我如果有一些指针相关的问题或其他的代码中不允许客户端接收帧的连续流。谢谢。update1发布这个问题之后,我意识到我应该写阅读的极限循环(服务器)j<=(buflen1)而不是<=(buflen-1+k)。这个删除分割错误,但我得到的是一个损坏的冻结帧而不是一个连续流和窗口在一段时间后停止响应。所以,现在我的问题是我怎么得到一个连续流?更新2后将关闭系统调用在服务器代码循环外,现在我得到一个连续流但它是模糊和帧出现压扁。仍然没有一个完美的流。

原文:

Hi i am trying to simulate a client-server program.Both are independent processes.The client listens for image data(mat.data) written on a named fifo by the server (which reads image frames from a webcam and writes them one by one on the namedfifo) My server and client sides work perfectly, if I create a simple mat object on the client side ,write it on the fifo,read it on the server and recreate it on the server side.However, when I try to write a continuous stream of frames from webcam, the server gives core-dump, segmentation fault.

The server side code is shown below.

     #include <stdio.h>
     #include <opencv2/opencv.hpp>
     #include <opencv2/core/core.hpp>
     #include <iostream>
     #include <stdlib.h>
     #include <sys/types.h>
     #include <sys/stat.h>
     #include <fcntl.h>
     #include <unistd.h>
     int main(int, char**)
     {
      VideoCapture cap(0); // open the default camera
      if(!cap.isOpened())  // check if we succeeded
       return -1;

      int check;
      int fd;
      int totalbytes;
      int buflen;

      fd = open("/home/vidfifo",O_WRONLY|O_NONBLOCK);

      for(;;)
      {
        Mat frame;
        cap >> frame; // get a new frame from camera

        int  totalbytes = frame.total()*frame.elemSize();
        int buflen = frame.cols*3;

        check = writefifo(frame.data,totalbytes,buflen,fd);

        if (check == 1)
        {
          cout<<"write successful"<<endl;
          imshow("frames1", frame);
          if(waitKey(30) >= 0) break;
        }
        else
        {
          break;
        }
    }
       close(fd);
       return 0;
    }

the writefifo function is as follows

    int writefifo(uchar *framepointer,int totalbytes,int buflen,int fd)
    {
      uchar* buf;
      buf = framepointer;
      int num = totalbytes/buflen;
      for(int i = 1;i<=num;i++)
      {
        write(fd,buf,buflen);
        buf = buf + buflen;
      }
      return 1;
     }

the client side is

    #include <stdio.h>
    #include <opencv2/opencv.hpp>
    #include <opencv2/core/core.hpp>
    #include <iostream>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    int main( int argc, char** argv )
    {
      //I found these by running the server program beforehand          
      int rows = 480;
      int cols = 640;
      int nchan = 3;
      int totalbytes = 921600;//rows*cols*nchan
      int buflen = 1920;//cols*nchan

      while(1)
      {
         Mat img(rows,cols,CV_8UC3);
         uchar buf[buflen];
         uchar datarray[totalbytes];

         int fd1 = open("/home/vidfifo",O_RDONLY);
         int j;
         int k = 0;
         int num = totalbytes/buflen;//=num of rows

         for(int i = 1;i<=num;i++)
         {
           read(fd1,buf,buflen);
           for ( j = 0 ; j<= (buflen-1);j++ ) //originally wrote this as j<= (buflen-1+k)--see update1 at the end of post
           {
              datarray[j+k] = buf[j];

           }
              k = k+buflen;
           }

           img.data = datarray;
           imshow("framesrec", img);
           if(waitKey(30) >= 0) break;
     }
            return 0;
     }

I know there's something wrong with a pointer in the server program.But I can't figure out what. Please tell me if there is some pointer related issue or something else in the code that does not allow the client to receive a continuous stream of frames. Thanks.

update1 after posting this question, I realized I should have written the limit of the read loop( in server) as j<=(buflen -1) instead of j<=(buflen-1+k).This removed the segmentation error, but all I get is a corrupted frozen frame instead of a continuous stream and the window stops responding after some time.So, now my question is How do I get a continuous stream?

update2 after putting the close system call outside loop in the server code, i now get a continuous stream but it is blurred and frames appear squashed.Still not a perfect stream.

网友:确保你打开设备之前循环并关闭之后。至少第一个例子有这样错误的关闭文件循环。并使其适当的缩进/格式化。其余的我不确定。

(原文:Make sure you open the device before the loop and close after. At least the first example has such error of closing the file in the loop. And make it properly indented / formatted. The rest I am not sure of.)

网友:是的,帮助流但它是模糊的

(原文:yea that helps with the stream but it is blurry)