之前实现了yolo图像的在线检测,这次主要完成远程视频的检测。主要包括推流--収流--检测显示三大部分

  首先说一下推流,主要使用ffmpeg命令进行本地摄像头的推流,为了实现首屏秒开使用-g设置gop大小,同时使用-b降低网络负载,保证流畅度。

linux

ffmpeg -r   -i /dev/video0 -vcodec h264 -max_delay  -f flv -g  -b  rtmp://219.216.87.170/live/test1

window

ffmpeg -r   -f vfwcap -i  -vcodec h264 -max_delay  -f flv -g  -b  rtmp://219.216.87.170/live/test1
ffmpeg -list_devices true -f dshow -i dummy
ffmpeg -r -f dshow -i video="1.3M HD WebCam" -vcodec h264 -max_delay -f flv -g -b rtmp://219.216.87.170/live/tes
t1

  其次是収流,収流最开始的时候,有很大的延迟,大约5秒,后来通过优化,现在延时保证在1s以内,还是可以接收的,直接上収流的程序

AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame, *pFrameRGB;
uint8_t *out_buffer;
AVPacket *packet;
//int y_size;
int ret, got_picture;
struct SwsContext *img_convert_ctx;
//输入文件路径
// char filepath[] = "rtmp://219.216.87.170/vod/test.flv";
char filepath[] = "rtmp://219.216.87.170/live/test1";
int frame_cnt; printf("wait for playing %s\n", filepath);
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
printf("size %ld\tduration %ld\n", pFormatCtx->probesize,
pFormatCtx->max_analyze_duration);
pFormatCtx->probesize = ;
pFormatCtx->max_analyze_duration = ;
// pFormatCtx->interrupt_callback.callback = timout_callback;
// pFormatCtx->interrupt_callback.opaque = pFormatCtx;
// pFormatCtx->flags |= AVFMT_FLAG_NONBLOCK; AVDictionary* options = NULL;
av_dict_set(&options, "fflags", "nobuffer", );
// av_dict_set(&options, "max_delay", "100000", 0);
// av_dict_set(&options, "rtmp_transport", "tcp", 0);
// av_dict_set(&options, "stimeout", "6", 0); printf("wating for opening file\n");
if (avformat_open_input(&pFormatCtx, filepath, NULL, &options) != ) {
printf("Couldn't open input stream.\n");
return -;
}
av_dict_free(&options);
printf("wating for finding stream\n");
if (avformat_find_stream_info(pFormatCtx, NULL) < ) {
printf("Couldn't find stream information.\n");
return -;
}
videoindex = -;
for (i = ; i < pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoindex = i;
break;
}
if (videoindex == -) {
printf("Didn't find a video stream.\n");
return -;
} pCodecCtx = pFormatCtx->streams[videoindex]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
printf("Codec not found.\n");
return -;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < ) {
printf("Could not open codec.\n");
return -;
}
/*
* 在此处添加输出视频信息的代码
* 取自于pFormatCtx,使用fprintf()
*/
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
out_buffer = (uint8_t *) av_malloc(
avpicture_get_size(AV_PIX_FMT_BGR24, pCodecCtx->width,
pCodecCtx->height));
avpicture_fill((AVPicture *) pFrameRGB, out_buffer, AV_PIX_FMT_BGR24,
pCodecCtx->width, pCodecCtx->height);
packet = (AVPacket *) av_malloc(sizeof(AVPacket));
//Output Info-----------------------------
printf("--------------- File Information ----------------\n");
av_dump_format(pFormatCtx, , filepath, );
printf("-------------------------------------------------\n");
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,
AV_PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);
CvSize imagesize;
imagesize.width = pCodecCtx->width;
imagesize.height = pCodecCtx->height;
IplImage *image = cvCreateImageHeader(imagesize, IPL_DEPTH_8U, );
cvSetData(image, out_buffer, imagesize.width * );
cvNamedWindow(filepath, CV_WINDOW_AUTOSIZE); frame_cnt = ;
int num = ;
while (av_read_frame(pFormatCtx, packet) >= ) {
if (packet->stream_index == videoindex) {
/*
* 在此处添加输出H264码流的代码
* 取自于packet,使用fwrite()
*/
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture,
packet);
if (ret < ) {
printf("Decode Error.\n");
return -;
}
if (got_picture) {
sws_scale(img_convert_ctx,
(const uint8_t* const *) pFrame->data, pFrame->linesize,
, pCodecCtx->height, pFrameRGB->data,
pFrameRGB->linesize); printf("Decoded frame index: %d\n", frame_cnt); /*
* 在此处添加输出YUV的代码
* 取自于pFrameYUV,使用fwrite()
*/ frame_cnt++;
cvShowImage(filepath, image);
cvWaitKey(); }
}
av_free_packet(packet);
} sws_freeContext(img_convert_ctx); av_frame_free(&pFrameRGB);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx); return ;

  将解压后的数据区与opencv的IplImage的数据区映射,实现opencv显示。

  

  检测部分,主要使用IplImage与yolo中的图像进行对接,在图像转换方面,进行了部分优化,缩减一些不必要的步骤。然后使用线程区接收ffmepg流,主循环里区做检测并显示。需要做线程同步处理,只有当收到新流时,才去检测。

实战小项目之ffmpeg推流yolo视频实时检测的更多相关文章

  1. Flask框架的学习与实战(二):实战小项目

    昨天写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统. blog系统很简单,只有一个页面,然而麻雀虽小五脏俱全.这里目的不是为了做项目而做项目,这篇文章本意是通过这次练习传达 ...

  2. 实战小项目之基于yolo的目标检测web api实现

    上个月,对微服务及web service有了一些想法,看了一本app后台开发及运维的书,主要是一些概念性的东西,对service有了一些基本了解.互联网最开始的构架多是cs构架,浏览器兴起以后,变成了 ...

  3. 实战小项目BUG纪录

    果然,作为程序员最可爱的女朋友就是各种BUG,解决了你的开发能力和开发效率就会上升到一个新的层次.反之,在你面对BUG的时候,如果轻易的就放弃了,你也就失去了一次自我成长的机会.学习就是这样的,我们有 ...

  4. Django集成celery实战小项目

    上一篇已经介绍了celery的基本知识,本篇以一个小项目为例,详细说明django框架如何集成celery进行开发. 本系列文章的开发环境: window 7 + python2.7 + pychar ...

  5. 【实战小项目】python开发自动化运维工具--批量操作主机

    有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子.只不过,很多运维同学学习Python之后,苦于没小项目训练.本篇就演示用Python写一个批量操作主机的工 ...

  6. ASP.NET Core 2.1 Web API + Identity Server 4 + Angular 6 + Angular Material 实战小项目视频

    视频简介 ASP.NET Core Web API + Angular 6的教学视频 我是后端开发人员, 前端的Angular部分讲的比较差一些, 可以直接看代码!!!! 这是一个小项目的实战视频, ...

  7. 实战小项目之RTMP流媒体演示系统

    项目简介 windows下使用基于Qt对之前的RtmpApp进行封装与应用,单独功能使用线程执行,主要包括以下几个功能: 视频下载 推送文件 推送摄像头数据或者桌面 基于libvlc的播放器 视频下载 ...

  8. 实战小项目之IMX6 VPU使用

    项目简介 基于官方的demo进行修改,限于能力问题,并没有将功能代码完全从官方的demo中分离出来,还是基于原来的框架进行修改,做了一些简单的封装,我做的工作如下: 使用自己的采集程序 定义6中工作模 ...

  9. 实战小项目之嵌入式linux图像采集与传输

    项目简介      本次编程实战主要是围绕嵌入式linux v4l2采集框架展开,包括以下几个部分: v4l2视频采集 IPU转码 framebuffer显示 自定义UDP简单协议进行传输 上位机软件 ...

随机推荐

  1. CSS、JavaScript学习过程

    初学JavaScript,通过博客记录自己学习过程中遇到的问题.(包含少量CSS) 零碎记录 JavaScript 输出 type="text/javascript" 那些老旧的实 ...

  2. Plugin 'InnoDB' registration as a STORAGE ENGINE failed

    今天在安装mysql时遇到了mysql服务打不开的的情况,通过在cmd中输入MySQL --console,显示错误信息,得到如下情况. 原因是InnoDB初始化异常,也就是是说,卸载mysql的时候 ...

  3. MySQL 5.7增强半同步测试

            we've know the machenism of semi-synchronous replication in my previous article,let's do som ...

  4. Linux每日一命令:【00】总纲

    Linux每日一命令更新频率为每周5篇. 文章结构如下: 简介 语法 选项 参数 常用实例 实用技巧(可选) 参考文档 文章目录如下: 2018-02-19 20:15 -- Linux每日一命令:[ ...

  5. 用原生JS写一个网页版的2048小游戏(兼容移动端)

    这个游戏JS部分全都是用原生JS代码写的,加有少量的CSS3动画,并简单的兼容了一下移动端. 先看一下在线的demo:https://yuan-yiming.github.io/2048-online ...

  6. Hive操作之向分区表中导入数据的语义错误

    1.建完分区表之后,向表中导入数据 命令为: load data local inpath '/home/admin/Desktop/2015082818' into table db_web_dat ...

  7. Python安装及简介

    Python简介 Python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...

  8. centos7下使用n grok编译服务端和客户端穿透内网

    (发现博客园会屏蔽一些标题中的关键词,比如ngrok.内网穿透,原因不知,所以改了标题才能正常访问,) 有时候想在自己电脑.路由器或者树莓派上搭建一些web.vpn等服务让自己用,但是自己的电脑一般没 ...

  9. (数据科学学习手札42)folium进阶内容介绍

    一.简介 在上一篇(数据科学学习手札41)中我们了解了folium的基础内容,实际上folium在地理信息可视化上的真正过人之处在于其绘制图像的高度可定制化上,本文就将基于folium官方文档中的一些 ...

  10. 【转】Odoo 学习之:constrains装饰

    constrains装饰用于对字段进行限制 应用举例: 定义列: age = fields.Integer(string="age") 方法: @api.constrains('a ...