OpenCV和FFMpeg图片转换对比

最近一直在处理图片,从H264解码后得到的图片是YUV图片,而且很多都是NV12的,不是YUV420P(它们的差别是NV12格式为YYY...Y UV UV UV ... UV,而420P格式为 YYY...YY UUU..U VVV...V),一张1920x1080的图片大小为3.1M,为了节省空间,我需要存储为jpg,jpeg格式实际上就是压缩后的YUV,别的不说先上代码

    /* OpenCV */
    cv::Mat srcimg, dstimg;
    srcimg.create(height*3/2, width, CV_8UC1);
    FILE* fp = fopen(yuvf, "rb");
    fread(srcimg.data, 1, height*width*3/2, fp);
    // 需要进行一次转化
    cv::cvtColor(srcimg, dstimg, cv::COLOR_YUV2BGR_NV12);
    // 文件保存,目前已经测试jpg和png文件可行
    cv::imwrite(fout, dstimg);
/* libavcodec */  1     AVCodec* codec;
  2     AVCodecContext* codecCtx;
  3     struct SwsContext* swsCtx;
  4     FILE* fp;
  5     int inSz, tmpSz;
  6     uint8_t *inbuff, *tmpbuff;
  7     size_t rd;
  8     int got_output = 0;
  9     int ret = 0;
 10     AVFrame *frame = NULL;
 11     AVPacket  pkt;
 12     if (width < 1 || height < 1 || !in || !out)
 13         return -1;
 14
 15     // 准备转换环境
 16     av_register_all(); // 必须调用,否则 avcodec_find_encoder 会失败
 17     codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
 18     if (NULL == codec) {
 19         return -2;
 20     }
 21     codecCtx = avcodec_alloc_context3(codec);
 22     if (NULL == codecCtx) {
 23         ret = -3;
 24         goto codecctx_errout;
 25     }
 26     codecCtx->bit_rate = 4000000;
 27     codecCtx->width =width;
 28     codecCtx->height = height;
 29     codecCtx->time_base = (AVRational){ 1, 25 };
 30     codecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P;
 31     if (avcodec_open2(codecCtx, codec, NULL) < 0) {
 32         ret = -4;
 33         goto codecctx_errout;
 34     }
 35     frame = av_frame_alloc();
 36     av_init_packet(&pkt);
 37     pkt.data = NULL;
 38     pkt.size = 0;
 39
 40     // 加载源文件
 41     fp = fopen(in, "rb");
 42     if (NULL == fp) {
 43         ret = -5;
 44         goto out;
 45     }
 46
 47     inSz = av_image_get_buffer_size(infmt, width, height, 1);
 48     if (inSz <= 0) {
 49         ret = -6;
 50         goto out;
 51     }
 52     inbuff = (uint8_t*)malloc(inSz);
 53     if (NULL == inbuff) {
 54         ret = -7;
 55         goto out;
 56     }
 57     rd = fread(inbuff, 1, inSz, fp);
 58     if (rd != (size_t)inSz) {
 59         fclose(fp);
 60         ret = -8;
 61         goto allout;
 62     }
 63     fclose(fp);
 64
 65     // 转换格式为YUV420P
 66     if (infmt != AV_PIX_FMT_YUVJ420P && infmt != AV_PIX_FMT_YUV420P) {
 67         swsCtx = sws_getContext(width, height, infmt, width, height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, 0, 0, 0);
 68         if (NULL == swsCtx) {
 69             ret = -9;
 70             goto allout;
 71         }
 72         tmpSz = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, width, height, 1);
 73         tmpbuff = (uint8_t*)malloc(tmpSz);
 74         if (NULL == tmpbuff) {
 75             ret = -9;
 76             goto allout;
 77         }
 78
 79         AVFrame FrIn, FrOut;
 80         av_image_fill_linesizes(FrIn.linesize, infmt, width);
 81         av_image_fill_pointers(FrIn.data, infmt, height, inbuff, FrIn.linesize);
 82         av_image_fill_linesizes(FrOut.linesize, AV_PIX_FMT_YUV420P, width);
 83         av_image_fill_pointers(FrOut.data, AV_PIX_FMT_YUV420P, height, tmpbuff, FrOut.linesize);
 84
 85         sws_scale(swsCtx, (const uint8_t* const*)FrIn.data, FrIn.linesize, 0, height, FrOut.data, FrOut.linesize);
 86         // 使用新的buffer
 87         free(inbuff);
 88         inbuff = tmpbuff;
 89     }
 90     // 填充AVFrame
 91     frame->format = codecCtx->pix_fmt;
 92     frame->width = width;
 93     frame->height = height;
 94
 95     // 转换
 96     av_image_fill_linesizes(frame->linesize, codecCtx->pix_fmt, width);
 97     av_image_fill_pointers(frame->data, codecCtx->pix_fmt, height, inbuff, frame->linesize);
 98     if (avcodec_send_frame(codecCtx, frame) < 0) {
 99         ret = -10;
100         goto allout;
101     }
102     if (0 == avcodec_receive_packet(codecCtx, &pkt)) {
103         fp = fopen(out, "wb");
104         if (fp) {
105             fwrite(pkt.data, 1, pkt.size, fp);
106             fclose(fp);
107         }
108         else {
109             ret = 12;
110         }
111         av_packet_unref(&pkt);
112     }
113
114     // 环境回收
115 allout:
116     free(inbuff);
117 out:
118     sws_freeContext(swsCtx);
119     av_frame_free(&frame);
120 codecctx_errout:
121     avcodec_close(codecCtx);
122     av_free(codecCtx);
123 errout:
124     return ret;

我的电脑配置I7 6700HQ,内存16G,系统Ubuntu 18.04,转换1920x1080图片结果为:OpenCV耗时超过80ms(在84左右浮动),而使用libavcodec版本只需要12ms。

OpevCV是很多做算法的喜欢的工具,可是这个效率,真的是很差 ,它的强项应该就是——代码足够短,FFMpeg使用将近100行的代码它只用了6行就完成了。

现在库包装越来越“豪华”,执行效率却是越来越低,我们真的需要这么高的硬件配置吗?还是我们被这么多工具给忽悠了?

近段在折腾Rockchip的RK3399,在前面被表扬的FFMepg这里就要被打脸了,解码1920x1080的H264视频流,FFMpeg也加入了硬解码,我测试了一下,CPU消耗也是100%,而我直接使用Rockchip提供的MPP借口解码CPU占用率维持在35%左右,没有细看FFMpeg代码,扫了一下,也是一样使用MPP接口,但就不知道为什么差别会这么大了。

原文地址:https://www.cnblogs.com/darkise/p/9945699.html

时间: 2024-10-13 05:08:04

OpenCV和FFMpeg图片转换对比的相关文章

OprenCV学习之路一:将彩色图片转换成灰度图

//将一张彩色图片转成灰度图: //////////////////////////// #include<cv.h> #include<cvaux.h> #include<highgui.h> #include<ml.h> #include<iostream> using namespace std; using namespace cv; int main() { IplImage *src=0; src=cvLoadImage("

OpenCV进行图像相似度对比的几种办法

对计算图像相似度的方法,本文做了如下总结,主要有三种办法: 1.PSNR(Peak Signal to Noise Ratio)峰值信噪比,一种全参考的图像质量评价指标. 简介: http://www.cnblogs.com/vincent2012/archive/2012/10/13/2723152.html PSNR是最普遍和使用最为广泛的一种图像客观评价指标,然而它是基于对应像素点间的误差,即基于误差敏感的图像质量评价.由于并未考虑到人眼的视觉特性(人眼对空间频率较低的对比差异敏感度较高,

[转] 小tip: 使用CSS将图片转换成模糊(毛玻璃)效果 ---张鑫旭

