使用socket发送Iplimage

sending Iplimage using sockets

本文关键字:Iplimage 发送 socket 使用      更新时间:2023-10-16

我试图通过usb从连接到树莓派的罗技术高清摄像头捕获帧,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= %sn",buffer);
         tmpframe->imageData = buffer;
         printf("data %sn",tmpframe->imageData);
         //snprintf(IDbuffer,10,"%d",frame->ID);
         //printf("frame->ID= %sn",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 portn",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 HOSTn");
  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("%sn",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 );
}

但是服务器崩溃了!!a segmentation fault at

cvShowImage( "mywindow", frame );

在没有真正仔细检查代码的情况下,我发现了两个问题:

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