c++ - How to send OpenCV Mat throught socket -


i trying send opencv mat throught tcp using c++ raspberry windows pc. code working , sending , getting frames, images on gray scale , bad quality.

client side (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; } 

server side (raspberry pi):

#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 openned."<<endl;  }  server = gethostbyname("192.168.1.10");  if(server ==null){   cout << "host 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 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 empty"<<endl;   break;  } } cout << "stopping camera..."<<endl; cam.release(); return 0; } 

here can see how client side gets frames.

i not know causing problem. missing after capturing frame?

i wouldn't recommend sending cv::mat bewtween computers - computers different cpu architecture, byte ordering, word length , memory padding.

convert image non-compressed (or losslessly compressed) format such png , send that.

you can use cv::encode / cv:: decode create image format in memory without having read/write temp file.

note: imdecode determines image type data inside image format (png, jpeg etc) header. receiver doesn't need know size or type.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -