I am trying to send an OpenCV Mat 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.
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 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 you can see how my client side gets the frames.
I do not know what is causing this problem. Am I missing anything after capturing the frame?