-1

so i understand the basics of socket programming however what i get when i go to localhost:8888 are unreadable strings instead of video or image frames. i was wondering if anyone had any pointer as to how to display images on my port rather than strings. the code i have is below:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* streamServer(void* arg);
void  quit(char* msg, int retval);

int main(int argc, char** argv)
{
    pthread_t   thread_s;
    int         key;

    if (argc == 2) {
        capture = cvCaptureFromFile(argv[1]);
    } else {
        capture = cvCaptureFromCAM(0);
    }

    if (!capture) {
        quit("cvCapture failed", 1);
    }

    img0 = cvQueryFrame(capture);
    img1 = cvCreateImage(cvGetSize(img0), IPL_DEPTH_8U, 1);

    cvZero(img1);
    cvNamedWindow("stream_server", CV_WINDOW_AUTOSIZE);

    /* print the width and height of the frame, needed by the client */
    fprintf(stdout, "width:  %d\nheight: %d\n\n", img0->width, img0->height);
    fprintf(stdout, "Press 'q' to quit.\n\n");

    /* run the streaming server as a separate thread */
    if (pthread_create(&thread_s, NULL, streamServer, NULL)) {
        quit("pthread_create failed.", 1);
    }

    while(key != 'q') {
        /* get a frame from camera */
        img0 = cvQueryFrame(capture);
        if (!img0) break;

        img0->origin = 0;
        cvFlip(img0, img0, 1); //-1);

        /**
         * convert to grayscale
         * note that the grayscaled image is the image to be sent to the client
         * so we enclose it with pthread_mutex_lock to make it thread safe
         */
        pthread_mutex_lock(&mutex);
        cvCvtColor(img0, img1, CV_BGR2GRAY);
        is_data_ready = 1;
        pthread_mutex_unlock(&mutex);

        /* also display the video here on server */
        cvShowImage("stream_server", img0);
        key = cvWaitKey(30);
    }

    /* user has pressed 'q', terminate the streaming server */
    if (pthread_cancel(thread_s)) {
        quit("pthread_cancel failed.", 1);
    }

    /* free memory */
    cvDestroyWindow("stream_server");
    quit(NULL, 0);
}

/**
 * This is the streaming server, run as a separate thread
 * This function waits for a client to connect, and send the grayscaled images
 */
void* streamServer(void* arg)
{
    struct sockaddr_in server;

    /* make this thread cancellable using pthread_cancel() */
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    /* open socket */
    if ((serversock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        quit("socket() failed", 1);
    }

    /* setup server's IP and port */
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = INADDR_ANY;

    /* bind the socket */
    if (bind(serversock, (const void*)&server, sizeof(server)) == -1) {
        quit("bind() failed", 1);
    }

    /* wait for connection */
    if (listen(serversock, 10) == -1) {
        quit("listen() failed.", 1);
    }

    /* accept a client */
    if ((clientsock = accept(serversock, NULL, NULL)) == -1) {
        quit("accept() failed", 1);
    }

    /* the size of the data to be sent */
    int imgsize = img1->imageSize;
    int bytes, i;

    /* start sending images */
    while(1)
    {
        /* send the grayscaled frame, thread safe */
        pthread_mutex_lock(&mutex);
        if (is_data_ready) {
            bytes = send(clientsock, img1->imageData, imgsize, 0);
            is_data_ready = 0;
        }
        pthread_mutex_unlock(&mutex);

        /* if something went wrong, restart the connection */
        if (bytes != imgsize) {
            fprintf(stderr, "Connection closed.\n");
            close(clientsock);

            if ((clientsock = accept(serversock, NULL, NULL)) == -1) {
                quit("accept() failed", 1);
            }
        }

the whole code: http://pastebin.com/jnuZhx8C

vipw
  • 7,593
  • 4
  • 25
  • 48
DasBoot
  • 707
  • 3
  • 15
  • 37

2 Answers2

1

Unless img1->imageData is in a format the browser is supposed to recognize (png, jpg, gif), unrecognizable text is all you should expect.

CrazyCasta
  • 26,917
  • 4
  • 45
  • 72
  • 1
    how would i be able to do that? should i cast it? if so how? sorry for not doing this correctly but my home connection lags too much so cant google as much. – DasBoot Oct 01 '12 at 22:26
  • I have the same problem,i agree some sample code would be best.+1 – DasBoot Oct 01 '12 at 22:27
  • @user1509326 You're asking a completely different question then, you should either edit or start a new question. The question you are now asking is, how do I convert an IplImage to a standard web image format. – CrazyCasta Oct 01 '12 at 22:31
1

Before we go into the technical details, ask yourself the question: what is standard web image format?

In your opinion, would it be PNG? JPG? TIFF? BMP? GIF? All of these?

An image format like that stores much more than just pixels. If you take a look at the specification of PNG, you'll see that it stores a lot of information about the image besides the pixels.

The problem is that when you send just the pixels over the network, like you are doing now, whoever is receiving the data on the other side of the connection can't do anything useful with it because it doesn't even know what's the dimension of the image.

The other misconception we need to clear is: there's no such thing as display images on my port rather than strings. What is a port?

Transferring data across networks is one thing. Doing something useful with the data (like displaying it on the screen) on the other side of the connection is an entirely different task.

If you need a practical example on how to accomplish these tasks, I suggest you take a look at this awesome tutorial: Streaming OpenCV Videos Over the Network. I just noticed that the code from your question came from there, so pay extra attention to section 4. Implementation of the Client-side.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • yes, but i am trying to access my video through the web browser not a specific client. so i need to use stream_server.c only not client. isnt this just casting iplimage to something that is understood by the browser? – DasBoot Oct 02 '12 at 22:06
  • No, it isn't. The simplest way would be to recreate the PNG file on the disk and tell the browser to open it. – karlphillip Oct 02 '12 at 22:12
  • but then how would someone else be able to access through the ip and port? thank you for helping me +1 – DasBoot Oct 02 '12 at 22:17
  • does opencv have a method for encoding the frames? so that the browser can understand it? – DasBoot Oct 02 '12 at 22:34