我正在尝试使用OpenCV和套接字实现流媒体服务.服务器端加载给定的图像并将其发送到客户端,客户端通过套接字接收它并显示它.但是,我遇到了很多麻烦,发送图像数据并在客户端重建它.这是我到目前为止所做的代码:
图片发件人:
#include#include #include #include #include #include #include #include #include #include #include using namespace cv; using namespace std; void error(const char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname 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,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); Mat image; image = imread(argv[3], CV_LOAD_IMAGE_COLOR); if(! image.data ) // Check for invalid input { cout << "Could not open or find the image" << std::endl ; return -1; } n = write(sockfd,image.data,image.total()*image.channels()); if (n < 0) error("ERROR writing to socket"); close(sockfd); namedWindow( "Client", CV_WINDOW_AUTOSIZE );// Create a window for display. imshow( "Client", image ); waitKey(0); return 0; }
图像接收器:
#include#include #include #include #include #include #include #include #include #include #include using namespace cv; using namespace std; void error(const char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { int sockfd, newsockfd, portno; socklen_t clilen; char buffer[1024]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,1024); n = read(newsockfd,buffer,1023); if (n < 0) error("ERROR reading from socket"); Mat image(690,690,CV_8UC3,*buffer); imwrite("/home/securitas/images/prova.jpg",image); close(newsockfd); close(sockfd); namedWindow( "Server", CV_WINDOW_AUTOSIZE );// Create a window for display. imshow( "Server", image ); waitKey(0); return 0; }
我在客户端收到的是黑色图像,没有别的.有帮助吗?
获取Mat.data
并直接发送到套接字,数据顺序是BGR BGR BGR ....在接收方假设您知道图像的大小.接收后只需将接收到的缓冲区(BGR BGR ...数组)分配给a Mat
.
客户:-
Mat frame; frame = (frame.reshape(0,1)); // to make it continuous int imgSize = frame.total()*frame.elemSize(); // Send data here bytes = send(clientSock, frame.data, imgSize, 0))
服务器:-
Mat img = Mat::zeros( height,width, CV_8UC3); int imgSize = img.total()*img.elemSize(); uchar sockData[imgSize]; //Receive data here for (int i = 0; i < imgSize; i += bytes) { if ((bytes = recv(connectSock, sockData +i, imgSize - i, 0)) == -1) { quit("recv failed", 1); } } // Assign pixel value to img int ptr=0; for (int i = 0; i < img.rows; i++) { for (int j = 0; j < img.cols; j++) { img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+ 0],sockData[ptr+1],sockData[ptr+2]); ptr=ptr+3; } }