一张图片的组成

  • 文件标识 + 数据块
  • 文件标识: 文件签名 维数 高度 宽度 深度 通道数 颜色格式 数据首地址 结束地址 数据量等等
  • 图像深度: 每个像素所用的比特数
  • 图像通道数: 灰度图的通道数为1. 彩色图为3

opencv源码结构学习

opencv基本架构分析

Mat的操作例子

#include <iostream>
#include <stdio.h>
#include <stdlib.h>


#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

void info(){
    std::cout<<"Please input parameter..."<<std::endl;
    std::cout<<"1-Function:Create zeros mat with 1 channel"<<std::endl;
    std::cout<<"2-Function:Create zeros mat with 3 channels"<<std::endl;
    std::cout<<"3-Function:Input image and output matrix values"<<std::endl;
    std::cout<<"4-Function:Copy a mat"<<std::endl;
    std::cout<<"5-Function:Deep copy a mat data"<<std::endl;
    std::cout<<"6-Function:Iterate  pixels in a mat"<<std::endl;
    std::cout<<"7-Function:Set ROI and editing"<<std::endl;

}

int main(int argc,char* argv[]){
    //没有输入参数
    if(argc==1){
        info();
        return 1;
    }

    switch(atoi(argv[1])){
        case 1:
            {
                std::cout<<"Function 1 : Create zeros mat with 1 channel"<<std::endl;
                //创建一个8*8,位数为8的单通道Mat
                cv::Mat mat(8,8,CV_8UC1);
                //将Mat置0,使得矩阵内所有像素值为0
                    mat.zeros(mat.size(),mat.type());
                //输出矩阵结果
                    std::cout<<mat<<std::endl;
                break;
            }

        case 2:
            {
                std::cout<<"Function 2 : Create zeros mat with 3 channels"<<std::endl;
                //创建一个8*8,位数为8的三通道Mat
                cv::Mat mat2(8,8,CV_8UC3);
                //同样将Mat置0,使得矩阵内所有像素值为0
                mat2.zeros(mat2.size(),mat2.type());
                //输出效果,和单通道的矩阵相比,数据量是单通道的三倍
                    std::cout<<mat2<<std::endl;
                break;
            }

        case 3:
            {
                std::cout<<"Function 3 : Input image and output matrix values"<<std::endl;
                //输入一张图,尺寸为图片原来的尺寸
                cv::Mat mat3 = cv::imread("lena.jpg");
                //修改这个图片Mat的使用尺寸
                cv::resize(mat3,mat3,cv::Size(8,8));
                //输出所有像素值
                std::cout<<mat3<<std::endl;
                break;
            }

        case 4:
            {
                std::cout<<"Function 4 : Copy a mat"<<std::endl;
                //输入一张图
                cv::Mat mat4 = cv::imread("lena.jpg");
                //浅拷贝一个Mat,浅拷贝只数据地址是公用的,所以修改其中一个Mat,两个Mat的值都会被修改
                cv::Mat mat4_1 = mat4;
                //垂直翻转图片
                cv::flip(mat4_1,mat4_1,1);
                //显示效果,两个Mat都被翻转了
                cv::imshow("mat4",mat4);
                cv::imshow("mat4_1",mat4_1);
                cv::waitKey(0);
                break;
            }

        case 5:
            {
                std::cout<<"Function 5 : Deep copy a mat data"<<std::endl;
                //输入一张图片
                cv::Mat mat5 = cv::imread("lena.jpg");
                //深拷贝一个Mat,数据完全复制,没有共用的部分,所以修改任意一个Mat,互不影响
                cv::Mat mat5_1;
                mat5.copyTo(mat5_1);
                //上下翻转矩阵
                cv::flip(mat5_1,mat5_1,0);
                //显示效果,只有一个是被翻转了,另个一不受影响
                cv::imshow("mat5",mat5);
                cv::imshow("mat5_1",mat5_1);
                cv::waitKey(0);
                break;
            }

        case 6:
            {
                std::cout<<"Function 6 : Iterate  pixels in a mat"<<std::endl;
                //输入一张图片
                                cv::Mat mat6 = cv::imread("lena.jpg");
                //重新定义尺寸
                cv::resize(mat6,mat6,cv::Size(8,8));
                //遍历每一个像素的值,可以看到和Function3,输出的结果一致
                for(int j=0;j<mat6.rows;j++){
                    for(int i=0;i<mat6.cols;i++){
                        std::cout<<(int)mat6.at<cv::Vec3b>(j,i)[0]<<", "<<(int)mat6.at<cv::Vec3b>(j,i)[1]<<", "<<(int)mat6.at<cv::Vec3b>(j,i)[2]<<", ";
                    }
                    std::cout<<std::endl;
                }
                break;
            }

        case 7:
            {
                std::cout<<"Function 7 : Set ROI and editing"<<std::endl;
                //输入一张图片
                cv::Mat mat7 = cv::imread("lena.jpg");
                //设置ROI位置
                cv::Rect roi(mat7.cols/4,mat7.rows/4,mat7.cols/2,mat7.rows/2);
                cv::Mat mat7_roi = mat7(roi);
                //垂直翻转,这时候,对ROI的任意操作都是在修改原图的基础上操作的
                cv::flip(mat7_roi,mat7_roi,1);
                //显示原图,ROI的部分被修改了
                cv::imshow("mat7",mat7);
                cv::waitKey(0);
                break;
            }

        default:
            {
                info();
                break;
            }

    }
    return 0;

}

