OpenCV 将内存的图像读取,然后显示在显示器上

opencv加载内存中图片

OpenCv读取与解码内存中的图片及过程中的内存问题 - swjtu_ray的博客 - CSDN博客 https://blog.csdn.net/swjtu_ray/article/details/52529535

开发中遇到的问题,为了让别人方便也让自己方便,特此记录。

有时候我们会需要读取内存里面的图片,为了提高效率,避免了从硬盘重复读取文件所消耗的时间。 
以下是代码:

    //data为图像再内存中的地址
    CvMat mat = cvMat(width, height, CV_8UC1, data);//Read input binary image  
    //第二个参数为flag,在opencv文档中查询
    IplImage *pIplImage = cvDecodeImage(&mat, 1);
    //记住第二个参数为copy=true,否则释放后内存会出错
    Mat image(pIplImage,true);
    //cvDecodeImage产生的IplImage*对象***需要手动释放内存***
    cvReleaseImage(&pIplImage);

有内存溢出的风险,试试看。

opencv从磁盘加载一张图片非常简单,通过cv::imread即可,代码如下

    cv::Mat src_mat = cv::imread("1.jpg"); //读取图片1.jpg,imread会将图片内容解码成yuv或rgb存放到Mat对象
    cv::Mat dst_mat = src_mat(cv::Rect(100, 100, 1600, 900)); //获取图片固定区域的内容
    std::vector<uchar> jpg_buff;
    bool ret = cv::imencode(".jpg", dst_mat, jpg_buff);//对固定区域的内容重新进行jpg编码,生成jpg图片,存入jpg_buff
    FILE *file = fopen("2.jpg", "wb");
    if (file != nullptr) {
        fwrite(jpg_buff.data(), 1, jpg_buff.size(), file); //将jpg图片写入内存
        fclose(file);
    }

然而,很多情况,程序需要从内存中加载图片,例如通过网络上传的图片。很显然,这样的图片不能写入磁盘,然后再通过cv::imread读取,效率太低了。因此,需要从内存直接加载。然后通过cv::imdecode将图片解码成cv::Mat,代码如下:

    FILE *file = fopen("1.jpg", "rb");
    uchar *mem_pic = nullptr;
    long size = 0;
    if (file != nullptr) {
        fseek(file, 0, SEEK_END);
        size = ftell(file);
        fseek(file, 0, SEEK_SET);
        mem_pic = new uchar[size];
        fread(mem_pic, 1, size, file);
        fclose(file);
    }
 
    cv::_InputArray pic_arr(mem_pic, size);
    cv::Mat src_mat = cv::imdecode(pic_arr, CV_LOAD_IMAGE_COLOR);
    cv::Mat dst_src = src_mat(cv::Rect(100, 100, 1600, 900));
    std::vector<uchar> pic_buff;
    bool ret = cv::imencode(".jpg", dst_src, pic_buff);
    file = fopen("3.jpg", "wb");
    if (file != nullptr) {
        fwrite(pic_buff.data(), 1, pic_buff.size(), file);
        fclose(file);
    }

cv::_Array还可以使用std::vector代替,代码如下:

    FILE *file = fopen("1.jpg", "rb");
    uchar *mem_pic = nullptr;
    long size = 0;
    if (file != nullptr) {
        fseek(file, 0, SEEK_END);
        size = ftell(file);
        fseek(file, 0, SEEK_SET);
        mem_pic = new uchar[size];
        fread(mem_pic, 1, size, file);
        fclose(file);
    }
 
    //cv::_InputArray pic_arr(mem_pic, size);
    std::vector<uchar> pic_vec(mem_pic, mem_pic + size);
    cv::Mat src_mat = cv::imdecode(pic_vec, CV_LOAD_IMAGE_COLOR);
    cv::Mat dst_src = src_mat(cv::Rect(200, 200, 400, 225));
    std::vector<uchar> pic_buff;
    bool ret = cv::imencode(".jpg", dst_src, pic_buff);
    file = fopen("3.jpg", "wb");
    if (file != nullptr) {
        fwrite(pic_buff.data(), 1, pic_buff.size(), file);
        fclose(file);
    }

从这个博客上下载的,为啥不写注释啊!

opencv加载内存中图片 - flyingshineangel的专栏 - CSDN博客 https://blog.csdn.net/flyingshineangel/article/details/86742617

 

得学习后有时间我来解惑答疑,现在我还不明白。

另外一个介绍

opencv加载内存中的图片数据 - 菜鸟逐梦 - CSDN博客 https://blog.csdn.net/qq_32435729/article/details/77061946

经过实践终于找到了 opencv加载内存中的图片数据的方法,现在记录下来。

//参数分别为 图片宽度,高度,类型,图片数据指针(unsigned char*)
//这个构造函数并没有从新分配内存
CvMat mCvmat = cvMat(w, h, CV_8UC1, mImgData);

IplImage* IpImg = cvDecodeImage(&mCvmat, 1);

//opencv3.0 IplImage到Mat类型的转换的方法
Mat image = cvarrToMat(IpImg);

if (!image.data)
{
        
    return false;
}
 cvReleaseImage(&IpImg);
或者(opencv 3.4.5实测)

    //Mat和mImgData共享同一块内存区域
    uchar* mImgData = new uchar[w*h*channel];
    Mat imm(h,w,CV_8UC3, mImgData);
    //process img
    delete []mImgData;
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值