2013-01-07 35 views
2

我想從通過USB連接到Raspberry Pi的Logitech高清攝像頭捕獲幀,RP運行arch linux,並且使用OpenCV C api和TCP客戶端。使用套接字發送Iplimage

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); 

這裏是我的客戶。 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); 

回答

2

兩個問題,我沒有看到代碼的真正仔細檢查:

  • 您正在使用printf(3)風格的函數來格式化二進制數據。這是錯誤的TM。結果字符串的長度不會與圖像的長度相同,並且二進制數據可能在中間爲零字節,或者沒有零終止符。
  • 您正在其範圍之外使用臨時緩衝區(char buffer[frame->imageSize]) - 這可能是分段故障的原因。
+0

分段故障位於服務器而不是客戶端。如何在客戶端上使用臨時緩衝區影響服務器? –

+0

哦,在服務器代碼中沒有看到'cvShowImage'。但是根據你的代碼判斷,'frame-> imageData'可能指向圖像的混亂/損壞表示。而客戶端上的臨時緩衝區仍然是一個問題。 –

+0

看起來,第一個代碼是一個概念證明,我可以將一幀保存到一個緩衝區,然後重建一個新的幀,它是緩衝區中的tmpbuffer(此代碼工作正常),第二個代碼是客戶端代碼,我嘗試發送從Cam中捕獲的幀,第三個代碼是我如何在服務器上接收幀。我不明白如何格式化二進制數據,因爲我是C的新手。 –