title: How to send OpenCV Mat throught socket
body: <p>I am trying to send an OpenCV <code>Mat</code> throught TCP using c++ from a raspberry to my Windows PC.
  My code is working and it is sending and getting the frames, however this images are on gray scale and really bad quality.</p>
  
  <p><strong>Client side (Windows):</strong></p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;fstream&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;winsock2.h&gt;
  #include &lt;opencv2/core/core.hpp&gt;
  #include &lt;opencv2/highgui/highgui.hpp&gt;
  #include &lt;iostream&gt;
  #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), &amp;Data);
      ////////////
  
      sockfd = socket(AF_INET, SOCK_STREAM, 0);
      if (sockfd &lt; 0) {
          cout &lt;&lt; "Error while opening socket"&lt;&lt;endl;
          return -1;
      }
  
      bzero((char*)&amp;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 *)&amp;serv_addr, sizeof(serv_addr)) &lt; 0) {
          cout &lt;&lt; "Error while binding." &lt;&lt; endl;
          return -1;
      }
      listen(sockfd, 5);
      clilen = sizeof(cli_addr);
      newsockfd = accept(sockfd, (struct sockaddr *)&amp;cli_addr,&amp;clilen);
  
      if (newsockfd &lt; 0) {
          cout &lt;&lt; "Error while accepting socket" &lt;&lt; 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 &lt;&lt; "Img size: " &lt;&lt; imgSize &lt;&lt; endl;
  
      while (1) {
          if ((bytes = recv(newsockfd, (char *)iptr, imgSize, MSG_WAITALL)) == -1) {
              cout &lt;&lt; "Error while recv frame" &lt;&lt; endl;
              break;
          }
          cv::imshow("VIDEO CLIENT", img);
          cv::waitKey(30);
      }
  
  
      // IMPORTANT
      WSACleanup();
      //////////////
  
      return 0;
  }
  </code></pre>
  
  <p><strong>Server side (Raspberry Pi):</strong></p>
  
  <pre><code>#include &lt;ctime&gt;
  #include &lt;iostream&gt;
  #include &lt;raspicam/raspicam_cv.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;opencv2/imgproc/imgproc.hpp&gt;
  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&lt;0){
    cout &lt;&lt; "Error while opening socket."&lt;&lt;endl;
    return -1;
   }else{
    cout &lt;&lt; "Socket is now openned."&lt;&lt;endl;
   }
   server = gethostbyname("192.168.1.10");
   if(server ==NULL){
    cout &lt;&lt; "Host does not exist."&lt;&lt;endl;
    return -1;
   }else{
    cout &lt;&lt; "Valid host!"&lt;&lt;endl;
   }
  
  
   bzero((char *) &amp;serv_addr,sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   bcopy((char*)server-&gt;h_addr,
          (char *)&amp;serv_addr.sin_addr.s_addr,
          server-&gt;h_length);
   serv_addr.sin_port = htons(portno);
   if (connect(sockfd,(struct sockaddr *) &amp;serv_addr,sizeof(serv_addr))&lt;0){
    cout &lt;&lt; "Error while trying to connect."&lt;&lt;endl;
    return -1;
   }
   else{
    cout &lt;&lt; "Connected!"&lt;&lt;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 &lt;&lt; "img size: " &lt;&lt; imageSize &lt;&lt; endl;
  
   cam.set(CV_CAP_PROP_FORMAT,CV_8UC1);
  
   cout &lt;&lt; "Opening camera..."&lt;&lt;endl;
   if (!cam.open()){
    cout &lt;&lt; "Error while opening camera." &lt;&lt; endl;
    return -1;
   }
  while(1){
   cout &lt;&lt; "Capturing frame..." &lt;&lt; endl;
   cam.grab();
   cam.retrieve(image);
   if(!image.empty()){
     if((bytes = send(sockfd,image.data,imageSize,0))&lt;0){
       cout &lt;&lt; "Error while sending..";
       break;
     }
     cout &lt;&lt; "Frame sent sucessfuly" &lt;&lt; endl;
     cout &lt;&lt; bytes &lt;&lt; " bytes sent." &lt;&lt;endl;
   }else{
    cout &lt;&lt; "Frame was empty"&lt;&lt;endl;
    break;
   }
  }
  cout &lt;&lt; "Stopping camera..."&lt;&lt;endl;
  cam.release();
  return 0;
  }
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/EusrB.jpg" rel="nofollow noreferrer">Here</a> you can see how my client side gets the frames.</p>
  
  <p>I do not know what is causing this problem.
  Am I missing anything after capturing the frame?</p>