opencv学习笔记(八)彩色视频转换成黑白视频

#include "cv.h"  
#include "highgui.h"  
  
int main(int argc, char** argv[])  

{  

       CvCapture* capture = 0;  

       capture = cvCreateFileCapture("2.avi"); 

//打开一个视频文件 

        if (!capture)  

    {  
        return -1;  
    }  
       IplImage *bgr_frame = cvQueryFrame(capture);  
       //通过cvQueryFrame读入视频
       double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); 
       //使用cvGetCaptureProperty来获得视频流的各种属性    
       CvSize size = cvSize(  
               (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH),  
               (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)  
        );  
CvVideoWriter *write = cvCreateVideoWriter(  
"hehe.avi",  //新建视频文件的名称 
 CV_FOURCC('M','J','P','G'),//视频压缩的编码格式,此处为MJPG编码格式
fps,  //播放的帧率  
size,  //视频图像的大小,此处为视频的帧率和大小  
0
);  
IplImage* gray_frame = cvCreateImage(size, IPL_DEPTH_8U, 1);  
while ((bgr_frame = cvQueryFrame(capture)) != NULL){  
       cvConvertImage(   
bgr_frame,
 gray_frame,
 CV_RGB2GRAY
        ); 
 cvFlip( gray_frame, NULL, 0 );//翻转图像 
        //将转换后的图像逐帧写入视频文件  
        cvWriteFrame(write, gray_frame);  
    }  
cvReleaseVideoWriter(&write);  
    cvReleaseImage(&gray_frame);  
    cvReleaseCapture(&capture);  
  
    return 0;  

}  

8.4.1 说明

程序运行到最终转换完成,需要一段时间。如果程序运行之后,直接把窗口关掉——会发现的确新建成功了,但是转换之后的视频只有一小段。等待几分钟,然后才能彻底转换完成。

此外,注意到为什么把编码格式写成'M','J','P','G'?因为这个是无压缩的,直接windows操作系统的media player就可以播放了,如果是'X', 'V', 'I', 'D'格式,还要下载有编码解码的播放器才能播放,很累。但是,MJPG压缩完之后变得很大,原彩色视频只有40M,转换之后却有200M。但是,用XVID格式却只有78.8M

8.5 CvVideoWriter结构

CvVideoWriter应该就是用来创建一个用来存储视频的内存空间。

CvVideoWriter是一个类似于CvCapture的视频写入结构。

该结构与下面的函数一起使用:

CvVideoWriter * cvCreateVideoWriter (

const char* filename,

int fourcc,

double fps,

CvSize frame_size,

int is_color=1

);

 

int cvWriteFrame(

CvVideoWriter* writer,

const IplImage* image

);

 

cvReleaseVideoWriter(

CvVideoWriter** writer

);

你会注意到,相比视频读入,视频写入需要一些额外的参数。除了视频文件名称,我们需要告诉视频写入结构视频编码格式、帧率以及每一帧的大小。还可以告诉OpenCV图像是否彩色(默认为彩色)

这里,四个字符标记来表示编码格式。(不了解视频编码的读者此时只需知道这是一个标识编码的四字节惟一性标志)int类型的cvCreateVideoWriter()参数fourcc是将四个字符被打包在一个整数中。由于经常使用,OpenCV提供了一个宏CV_FOURCC(c0clc2c3)来实现这个打包操作。

视频写入结构建好之后,需要调用cvWriteFrame()函数,并且为cvWriteFrame()函数传入一个CvVideoWriter*指针和一个IplImage*指针来写入文件。

写人完成后,为了关闭写入结构,必须调用cvReleaseVideoWriter()函数。如果平时不习惯释放不再使用的空间和结构,对这个结构千万别偷懒,因为不显式地释放写入结构,视频文件可能会被损坏。

8.5.1 cvCreateVideoWriter()

定义:

CvVideoWriter * cvCreateVideoWriter ( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1 );

filename 输出视频文件名。

fourcc为 四个字符用来表示压缩帧的codec——就是一种压缩格式

例如:

CV_FOURCC('P','I','M','1') = MPEG-1 codec

CV_FOURCC('M','J','P','G') = motion-jpeg codec

CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec

CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec

CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec

CV_FOURCC('U', '2', '6', '3') = H263 codec

CV_FOURCC('I', '2', '6', '3') = H263I codec

CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

若编码器代号为 -1,则运行时会弹出一个编码器选择框.

fps 被创建视频流的帧率。

frame_size 视频流的大小。

is_color 如果非零,编码器将希望得到彩色帧并进行编码;否则,是灰度帧(只有在Windows下支持这个标志)。

所以,要想建立一个内存空间存储黑白视频,is_color必须是0

作用:

创建视频写入器结构。

8.5.2 CV_FOURCC

int类型的cvCreateVideoWriter()参数fourcc是将四个字符被打包在一个整数中。由于经常使用,OpenCV提供了一个宏CV_FOURCC(c0clc2c3)来实现这个打包操作。程序中使用的是:     CV_FOURCC('M','J','P','G'),

 

8.5.3 帧率

帧率(Frame rate)是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS)或“赫兹”(Hz)。此词多用于影视制作和电子游戏。

由于人类眼睛的特殊生理结构,如果所看画面之帧率高于24的时候,就会认为是连贯的,此现象称之为视觉暂留。

电视(PAL)帧率是25fps

8.6 fps

double cvGetCaptureProperty(CvCapture* capture,int property_id)默认是double类型,所以返回值也会是double类型。

8.7 cvConvertImage()图像格式转换

定义:

void cvConvertImage( const CvArr* src, CvArr* dst, int flags=0 );

src是源图像的IplImage指针;源图像可以是单个,3个或者4个通道

dst是转换后的图像的IplImage指针;目标图像必须8位的单通道或者3个通道

flags是转换的模式,可以取0:没有变化;

                         1:垂直翻转,即沿x轴翻转;

                         2:交换红蓝信道;

有时候摄像机图像格式与图像显示格式会反转,设置这个参数可以在内存中彻底旋转图像。

enum

{

    CV_CVTIMG_FLIP      =1,

    CV_CVTIMG_SWAP_RB   =2

};

8.7.1 辨析

cvConvertImage()cvCvtColor()相比,除了转换颜色,还多了反转图片的功能。

8.8 cvFlip()

    直接将图像采集卡采集的图像cvShowImage()出来的是反着的图像,也就是图像采集卡采集的图像是以左下角为原点的,而窗口显示的图像原点是左上角,相当于是关于X轴翻转了。在显示图像之前使用cvFlip()函数将图像翻转一下就可以了。

Flip

垂直,水平或即垂直又水平翻转二维数组

定义:

void cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0);

src

原数组——就是原图像

dst

目标责任制数组. 如果 dst = NULL 翻转是在内部替换.

flip_mode

指定怎样去翻转数组。

flip_mode = 0 沿X-轴翻转,

flip_mode > 0 (1) 沿Y-轴翻转,

flip_mode < 0 (-1) 沿X-轴和Y-轴翻转(即关于原点对称)。

8.9 cvWriteFrame()

定义:

int cvWriteFrame( CvVideoWriter* writer, const IplImage* image );

作用:

写入一帧到一个视频文件中

writer

视频写入器结构。

image

被写入的帧。

函数cvWriteFrame写入/附加到视频文件一帧。

返回:

成功返回1,不成功返回0

8.10 cvReleaseVideoWriter()

cvReleaseVideoWriter(&write);  

释放相应的CvVideoWriter空间


你可能感兴趣的:(opencv学习笔记(八)彩色视频转换成黑白视频)