视频的读取与控制

  • 视频相关操作使用的是: cv::VideoCapture
  • 获得视频的相关信息
    eg.
    获取当前视频帧率 double rate = capture.get(CV_CAP_PROP_FPS);获取总帧数: int frame_num = capture.get(CV_CAP_PROP_POS_FRAMES);
  • 视频操作的框架代码
#include <iostream>



#include <opencv2/core/core.hpp>


#include <opencv2/highgui/highgui.hpp>


#include <opencv2/imgproc/imgproc.hpp>


int main(int argc,char* argv[]){
//capture直接定义视频文件路径,如果路径设置为0,则读取电脑摄像头的数据
//cv::VideoCapture capture(0);
cv::VideoCapture capture(argv[1]);
if(!capture.isOpened()){
    std::cout<<"video not open."<<std::endl;
    return 1;
}
//获取当前视频帧率
double rate = capture.get(CV_CAP_PROP_FPS);
//当前视频帧
cv::Mat frame;
//每一帧之间的延时
//与视频的帧率相对应
int delay = 1000/rate;
bool stop(false);
while(!stop){
    if(!capture.read(frame)){
        std::cout<<"no video frame"<<std::endl;
        break;
    }

    /*
     *
     * 此处为添加对视频的每一帧的操作方法
     *
     */

    cv::cvtColor(frame,frame,CV_RGB2GRAY);

    cv::imshow("video",frame);
    //引入延时
    //也可通过按键停止
    if(cv::waitKey(delay)>0)
        stop = true;
}
//关闭视频,手动调用析构函数(非必须)
capture.release();
return 0;
}
  • 保存视频: VideoWriter 用来保存视频
cv::VideoWriter writer;

初始化: 要指定哪些数据呢?

writer.open("VideoOutput.avi",CV_FOURCC('M','J','P','G'),rate,cv::Size(frame.cols,frame.rows));
// 函数原型
CV_WRAP virtual bool open(const string& filename, int fourcc, double fps,Size frameSize, bool isColor=true);
  • 输出文件名 格式 帧率 帧的大小 默认为彩色图
  • 保存视频的源代码学习:
#include <iostream>



#include <opencv2/core/core.hpp>


#include <opencv2/highgui/highgui.hpp>



int main(int argc,char* argv[]){
cv::VideoCapture capture(argv[1]);
if(!capture.isOpened()){
    std::cout<<"video not open."<<std::endl;
    return 1;
}
//获取当前视频帧率
double rate = capture.get(CV_CAP_PROP_FPS);
//当前视频帧
cv::Mat frame;
//每一帧之间的延时
//与视频的帧率相对应
int delay = 1000/rate;
bool stop(false);

//创建VideoWriter做保存视频
cv::VideoWriter writer; 
bool writer_init(false);

while(!stop){
    if(!capture.read(frame)){
        std::cout<<"no video frame"<<std::endl;
        break;
    }
    if(!writer_init){
        writer.open("VideoOutput.avi",CV_FOURCC('M','J','P','G'),rate,cv::Size(frame.cols,frame.rows));
        writer_init = true;
    }

    /*
     *
     * 此处为添加对视频的每一帧的操作方法
     *
     */

    //写入保存视频
    writer<<frame;

    cv::imshow("video",frame);
    //引入延时
    //也可通过按键停止
    if(cv::waitKey(delay)>0)
        stop = true;
}
//关闭视频,手动调用析构函数(非必须)
capture.release();
return 0;
}