在OpenCV中我们处理视频是先将视频保存成图像,然后再处理图像,将处理完的图像再生成视频这样子操作的。但是OpenCV中常见的图像操作有关容器有Mat,cvMat,IplImage等。在这些中,我们在选择的时候应该将哪一种作为处理图像的容器呢?
- Mat类型较CvMat与IplImage类型来说,有更强的矩阵运算能力,支持常见的矩阵运算。Mat类型侧重于计算,数学性高,OpenCV对Mat类型的计算也进行了优化。在计算密集型的应用当中,将CvMat与IplImage类型转化为Mat类型将大大减少计算时间花费。
- CvMat和IplImage类型更侧重于“图像”,OpenCV对其中的图像操作(缩放,单通道提取,图像阈值操作等)进行了优化。
- CvMat和IplImage的定义是结构体,而Mat的定义是类。从类型上就使得他们有很大的区别。结构体大多都是成员变量,而类中有成员变量、成员函数和重载函数。所以Mat利用自身的一些成员函数就可以进行很多的处理,但是CvMat和IplImage还需要一些辅助的函数去处理图片。
接下来再简单看一下如何初始化定义这三种类型的图像。
- Mat
Mat image = imread(const string& filename, intflags = 1);
第二个参数定义的是指定一个加载图像的颜色类型。取0时为灰度图;取1时为彩色图像;取2时,若载入的图像的深度为16位或者32位,就返回对应深度的图像,否则,就转换为8位图像再返回;取4时,代表保持颜色通道不变。
CvMat* image = cvCreateMat(int rows, int cols, int type);
IplImage* image = cvLoadImage(const char* filename, int iscolor = 1)
这里需要注意一点,当使用完定义的CvMat和IplImage时,得需要分别使用cvReleaseImage(&image)、cvReleaseMat(&image)将其所占用的内存给释放。
我们在检测的过程中,需要对检测目标进行框选,这个时候就需要用到OpenCV中画矩形的函数,下面介绍一下这两个函数
- cvRectangle
void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness = 1, int line_type=8, int shift=0)
参数介绍:
1. img 需要输入的图像,这里需要是由IplImage或CvMat所定义的图像。
2. pt1 矩形的一个顶点。
3. pt2 矩形对角线上的另一个顶点。
4. 由CvScalar所定义的color颜色,CvScalar是一个可以用来存放4个double数值的数组。如果是三维数组则为彩色线条,如果是一维数组则是灰度图像。
5. thickness是组成矩形线条的粗细程度。如果取-1的话会将矩形框填充满所取的颜色。
6. line_type边框的线型(8-8邻接连接线,4-4邻接连接线,CV_AA-antialiased线条),不过这三种线条在画出来之后基本看不到什么区别,一般默认用8.
7. shift-坐标点的小数点位数。
- rectangle
void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
void rectangle(Mat& img, Rect rec, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
rectangle里面的参数跟上面所讲的基本一样,只是这里面需要注意输入的图片得是由Mat定义的即可,除了直接输入矩阵对角线的两个点之外,也可以通过Rect进行定义
再画出检测框之后,我们还需要显示出目标的类别,这就需要我们使用putText函数在图片上添加文字
- PutText
void putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false)
参数介绍
1. img 需要将文字输入的图像名
2. text 需要显示的文字
3. org 文字在图像中左下角坐标
4. fontFace 字体类型,可选字体(ONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN, FONT_HERSHEY_DUPLEX,FONT_HERSHEY_COMPLEX, FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL,FONT_HERSHEY_SCRIPT_SIMPLEX,orFONT_HERSHEY_SCRIPT_COMPLEX,以上所有类型都可以配合 FONT_HERSHEY_ITALIC使用,产生斜体效果。)一共有0——7个int数字可以选择。
5. fontScale 字体大小,该值和字体内置大小相乘得到字体大小。
6. color 文本颜色
7. thickness 写字的线的粗细
8. lineType 线的类型
9. bottomLeftOrigin -true时,图像数据原点在左下角. -false 图像数据原点在左上角.
OpenCV将它的定义写在了highgui.hpp文件中,我们可以先查看一下这个类中都定义了什么成员函数
class CV_EXPORTS_W VideoCapture
{
public:
CV_WRAP VideoCapture();
CV_WRAP VideoCapture(const string& filename); //读取视频文件
CV_WRAP VideoCapture(int device); //打开摄像头,一般默认为0
virtual ~VideoCapture();
CV_WRAP virtual bool open(const string& filename); //另一种添加打开视频文件的方式
CV_WRAP virtual bool open(int device); //打开摄像头,一般默认为0
CV_WRAP virtual bool isOpened() const; //判断视频是否打开
CV_WRAP virtual void release(); //在程序结束的时候需要运行这个函数释放内存
CV_WRAP virtual bool grab();
CV_WRAP virtual bool retrieve(CV_OUT Mat& image, int channel=0);
virtual VideoCapture& operator >> (CV_OUT Mat& image);
CV_WRAP virtual bool read(CV_OUT Mat& image); //读取视频
CV_WRAP virtual bool set(int propId, double value); //读取视频时的一些设置
CV_WRAP virtual double get(int propId); // 得到所添加视频中的大部分信息
protected:
Ptr cap;
};
可以有两种方式打开视频
1. VidoeCapture capture(); capture.open("filename");
2. VideoCapture capture("filename");
在打开视频之后我们就可以定义一个Mat,然后利用read函数去读取视频,但是在这之前还需要用set函数去设置一些参数
capture.set(CV_CAP_PROP_POS_FRAMES,0); //设置视频从第0帧开始读取
Mat frame;
capture.read(frame); //读取视频的当前帧到Mat frame中
imshow("video",frame); waitKey(0); //读取视频
我们还可以利用capture.get()获得视频中的很多信息,下面列出一些OpenCV里的一些宏定义,这些都可以利用get或set成员函数来设置或获取
#define CV_CAP_PROP_POS_MSEC 0 //以毫秒计算的当前的位置
#define CV_CAP_PROP_POS_FRAMES 1 //以帧计算当前的位置
#define CV_CAP_PROP_POS_AVI_RATIO 2 //视频的相对位置,从0到1前面这三个参数应该是跟视频播放,读取相关的动态信息
#define CV_CAP_PROP_FRAME_WIDTH 3 //帧宽
#define CV_CAP_PROP_FRAME_HEIGHT 4 //帧高度
#define CV_CAP_PROP_FPS 5 //帧率
#define CV_CAP_PROP_FOURCC 6 //4 字符编码方式
#define CV_CAP_PROP_FRAME_COUNT 7 //视频帧数
#define CV_CAP_PROP_FORMAT 8 //视频格式
#define CV_CAP_PROP_MODE 9 //后端指定值指示当前捕捉的模式.
#define CV_CAP_PROP_BRIGHTNESS 10 //图像亮度 (只对摄像头).
#define CV_CAP_PROP_CONTRAST 11 //图像对比度(只对摄像头).
#define CV_CAP_PROP_SATURATION 12 //图像饱和度(只对摄像头).
#define CV_CAP_PROP_HUE 13 //色调(只对摄像头)
#define CV_CAP_PROP_GAIN 14 //增益(只对摄像头)
#define CV_CAP_PROP_EXPOSURE 15 //曝光(只对摄像头)
#define CV_CAP_PROP_CONVERT_RGB 16 //布尔型标记图像是否应该被转换为RGB.
#define CV_CAP_PROP_WHITE_BALANCE 17 //白平衡
#define CV_CAP_PROP_RECTIFICATION 18 //立体相机的矫正标记