3

I have an image processing application that uses Qt and openCV.

for each frame, I should send the captured cv::Mat image object to the server to process it and get the results.

I should use the REST architecture for its low playload.

What is the tool that I should use to send cv::Mat to the server.

I am using POCO for portability.

I seek for the lightest solution to do that, I need a minimum speed of 10 frames processed by the server in a second.

I mean, is there a method to pass the C++ Object to the server without an explicit serialization?

ProEns08
  • 1,856
  • 2
  • 22
  • 38
  • 1
    1) Serialize the image to a string (easily done with `imencode` and eventually base64 encoding), 2) send the string via REST 3) on server decode the image (base64 decoding and `imdecode`) 4) now you have your image server-side. – Miki Apr 21 '16 at 13:56
  • Thanks, why you did not put it as an answer? The problem is that I am still a beginner in POCO and searching to have a complete example in POCO sending a cv::Mat. – ProEns08 Apr 21 '16 at 14:05
  • Because a complete answer will be too broad (as the question ;D). I was just giving you some pointers. You can easily find a lot of info for each step – Miki Apr 21 '16 at 14:08
  • Yes, your points are very informative. – ProEns08 Apr 21 '16 at 14:15
  • @Miki for you're suggestion it's working but 1) Frames per second will decreased to 5FPS. we will send data like object(ex :- {"photo": "Image data interms of bytes" }) and at receiver side it's easy to recover back 2)If I send after imencode data as string it's like 20FPS. but data like string. 3) I want to nearly 30 FPS how it possible. – Amarnath Reddy Surapureddy Sep 10 '22 at 08:52

1 Answers1

2

EDIT

With the POCO library, you can take a look in this answer: HttpRequest PUT content in poco library. He is sending a file on a ifstream.

In this answer you can check how to convert a cv::Mat into a istream: OpenCV cv::Mat to std::ifstream for base64 encoding.

And finally, Thanks to polymorphism, the istream is implicity converted to a ifstream.


You can use the C++ Rest SDK. A code example of the PUT command.

Source of code

Library Github where you can find the full documentation.

#include <http_client.h>
#include <filestream.h>
#include <iostream>
#include <sstream>

using namespace web::http;
using namespace web::http::client;

// Upload a file to an HTTP server.
pplx::task<void> UploadFileToHttpServerAsync()
{
    using concurrency::streams::file_stream;
    using concurrency::streams::basic_istream;

    // To run this example, you must have a file named myfile.txt in the current folder. 
    // Alternatively, you can use the following code to create a stream from a text string. 
    // std::string s("abcdefg");
    // auto ss = concurrency::streams::stringstream::open_istream(s); 

    // Open stream to file. 
    return file_stream<unsigned char>::open_istream(L"myfile.txt").then([](pplx::task<basic_istream<unsigned char>> previousTask)
    {
        try
        {
            auto fileStream = previousTask.get();

            // Make HTTP request with the file stream as the body.
            http_client client(L"http://www.fourthcoffee.com");
            return client.request(methods::PUT, L"myfile", fileStream).then([fileStream](pplx::task<http_response> previousTask)
            {
                fileStream.close();

                std::wostringstream ss;
                try
                {
                    auto response = previousTask.get();
                    ss << L"Server returned returned status code " << response.status_code() << L"." << std::endl;
                }
                catch (const http_exception& e)
                {
                    ss << e.what() << std::endl;
                }
                std::wcout << ss.str();
            });
        }
        catch (const std::system_error& e)
        {
            std::wostringstream ss;
            ss << e.what() << std::endl;
            std::wcout << ss.str();

            // Return an empty task. 
            return pplx::task_from_result();
        }
    });

    /* Sample output:
    The request must be resent
    */
}
Community
  • 1
  • 1
Will Glück
  • 1,242
  • 12
  • 17
  • Thanks a lot, +1.but I am using POCO for portability as I edited. – ProEns08 Apr 21 '16 at 14:00
  • I edited my answer, looks that the linked answer have what you need. Hope it helps. – Will Glück Apr 21 '16 at 14:05
  • Thanks, but in the example he is sending a file. I search to send a cv::Mat or a pure C++ object in a general. – ProEns08 Apr 21 '16 at 14:14
  • Do you really need to pass the value direct from memory? One option is to save the image to a file using the `cv::imwrite` command. – Will Glück Apr 21 '16 at 14:15
  • 1
    This a solution. but this will make the application heavier. I should process at a minimal speed of 10 frame/ second. I search to know how to serialize the object from the client part and to be able to read it form the sever part. – ProEns08 Apr 21 '16 at 14:18
  • Check my answer again, I edited. Now you can check how to transform you Mat into a ifstream and then passe it to the `copyStream` method from POCO. – Will Glück Apr 21 '16 at 14:27
  • Yes, thanks a lot for your answer. But, I am searching for a solution that is less CPU consuming. – ProEns08 Apr 21 '16 at 14:30
  • @ProEns08 you got the answer for this sending 10FPS using Poco – Amarnath Reddy Surapureddy Sep 10 '22 at 08:45