opencv笔记 | 图片/视频读入

一张图片的组成

  • 文件标识 + 数据块
  • 文件标识: 文件签名 维数 高度 宽度 深度 通道数 颜色格式 数据首地址 结束地址 数据量等等
  • 图像深度: 每个像素所用的比特数
  • 图像通道数: 灰度图的通道数为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);
                //Mat0,使得矩阵内所有像素值为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);
                //同样将Mat0,使得矩阵内所有像素值为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;
    }

猜你喜欢

转载自blog.csdn.net/qjh5606/article/details/80376643
今日推荐