-1

ソケットプログラミングの基本は理解していますが、localhost:8888 にアクセスすると、ビデオや画像フレームではなく読み取り不能な文字列が表示されます。ポートに文字列ではなく画像を表示する方法について誰かが何かポインタを持っているかどうか疑問に思っていました。私が持っているコードは以下です:

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);
            }
        }

コード全体: http://pastebin.com/jnuZhx8C

4

2 に答える 2

1

img1->imageData が、ブラウザーが認識できる形式 (png、jpg、gif) でない限り、認識できないテキストが表示されるだけです。

于 2012-10-01T22:21:31.967 に答える
1

技術的な詳細に入る前に、次の質問を自問してくださいstandard web image format

あなたの意見では、それはPNGでしょうか?JPG? ティフ?BMP? GIF?これらすべて?

そのような画像形式は、単なるピクセル以上のものを保存しますPNGの仕様を見ると、ピクセル以外にも画像に関する多くの情報が格納されていることがわかります。

問題は、ネットワーク経由でピクセルのみを送信する場合、現在行っているように、接続の反対側でデータを受信して​​いる人は、次元が何であるかさえ知らないため、データを使用して何も役に立たないことです。画像の。

私たちがクリアしなければならないもう 1 つの誤解は、.などというものは存在しないということdisplay images on my port rather than stringsです。ポートとは

ネットワークを介してデータを転送することは 1 つのことです。接続の反対側で (画面に表示するなど) データを処理するのは、まったく別のタスクです。

これらのタスクを達成する方法に関する実用的な例が必要な場合は、この素晴らしいチュートリアルをご覧になることをお勧めします: Streaming OpenCV Videos Over the Network . あなたの質問のコードがそこから来ていることに気付いたので、セクションに特に注意して 4. Implementation of the Client-sideください。

于 2012-10-02T15:07:33.793 に答える