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);
分段故障位於服務器而不是客戶端。如何在客戶端上使用臨時緩衝區影響服務器? –
哦,在服務器代碼中沒有看到'cvShowImage'。但是根據你的代碼判斷,'frame-> imageData'可能指向圖像的混亂/損壞表示。而客戶端上的臨時緩衝區仍然是一個問題。 –
看起來,第一個代碼是一個概念證明,我可以將一幀保存到一個緩衝區,然後重建一個新的幀,它是緩衝區中的tmpbuffer(此代碼工作正常),第二個代碼是客戶端代碼,我嘗試發送從Cam中捕獲的幀,第三個代碼是我如何在服務器上接收幀。我不明白如何格式化二進制數據,因爲我是C的新手。 –