OpenCV 网络url图像路径转OpenCV Mat

一、简述

OpenCV中imread() 读取图像函数是不可以载入图像的网络url路径的,如果想要将网络url图像加载并转成mat数据格式,那么还需要借助第三方网络库curl。

二、环境

windows 10 + vs2017 + opencv3.4.7 + curl-7.78.0 + cmake

三、安装curl

1、curl简介

libcurl是免费的客户端URL传输库,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP。libcurl支持SSL证书, HTTP POST、HTTP PUT、FTP上传、基于HTTP表单的上传、代理、Cookie、用户+口令认证(基本、摘要、NTLM、协商、Kerberos)、文件续传、HTTP代理隧道等!

libcurl是高度可移植的,它构建和工作在许多平台上,包括Solaris、NETBSD、FreeBSD、OpenBSD、Darwin、HPUX、IIX、AIX、TUR64、Linux、UNIX、HUD、Windows、AMIGA、OS/2、BeOs、Mac OS X、ULTRIX、QNX、OpenVMS、RISC OS、Novell NETWORD、DOS等等。

libcurl是免费的,线程安全,IpV6兼容,功能丰富,良好支撑,快速,文档全面,并已被许多知名的,大的和成功的公司使用。

2、在curl官方中下载curl库

官方地址:https://curl.se/download.html

 

3、编译

有多种编译方式,比如:vs 自带的 nmake 编译、cmake编译。我这里选择的是cmake编译。

(1)解压curl-7.78.0.zip,进入目录中,并创建目录build,用于存放编译后的文件;创建install目录用于存放最终编译生成的头文件、dll、lib文件。

 

(2)打开cmake,源码目录选择解压后的curl-7.78.0目录,编译目录选择刚刚创建的build目录。点击“Configure”按钮,选择vs2017 、x64,配置成功。

 (3)CMAKE_INSTALL_PREFIX选项,参数修改为刚刚创建的install目录,用于存放生成的头文件、库文件;

(4)再次点击“Configure”按钮,再点击“Generate”按钮,生成成功。

(5)在build目录中找到 CURL.sln,用vs2017打开【注意:一定要用管理员身份运行vs2017,不然生成库时会报错】,选择Debug/Release x64,这里我选择的是Release x64。

4、依次对项目“ALL_BUILD”、“INSTALL”生成

 

5、全部生成成功后,在install目录中看到生成的头文件、dll文件和lib文件

 

6、我们只需要install这一个目录即可,其他的所有文件都可以删除了。我这里把install目录单独拷贝出来,修改了名称

 

7、根据需求,自行在windows环境变量Path中添加curl的bin路径;【添加到系统环境变量中后就不需要把dll文件拷贝到项目运行目录下了】

四、网络url图像路径转Mat

1、配置

(1)在vs2017中,右击项目进入属性页;

(2)在“配置属性”->“C/C++”->“常规”->“附加包含目录”中添加curl的include目录;

(3)在“配置属性”->“链接器”->“常规”->“附加库目录”中添加curl的lib目录;

(4)在“配置属性”->“链接器”->“常规”->“输入”->“附加依赖项”中添加libcurl_imp.lib(Release模式)或libcurl-d_imp.lib(Debug模式)。

2、使用

这里参考链接:https://answers.opencv.org/question/91344/load-image-from-url/

直接贴上代码:

#include "curl/curl.h" // has to go before opencv headers

#include <iostream>

#include <vector>using namespace std;

#include <opencv2/opencv.hpp>

using namespace cv;

//curl writefunction to be passed as a parameter// we can't ever expect to get the whole image in one piece,// every router / hub is entitled to fragment it into parts// (like 1-8k at a time),// so insert the part at the end of our stream.size_t write_data(char *ptr, size_t size, size_t nmemb, void *userdata)

{

    vector<uchar> *stream = (vector<uchar>*)userdata;

    size_t count = size * nmemb;

    stream->insert(stream->end(), ptr, ptr + count);

return count;

}



//function to retrieve the image as cv::Mat data type

cv::Mat curlImg(const char *img_url, int timeout=10)

{

    vector<uchar> stream;

    CURL *curl = curl_easy_init();

    curl_easy_setopt(curl, CURLOPT_URL, img_url); //the img url

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); // pass the writefunction

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream); // pass the stream ptr to the writefunction

    curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); // timeout if curl_easy hangs,

    CURLcode res = curl_easy_perform(curl); // start curl

    curl_easy_cleanup(curl); // cleanup

return cv::imdecode(stream, -1); // 'keep-as-is'

}

int main(void)

{

    Mat image = curlImg("https://img-blog.csdnimg.cn/2020122114040625.png");

    if (image.empty())

        return -1; // load fail



    namedWindow( "Image output", CV_WINDOW_AUTOSIZE );

    imshow("Image output",image); // here's your car ;)

waitKey(0); // infinite

}

3、耗时统计

测试了一下,从网络上找了一个 837*675尺寸的png图像,测试几百次,平均获取耗时达到 170ms了;也测试了一些其他网络图像,获取耗时也是很大。当然可能和网络也有些关系。 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值