我想發送一個OpenCV Mat
通過TCP使用C++從樹莓到我的Windows PC。 我的代碼正在工作,它正在發送和獲取幀,但是這些圖像的灰度和質量都很差。如何發送OpenCV墊通過插座
客戶端(Windows)中:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string.h>
#include <sys/types.h>
#include <winsock2.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include "WS2tcpip.h"
#define bzero(b,len) (memset((b),'\0',(len)),(void)0)
#define bcopy(b1,b2,len) (memmove((b2),(b1),(len)),(void) 0)
using namespace std;
int main()
{
int sockfd, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
// IMPORTANT
WSADATA Data;
WSAStartup(MAKEWORD(2, 2), &Data);
////////////
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
cout << "Error while opening socket"<<endl;
return -1;
}
bzero((char*)&serv_addr,sizeof(serv_addr));
portno = 5001;
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) {
cout << "Error while binding." << endl;
return -1;
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr,&clilen);
if (newsockfd < 0) {
cout << "Error while accepting socket" << endl;
return -1;
}
cv::Mat img;
img = cv::Mat::zeros(480, 640, CV_8UC1);
int imgSize = img.total() * img.elemSize();
uchar *iptr = img.data;
int bytes = 0;
if (!img.isContinuous()) {
img = img.clone();
}
cout << "Img size: " << imgSize << endl;
while (1) {
if ((bytes = recv(newsockfd, (char *)iptr, imgSize, MSG_WAITALL)) == -1) {
cout << "Error while recv frame" << endl;
break;
}
cv::imshow("VIDEO CLIENT", img);
cv::waitKey(30);
}
// IMPORTANT
WSACleanup();
//////////////
return 0;
}
服務器端(樹莓派):
#include <ctime>
#include <iostream>
#include <raspicam/raspicam_cv.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
int main (int argc, char **argv){
int sockfd,portno,n;
struct sockaddr_in serv_addr;
struct hostent *server;
portno=5001;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
cout << "Error while opening socket."<<endl;
return -1;
}else{
cout << "Socket is now openned."<<endl;
}
server = gethostbyname("192.168.1.10");
if(server ==NULL){
cout << "Host does not exist."<<endl;
return -1;
}else{
cout << "Valid host!"<<endl;
}
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){
cout << "Error while trying to connect."<<endl;
return -1;
}
else{
cout << "Connected!"<<endl;
}
raspicam::RaspiCam_Cv cam;
cv::Mat image;
image = cv::Mat::zeros(480,640,CV_8UC1);
if (!image.isContinuous()){
image = image.clone();
}
int imageSize = image.total()*image.elemSize();
int bytes = 0;
cout << "img size: " << imageSize << endl;
cam.set(CV_CAP_PROP_FORMAT,CV_8UC1);
cout << "Opening camera..."<<endl;
if (!cam.open()){
cout << "Error while opening camera." << endl;
return -1;
}
while(1){
cout << "Capturing frame..." << endl;
cam.grab();
cam.retrieve(image);
if(!image.empty()){
if((bytes = send(sockfd,image.data,imageSize,0))<0){
cout << "Error while sending..";
break;
}
cout << "Frame sent sucessfuly" << endl;
cout << bytes << " bytes sent." <<endl;
}else{
cout << "Frame was empty"<<endl;
break;
}
}
cout << "Stopping camera..."<<endl;
cam.release();
return 0;
}
Here你可以看到我的客戶端如何得到的幀。
我不知道是什麼導致了這個問題。 捕獲框架後我是否缺少任何東西?
對cv :: Mat進行序列化可能具有挑戰性。你有沒有考慮用PNG進行編碼,然後通過網線發送並解壓縮PNG? – Xvolks
我不會指望'recv'中的'MSG_WAITALL'。更多閱讀:https://stackoverflow.com/questions/12214356/winsock2-how-to-open-a-tcp-socket-that-allows-recv-with-msg-waitall – user4581301