简体   繁体   中英

Loading an image from a URL into a variable/opencv Mat

bool loadImage(string inputName, Mat &image)
{
  bool from_net = true;

  if (inputName.find("http") != string::npos)
    {
      string URL = inputName;
      if (inputName.find("\"") == 0)
        {
          URL = inputName.substr(1,inputName.length()-2);
        }
      ofstream myfile;
      myfile.open ("test.jpg");
      //  Create a writer to handle the stream

      curl_writer writer(myfile);
      // Pass it to the easy constructor and watch the content returned in that file!
      curl_easy easy(writer);

      // Add some option to the easy handle
      easy.add(curl_pair<CURLoption,string>(CURLOPT_URL,URL));
      easy.add(curl_pair<CURLoption,long>(CURLOPT_FOLLOWLOCATION,1L));
      try {
        easy.perform();
      } catch (curl_easy_exception error) {
        // If you want to get the entire error stack we can do:
        vector<pair<string,string>> errors = error.what();
        // Otherwise we could print the stack like this:
        //error.print_traceback();
      }
      myfile.close();

      string inputname = "test.jpg";
      image = imread(inputname,1);

      if(image.rows == 0 || image.cols == 0)
          from_net = false;
    }  
  else
    {
      image = imread( inputName, 1 );
      if (image.total() < 1)         
          from_net = false;

    }
  return from_net; 
}

And this works fine for my application, if I change test.txt to test.jpg . However, my application demands that I avoid the overhead of creating the file, reading, writing and closing it. Is there an easy and direct way to get the image data from the URL and write it to an openCV Mat ?

I also tried the 3rd example in the above link. But for some reason when I do a receiver.get_buffer() , the image remains empty. I get image dimensions as 0X0 .

Any help related to this is really appreciated. I have never used curlcpp before and so, any detailed explanation for the same would be much appreciated.

Thanks.

There is a simple solution to this, my bad for not noticing this earlier. You can write the data to ostringstream. Please see the code below for details.

bool loadImage(string inputName, Mat &image)
{
  bool from_net;
  from_net = true;


  if (inputName.find("http") != string::npos)
    {
      string URL;
      URL = inputName;
      if (inputName.find("\"") == 0)
        {
           URL = inputName.substr(1,inputName.length()-2);
        }

  std::ostringstream stream;

  curl_writer writer(stream);
  // Pass it to the easy constructor and watch the content returned in that file!
  curl_easy easy(writer);

  // Add some option to the easy handle
  easy.add(curl_pair<CURLoption,string>(CURLOPT_URL,URL));
  easy.add(curl_pair<CURLoption,long>(CURLOPT_FOLLOWLOCATION,1L));

  try {
    easy.perform();
  } catch (curl_easy_exception error) {
    // If you want to get the entire error stack we can do:
    vector<pair<string,string>> errors = error.what();
    // Otherwise we could print the stack like this:
    error.print_traceback();
  }
  string output = stream.str(); // convert the stream into a string
  if (output.find("404 Not Found") != string::npos)
    from_net = false;
  else
  {
      vector<char> data = std::vector<char>( output.begin(), output.end() ); //convert string into a vector 
  if (data.size() > 0)
    {
      Mat data_mat = Mat(data); // create the cv::Mat datatype from the vector
      image = imdecode(data_mat,-1); //read an image from memory buffer
      if(image.rows == 0 || image.cols == 0)
    from_net = false;
    }
  else
    from_net = false;
    }
}
  else
    {
      image = imread( inputName, 1 );
      if (image.total() < 1)         
        from_net = false;   
    }
  return from_net;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM