ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片-阿里云开发者社区

开发者社区> double2li> 正文

ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片

简介: 这里请注意,在编译ffmpeg时,不要使用--disable-devices选项。 使用 --enable-encoder=rawvideo --enable-decoder=rawvideo 启用rawvideo codec。
+关注继续查看

这里请注意,在编译ffmpeg时,不要使用--disable-devices选项。

使用

--enable-encoder=rawvideo
 --enable-decoder=rawvideo

启用rawvideo codec。

代码如下:

  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4.   
  5. #include <libavformat/avformat.h>  
  6. #include <libavcodec/avcodec.h>  
  7. #include <libavdevice/avdevice.h>  
  8. #include <libswscale/swscale.h>  
  9.   
  10. #include <windows.h>  
  11.   
  12. #include <time.h>  
  13.   
  14. #define MAX_INPUT_DEVICE_NUM 10  
  15.   
  16. #ifdef _WIN32  
  17. int strcasecmp(const char *s1, const char *s2)  
  18. {  
  19.     while ((*s1 != '\0')  
  20.         && (tolower(*(unsigned char *) s1) ==  
  21.         tolower(*(unsigned char *) s2)))   
  22.     {  
  23.         s1++;  
  24.         s2++;  
  25.     }  
  26.     return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);  
  27. }  
  28. int strncasecmp(const char *s1, const char *s2, unsigned int n)  
  29. {  
  30.     if (n == 0)  
  31.         return 0;  
  32.     while ((n-- != 0)  
  33.         && (tolower(*(unsigned char *) s1) ==  
  34.         tolower(*(unsigned char *) s2))) {  
  35.             if (n == 0 || *s1 == '\0' || *s2 == '\0')  
  36.                 return 0;  
  37.             s1++;  
  38.             s2++;  
  39.     }  
  40.     return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);  
  41. }  
  42. #endif  
  43.   
  44. void save_bmp(unsigned char * data,int data_size,int w,int h,FILE * out)  
  45. {  
  46.     // 位图文件头  
  47.     BITMAPFILEHEADER bmpheader;   
  48.     BITMAPINFO bmpinfo;   
  49.     int bit = 24;  
  50.   
  51.     bmpheader.bfType = ('M' <<8)|'B';   
  52.     bmpheader.bfReserved1 = 0;   
  53.     bmpheader.bfReserved2 = 0;   
  54.     bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);   
  55.     bmpheader.bfSize = bmpheader.bfOffBits + w*h*bit/8;  
  56.   
  57.     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);   
  58.     bmpinfo.bmiHeader.biWidth = w;   
  59.     bmpinfo.bmiHeader.biHeight = 0-h;   
  60.     bmpinfo.bmiHeader.biPlanes = 1;   
  61.     bmpinfo.bmiHeader.biBitCount = bit;   
  62.     bmpinfo.bmiHeader.biCompression = BI_RGB;   
  63.     bmpinfo.bmiHeader.biSizeImage = 0;   
  64.     bmpinfo.bmiHeader.biXPelsPerMeter = 100;   
  65.     bmpinfo.bmiHeader.biYPelsPerMeter = 100;   
  66.     bmpinfo.bmiHeader.biClrUsed = 0;   
  67.     bmpinfo.bmiHeader.biClrImportant = 0;  
  68.   
  69.     fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,out);   
  70.     fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,out);  
  71.     fwrite(data,data_size,1,out);  
  72. }  
  73. int CaptureFromLocalCamera()  
  74. {  
  75.     AVFormatContext *ic = NULL;  
  76.     AVFormatParameters in_fmt_para={0};  
  77.     AVPacket packet;  
  78.     char buffer[MAX_PATH]={0};  
  79.     int width = 0,height = 0;  
  80.     int ret,video_stream = -1,i=0;  
  81.   
  82.     //查找输入(vfwcap)格式  
  83.     AVInputFormat *in_fmt = av_find_input_format ("vfwcap");   
  84.     if (in_fmt == NULL)   
  85.     {  
  86.         printf("not support input device vfwcap.\n");  
  87.         return -1;  
  88.     }  
  89.     memset (&in_fmt_para, 0, sizeof(in_fmt_para));  
  90.     //指定需要采集图像的高度  
  91.     in_fmt_para.height = height;  
  92.     //指定需要采集图像的宽度  
  93.     in_fmt_para.width  = width;  
  94.   
  95.     //设置帧率  
  96.     av_parse_video_frame_rate(&in_fmt_para.time_base,"20");  
  97.   
  98.     //打开摄像头设备,从"0"到MAX_INPUT_DEVICE_NUM依次尝试打开  
  99.     for( i=0 ; i < MAX_INPUT_DEVICE_NUM + 1; i++ )  
  100.     {  
  101.         sprintf(buffer,"%d",i);  
  102.         ret = av_open_input_file ( &ic, buffer, in_fmt,sizeof(in_fmt_para),&in_fmt_para);  
  103.         if ( ret == 0 && ic)  
  104.         {  
  105.             break;  
  106.         }  
  107.     }  
  108.     //open success?  
  109.     if(!ic || ret != 0)  
  110.     {  
  111.         if(ic)  
  112.             av_close_input_file(ic);  
  113.         printf("can not open input file.\n");  
  114.         return -2;  
  115.     }  
  116.     printf("input device no. is %d\n",i);  
  117.     //find the video stream  
  118.     for(i=0;i<ic ->nb_streams;i++)  
  119.     {  
  120.         if ( CODEC_TYPE_VIDEO == ic ->streams[i] ->codec ->codec_type )  
  121.         {  
  122.             video_stream = i;  
  123.             break;  
  124.         }  
  125.     }  
  126.     if(video_stream < 0)  
  127.     {  
  128.         av_close_input_file(ic);  
  129.         printf("can not find a video stream.\n");  
  130.         return -3;  
  131.     }  
  132.     //获取视频时间宽度和高度  
  133.     width  = ic ->streams[video_stream] ->codec ->width;  
  134.     height = ic ->streams[video_stream] ->codec ->height;  
  135.     printf("video size: %dx%d\n",width,height);  
  136.     //从摄像头获取图像数据  
  137.     if( 0 == av_read_frame(ic,&packet))  
  138.     {  
  139.         //find the decode codec  
  140.         AVCodec * decodec =  avcodec_find_decoder(ic ->streams[video_stream] ->codec ->codec_id);  
  141.         if(decodec)  
  142.         {  
  143.             //open the decode codec  
  144.             if( 0 == avcodec_open(ic ->streams[video_stream] ->codec,decodec) )  
  145.             {  
  146.                 int got_picture = 0;  
  147.                 AVFrame * frame = avcodec_alloc_frame();  
  148.                 avcodec_decode_video2(ic ->streams[video_stream] ->codec,frame,&got_picture,&packet);  
  149.                 //decode success  
  150.                 if(got_picture)  
  151.                 {  
  152.                     uint8_t * buffer = NULL;  
  153.                     size_t buffer_size = 0;  
  154.                     struct SwsContext *pSwsCtx=NULL;  
  155.                     AVFrame * rgb_frame = avcodec_alloc_frame();  
  156.                     buffer_size = avpicture_get_size(PIX_FMT_BGR24,width,height);  
  157.                     buffer = (uint8_t *)av_malloc(buffer_size);  
  158.                     avpicture_fill((AVPicture*)rgb_frame,(uint8_t *)buffer,PIX_FMT_BGR24,width,height);  
  159.                     //get swscale ctx  
  160.                     pSwsCtx = sws_getContext(  
  161.                         ic ->streams[video_stream] ->codec ->width,  
  162.                         ic ->streams[video_stream] ->codec ->height,  
  163.                         ic ->streams[video_stream] ->codec ->pix_fmt,  
  164.                         width,  
  165.                         height,  
  166.                         PIX_FMT_BGR24,  
  167.                         SWS_BILINEAR,  
  168.                         NULL,  
  169.                         NULL,  
  170.                         NULL);  
  171.                     if(pSwsCtx)  
  172.                     {  
  173.                         FILE *fp = NULL;  
  174.                         SYSTEMTIME dt={0};  
  175.                         //图像格式转换  
  176.                         sws_scale(  
  177.                             pSwsCtx,  
  178.                             frame ->data,  
  179.                             frame ->linesize,  
  180.                             0,  
  181.                             ic ->streams[video_stream] ->codec ->height,  
  182.                             rgb_frame ->data,  
  183.                             rgb_frame ->linesize);  
  184.                         //create the image file name  
  185.                         GetLocalTime(&dt);  
  186.                         srand(0);  
  187.                         sprintf(buffer,"imgs/%04d_%02d_%02d %02d_%02d_%02d %02d.bmp",dt.wYear,dt.wMonth,dt.wDay,dt.wHour,dt.wMinute,dt.wSecond,rand()%30);  
  188.                         //  
  189.                         CreateDirectoryA("imgs",NULL);  
  190.                         //open file  
  191.                         fp = fopen(buffer, "wb");  
  192.                         if(fp)  
  193.                         {  
  194.                             save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*height,width,height,fp);  
  195.                             fclose(fp);  
  196.                         }  
  197.                         //free sws ctx  
  198.                         sws_freeContext(pSwsCtx);  
  199.                     }  
  200.                     //free buffer  
  201.                     av_free(rgb_frame);  
  202.                     av_free(buffer);  
  203.                 }  
  204.                 //free buffer  
  205.                 av_free(frame);  
  206.                 //close the decode codec  
  207.                 avcodec_close(ic ->streams[video_stream] ->codec);  
  208.             }  
  209.         }  
  210.     }  
  211.           
  212.     //close the input device  
  213.     av_close_input_file(ic);  
  214.   
  215.     return 0;  
  216. }  
  217.   
  218.   
  219. int main()  
  220. {  
  221.     //avcodec_init();      
  222.     avcodec_register_all();  
  223.     avdevice_register_all();  
  224.     CaptureFromLocalCamera();  
  225.   
  226.     return 0;  
  227. }  

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
windows linux 使用python执行系统命令并将结果保存到变量
最近需要用到os.system 发现不能赋值到变量 后查有更新的模块,如下: os.system os.spawn* os.popen* popen2.* commands.* 重新使用content=os.
1068 0
与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频)
原文:与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频) [索引页][源码下载] 与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频) 作者:webabcd介绍与众不同 windows phone 7.
835 0
WinForm 加载本地图片
方式一: /// &lt;summary&gt; /// 从程序集中加载图片 /// &lt;/summary&gt; /// &lt;param name="imagePathName"&gt;图片路径(该图片必须是嵌入的资源)&lt;/param&gt; /// &lt;returns&gt;Bitmap 格式图片&
1064 0
同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同
同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同
328 0
C# Windows Phone App 开发,修改【锁定画面】,从【Assets】、【UI】、【网路图片】,并解决失灵问题。
原文:C# Windows Phone App 开发,修改【锁定画面】,从【Assets】、【UI】、【网路图片】,并解决失灵问题。 一般我们在开发Windows Phone App,有时会希望透过应用程式来改变锁定画面,但是锁定画面的设定有时会发生非常吊诡的现象,譬如锁定画面只会在第一次设定的时候成功,第二次之後全数失败,而且没有发生任何错误,这究竟是为什麽呢?! ? 本篇文章将引导您修改【锁定画面】,从【Assets】、【UI】、【网路图片】,并解决失灵问题。
969 0
Win8 Metro(C#) 数字图像处理--1 图像打开,保存
原文:Win8 Metro(C#) 数字图像处理--1 图像打开,保存 作为本专栏的第一篇,必不可少的需要介绍一下图像的打开与保存,一便大家后面DEMO的制作。
851 0
C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!!
原文:C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!! 一般我们在开发Winodws Phone APP 的时候往往需要使用照片浏览的功能,但是在Windows Phone 8 SDK 中...
710 0
ffmpeg实现将图片转换为视频
##名称:ffmpeg实现将图片转换为视频 ##平台:ubuntu(已经安装好了ffmpeg工具) ##日期:2017年12月10日 简介: 因为学习需要,需要将连续图片转换成视频,昨天和今天早上用opencv实现了, 但是对于视频的处理用ffmpeg工具,更为强大。
1504 0
+关注
double2li
一个在IT行业摸爬滚打的老司机
2870
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载