Reputation: 73
I have just started working on a Robot controller,however I haven't got the camera part working. I want to receive webcam stream over tcp from a server, which sends Mat[s], then display this information on the client side.
Either the server sends wrong information, potentially as a result of the cast, or the client interprets this information wrong, also potentially as a result of the cast. Either way I'm not sure how to resolve this issue.
So far my server.cpp looks like this :
#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
using namespace cv;
int main(int argc, char** argv)
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 1111 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
VideoCapture cap;
// open the default camera, use something different from 0 otherwise;
// Check VideoCapture documentation.
if(!cap.open(0))
return 0;
for(;;)
{
Mat frame;
cap >> frame;
if( frame.empty() ) break; // end of video stream
//imshow("Input :)", frame);
write(client_sock,(char *)frame.data,strlen((char *)frame.data));
if( waitKey(1) == 27 ) break; // stop capturing by pressing ESC
}
// the camera will be closed automatically upon exit
// cap.close();
return 0;
}
And my client looks like this :
#include "opencv2/opencv.hpp"
#include <SFML/Network.hpp>
using namespace cv;
int main() {
sf::TcpSocket socket;
sf::Socket::Status status = socket.connect("127.0.0.1", 1111);
if (status != sf::Socket::Done)
{
puts("Bye\n");
return 0;
}
while(true) {
Mat frame;
char data[1000000]; //strlen gave me around 930000 when I was debugging.
std::size_t received;
// TCP socket:
if (socket.receive(data, 1000000, received) != sf::Socket::Done)
{
continue;
}else {
frame.data = (unsigned char *)data;
imshow("Hello",frame); //Error occurs here, not sure what causes it
}
}
}
Error
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui/src/window.cpp, line 269
terminate called after throwing an instance of 'cv::Exception'
what(): /build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui/src/window.cpp:269: error: (-215) size.width>0 && size.height>0 in function imshow
Aborted
Upvotes: 0
Views: 1638
Reputation: 8708
I'm guessing it's because you only send the Mat
's data. A Mat
object contains header, which include, among other, the Mat
size.
I'd suggest at the very least to also transmit the Size
and Type
of the Mat and then using it to create a new Mat
Mat frame(receivedSize, receivedType)
I'm not sure if that's would be enough, but that's a start.
Also, is there a reason you only send the data
instead of (char *)&frame
and then casting it back to Mat
?
Upvotes: 3