【问题标题】:sending Iplimage using sockets使用套接字发送 Iplimage
【发布时间】:2012-12-21 11:00:26
【问题描述】:

我正在尝试从通过 USB 连接到 Raspberry Pi 的 Logitech HD cam 捕获帧,RP 正在运行 arch linux,我正在使用 OpenCV C api 和 TCP 客户端。

TCP服务器在ubuntu下运行c++(QT)。

我将 frame->imageData 存储在缓冲区中,然后将数据发送到缓冲区中。

这是一个概念证明,我可以将帧保存到缓冲区,然后从缓冲区重建一个新帧,即 tmpbuffer,实际上这段代码运行良好:

CvCapture *capture = cvCaptureFromCAM(1);
cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
    int i =1;

   while ( 1 ) {
     // Get one frame
     IplImage* frame = cvQueryFrame( capture );
     CvSize size;
     size.height = 480;
  size.width = 640;
     IplImage* tmpframe = cvCreateImageHeader(size, IPL_DEPTH_8U, 3); //create a new frame
     if ( !frame ) {
       //fprintf( stderr, "ERROR: frame is null...\n" );
       getchar();
       break;
     }else
     {
         //std::cout<<i<<std::endl;
         char buffer[frame->imageSize];
         snprintf(buffer,frame->imageSize,"%s",frame->imageData);
         //printf("frame->height= %s\n",buffer);

         tmpframe->imageData = buffer;
         printf("data %s\n",tmpframe->imageData);

         //snprintf(IDbuffer,10,"%d",frame->ID);
         //printf("frame->ID= %s\n",IDbuffer);
         i++;
     }
     cvShowImage( "mywindow", tmpframe );

这是我的 client.c 文件:

#include <opencv/cv.h>
 #include <opencv/highgui.h>
 #include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


void error(char *msg)
{
 perror(msg);
 exit(0);
}

int main(int argc,char *argv[])
{

int sockfd,portno,n;
 struct sockaddr_in serv_addr;
 struct hostent *server;


 if(argc <3)
 {
  fprintf(stderr,"usage %s hostname portname port\n",argv[0]);
  exit(0);
 }

 portno = atoi(argv[2]);
 sockfd = socket(AF_INET , SOCK_STREAM,0);

 if(sockfd < 0)
 {
  error("ERROR OPENING SOCKET");
 }

 server = gethostbyname(argv[1]);
 if(server == NULL)
 {
  fprintf(stderr,"ERROR,NO SUCH HOST\n");
  exit(0);
 }

 bzero((char*)&serv_addr,sizeof(serv_addr));
 serv_addr.sin_family = AF_INET;

 bcopy((char*)server->h_addr,(char*)&serv_addr.sin_addr.s_addr,server->h_length);
 serv_addr.sin_port = htons(portno);

 if(connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)
 {
  error("ERROR CONNECTING");
 }
    CvCapture *capture = cvCaptureFromCAM(1);
       // Show the image captured from the camera in the window and repeat
        int i =1;

       while ( 1 ) {
         // Get one frame
         IplImage* frame = cvQueryFrame( capture );
         if ( !frame ) {
           //fprintf( stderr, "ERROR: frame is null...\n" );
           getchar();
           break;
         }else
         {
             i++;
         }

         char *msg = frame->imageData;
         char buffer[frame->imageSize];
         bzero (buffer,frame->imageSize);
         snprintf(buffer,frame->imageSize,"%s",msg);
 n=write(sockfd,buffer,frame->imageSize);
 if(n <0)
 {
  error("ERROR READING FROM SOCKET");
 }
 //printf("%s\n",buffer);


 }
return 0;
}

这就是我在服务器上接收数据的方式:

void HostConnector::readyRead()
{
    QByteArray Data = socket->readAll();

    CvSize size;
    size.height = 480;
    size.width = 640;
    IplImage *frame = cvCreateImageHeader(size, IPL_DEPTH_8U, 3);


    frame->imageData = Data.data();
    cvShowImage( "mywindow", frame );

}

但是服务器崩溃了!! 一个segmentation fault

cvShowImage( "mywindow", frame );

【问题讨论】:

    标签: c++ c qt sockets opencv


    【解决方案1】:

    我没有仔细检查代码就看到了两个问题:

    • 您正在使用printf(3) 风格的函数来格式化二进制数据。这是错误的TM。结果字符串的长度与图像的长度不同,二进制数据的中间可能有零字节,或者没有零终止符。
    • 您正在使用超出其范围的临时缓冲区 (char buffer[frame-&gt;imageSize]) - 这可能是分段错误的原因。

    【讨论】:

    • 分段错误在服务器而不是客户端。在客户端使用临时缓冲区如何影响服务器??
    • 哦,在服务器代码中没有看到cvShowImage。但从您的代码来看,frame-&gt;imageData 可能指向图像的混乱/损坏表示。而且客户端上的临时缓冲区仍然是个问题。
    • 看,第一个代码是概念证明,我可以将帧保存到缓冲区,然后从缓冲区重建一个新帧,即 tmpbuffer(此代码工作正常),第二个代码是我试图发送从 Cam 捕获的帧的客户端代码,第三个代码是我如何在服务器上接收帧。我不明白如何格式化二进制数据,因为我是 C 新手。
    • 您不需要格式化二进制数据。如果 imgData 是一个连续的字节数组,则直接将其发送到套接字。您无需将其复制到其他缓冲区。
    • 您确认收到的数据量与您发送的数据量相同吗?就目前而言,您的接收代码需要为 640x480 图像提供足够的数据。如果你没有收到那么多数据,cvShowImage 会离开你给它的缓冲区的末端,然后繁荣!段错误。
    猜你喜欢
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 2012-12-20
    • 2021-11-19
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多