Send image from OpenCV 3 to Cognitive Face API using C ++ REST SDK

I want to use Microsoft Face API from a C ++ application. Cpprest sdk allows me to send image url or image binary data. The problem is my image is not a file on disk, but a cv :: Mat in memory. I'm trying to serialize it using a string stream, but the request method is complaining because it only accepts some strings and an istream.

The following code is fine when opening an image from a file:

file_stream<unsigned char>::open_istream(filename)
 .then([=](pplx::task<basic_istream<unsigned char>> previousTask)
 {
    try
    {
       auto fileStream = previousTask.get();

       auto client = http_client{U("https://api.projectoxford.ai/face/v0/detections")};

       auto query = uri_builder()
          .append_query(U("analyzesFaceLandmarks"), analyzesFaceLandmarks ? "true" : "false")
          .append_query(U("analyzesAge"), analyzesAge ? "true" : "false")
          .append_query(U("analyzesGender"), analyzesGender ? "true" : "false")
          .append_query(U("analyzesHeadPose"), analyzesHeadPose ? "true" : "false")
          .append_query(U("subscription-key"), subscriptionKey)
          .to_string();

       client
          .request(methods::POST, query, fileStream)
   ...
    }
}

      

Here file_stream is used to open a file. I've tried serializing my Mat like this:

    // img is the cv::Mat
    std::vector<uchar> buff;
    cv::imencode(".jpg", img, buff);
    std::stringstream ssbuff;
    copy(buff.begin(), buff.end(), std::ostream_iterator<unsigned char>(ssbuff,""));

      

This serialization works the way I can decode if after and rebuild the image.

¿How can I send opencv Mat image to server via client?

+3


source to share


1 answer


This question here (the best way to load uint8_t array into azure blob storage with wastorage in C ++ ) will lead me to the final answer.

The request method for the client asks for a concurrency :: streams :: istream object when submitting raw data (see docs here: https://microsoft.github.io/cpprestsdk/classweb_1_1http_1_1client_1_1http__client.html#a5195fd9b36b8807456 a string containing byc5195fd9b36b8807456 string3) should be passed to a bytestream object provided by the SDK and open it with an istream object (also provided by the SDK).



concurrency::streams::bytestream byteStream = 
concurrency::streams::bytestream();
concurrency::streams::istream inputStream = 
byteStream.open_istream(ssbuff.str());
auto fileStream = inputStream;
// Build uri and so on ...
client.request(methods::POST, query, fileStream)
// async processing ...

      

The request type is not needed to be explicit as it defaults to "application / octet-stream" according to the docs.

0


source







All Articles