根据书上的案例读取一个AVI格式的视频。
播放视频遇到的问题:
用cvCreateFileCapture()读取视频文件,本来看是一个很普通的问题,但遇到播放不出画面时总让人纠结。
今天用此函数读取视频文件,总是灰屏闪退。仔细查看问题,发现此函数对视频读取颇为苛刻。要和本机的解码器相匹配。
首先下载XviD codec 解码器http://www.xvidmovies.com/codec/,然后确保自己的视频文件为xvid格式的avi文件。
又下载了狸窝全能视频转换器http://dl.pconline.com.cn/download/57474.html的,
将目标文件确认转换为xvid格式的avi。
补充:XviD的文件扩展名可以是AVI、MKV、MP4等。
需要说明的是,仅从扩展名并不能看出这个视频的编码格式。比如说一部电影是.avi格式,
但是实际上的视频编码格式可以是DV Code,也可以是XviD或者其他的;音频编码格式可以是PCM、AC3或者MP3。
MP4和MKV格式比AVI更先进,支持更多的功能,比如字幕。AVI视频的字幕需要另外的SRT文件。目前国外绝大多数的影视资源都是AVI格式。上述方式在新版本的OpenCV不成功,
终极原因:cvCreateFileCapture在3.4.6版本FFMPEG不支持旧版本的接口了。shit
int main(int argc,char** argv)
{
cvNamedWindow("Example2",CV_WINDOW_AUTOSIZE);
cv::VideoCapture* cap = new cv::VideoCapture("./../../VideoPicture/hero.avi");
//开启摄像头
//cv::VideoCapture* cap = new cv::VideoCapture(0);
//或者使用cv::VideoCapture capture(0)
while (true)
{
cv::Mat frame;
cap->read(frame); //等价于 cap >> frame;
imshow("读取视频",frame);
char c = cv::waitKey(60);
//判断是不是ESC
if (c == 27)
break;
}
#if 0
//对于精度要求高的程序来说,使用CvCapture结构体来读取视频帧率方法更好 就特么没成功 低版本支持该接口
CvCapture* capture = cvCreateFileCapture("aaaa.avi");
IplImage* frame1;
while (true)
{
frame1 = cvQueryFrame(capture);
if (!frame1)
{
break;
}
cvShowImage("Example2", frame1);
//当前帧显示后等待33毫秒
char c = cvWaitKey(33);
if (c == 27)
break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Example2");
#endif
return 0;
}
VS 编辑器碰到的问题:
error C2760: 语法错误: 意外的令牌“int”,预期的令牌为“表达式”
error C2589: “(”:“::”右边的非法标记
解决办法:打开项目工程----> 属性 ---> c/c++ --> 语言 --> 符合模式 修改成否即可
咱也不知道,咱也不敢问
error MSB8020: The builds tools for v140 (Platform Toolset = 'v140') cannot be found.
配置属性->常规->平台工具集 修改为VS对应的版本
将视频图像灰度化,扫描显示出轮廓
#include <opencv2/opencv.hpp>
using namespace cv;
#if 0
//项目路径是以 .vcxproj 为起始当前路径的
const char* fileName = "./../../VideoPicture/hero.avi";
FILE *fp = NULL; /* 需要注意 */
int error = fopen_s(&fp, fileName, "rb");
printf("error--------------------------:%d \n", error);
exit(0);
#endif
int main(int argc,char** argv)
{
//cvNamedWindow("Example2",CV_WINDOW_AUTOSIZE);
//创建对象的两种方式
//cv::VideoCapture capture;
//capture.open("./../../VideoPicture/hero.avi");
//cv::VideoCapture* cap = new cv::VideoCapture("./../../VideoPicture/hero.avi");
//开启摄像头
cv::VideoCapture* cap = new cv::VideoCapture(0);
//或者使用cv::VideoCapture capture(0)
cv::Mat edges;
cv::Mat frame; //存储每一帧视频
while (true)
{
cap->read(frame);
//imshow("读取视频",frame);
//将原图像转换为灰度图像,转换RGB彩色为灰度
cvtColor(frame, edges,CV_BGR2GRAY);
//使用3 * 3内核降噪 2*3+1=7 进行模糊
blur(edges,edges,cv::Size(7 , 7));
//进行canny边缘检测并显示
cv::Canny(edges,edges,0,30,3);
imshow("被边缘检测后的视频", edges);
char c = cv::waitKey(60);
//判断是不是ESC
if (c == 27)
break;
}
return 0;
}