by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=3804 去年盛夏之时,曾写过“小tip: 使用CSS将图片转换成黑白”一文,本文的模式以及内容其实走得是类似路线.CSS3 → SVG → IE filter → canvas. 前段时间,iOS7不是瓜未熟就落地了嘛,然后捡瓜的人很多,然后国内外开始了各种探讨,从界面到动画,从兼容到实现等.其中,“毛玻璃”一次梆梆出世

怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图?

  分类: OpenCV [Q1]怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图? 进行灰度化,IplImage* pImg = cvLoadImage( "C:\\1.bmp", 0 ); 这样图像已经灰度化,然后调用cvThreshold(image, image, 125, 255, CV_THRESH_BINARY); 就可以了,125那里是你所用的阈值,这就是最简单的二值化,你要用ostu,或者别的高级一点的,就要自己写函数了   // Truncate v

jpg图片转换成文字

好的电子书大多是PDF格式的,用手持的电子阅读器看不了.有的手持阅读器虽支持PDF格式,但是价格奇贵且效果不好.所以将PDF格式转成TXT格式成了重要问题.这一工作现在可以交由捷速pdf文字识别软件来处理了.该软件具有超强的技术支持,识别效果非常好.市面上普通的软件使用时需将图像文件调入软件界面,然后必须根据软件的规则调整好位置方能进行识别:而我们这款软件根本没这么麻烦,导入需要识别的pdf文件,再点击识别按钮,几秒钟后就会弹出识别结果.下面我们就以事实说话,看看软件实际操作得出的 识别效果是怎

jpeg图片转换成word

好的电子书大多是PDF格式的,用手持的电子阅读器看不了.有的手持阅读器虽支持PDF格式,但是价格奇贵且效果不好.所以将PDF格式转成TXT格式成了重要问题.这一工作现在可以交由捷速pdf文字识别软件来处理了.该软件具有超强的技术支持,识别效果非常好. 市面上普通的软件使用时需将图像文件调入软件界面,然后必须根据软件的规则调整好位置方能进行识别:而我们这款软件根本没这么麻烦,导入需要识别的pdf文件,再点击识别按钮,几秒钟后就会弹出识别结果.下面我们就以事实说话,看看软件实际操作得出的识别效果是怎

小tip: 使用CSS将图片转换成黑白(灰色、置灰) ? 张鑫旭-鑫空间-鑫生活

小tip: 使用CSS将图片转换成黑白(灰色.置灰) 这篇文章发布于 2012年08月19日,星期日,20:41,归类于 css相关, SVG相关. 阅读 159943 次, 今日 146 次 by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=2547 //zxx: 最近很积极地折腾手机页面的些东西,加上其他一些人生重要的事,所以木有更新. 可能早就知道,像汶川这种糟糕

Linux中gif的制作和图片转换

图片转换命令convert convert 命令是由 ImageMagick 包提供. 选择转换为jpg图片会比转换为png图片小很多. jpg 图片比 png小. 缩放: convert -sample 80x60 input.jpg output.jpg 缩放后图像保持原来的长宽比例(也可同时转换格式,好用法): convert -sample 25%x25% input.jpg output.jpg 类型转换 convert 1.jpg 1.png 特殊效果 convert -charco

照片转成pdf 如何把jpg图片转换成pdf格式

大家不知道还记不记得,那句台词"好男人就是我,我就是xxx"曾小贤.没错就是他<爱情公寓>毫无疑问近几年比较有特点的喜剧了,而且每个人都在盼望着第五季.尤其是到第四部结尾的时候,大家都希望曾小贤能和一菲在一起,在这时候它结束了,我们都幻想着爱情公寓第五季,可是迟迟没有音信.大家依然还记得子乔的小姨妈.楼下的小黑.婉瑜.展博. 这群年轻人跟现实生活中的我们一样,过着合租群租的生活,我们没有他们那么多的欢声笑语,可能这就是电视剧和现实差距,当我们最爱的几位主演都有了自己新的工作