• OpenCV之Mat类使用总结


    #前言
    Mat 是Opencv中很常用的一个图像容器类,图像在计算机中的存储形式是二进制字节流,其本质的存储形式如下图所示;
    一张来自官方文档的图片
    而一张图片是由很多像素点组成,单个像素点又会因为图像格式的不同而不同。例如彩色的RBG或者灰度图像。而在OpenCV中,则可以抽象成一个顺序排列的内存区域,里面保存了图像的所有像素信息,这里用Mat类封装了这些图像的信息,包括图像大小,类型等等,大大地简化了我们处理和操作图像。
    #概念
    Mat 是一个类,从最早的OpenCV是C语言风格发展到现在的C++风格,它对面向对象的支持更加友好。相比较于之前C结构的IplImage,Mat有更多有优点;

    1. 内存的分配与释放更加安全;
    2. 使用Mat可以使代码更加简洁;
    3. 对于图像数据的处理更加高效;

    Mat基本上是一个包含两个数据部分的类:矩阵头(包含矩阵大小,用于存储的方法,存储矩阵的地址等信息)和指向包含矩阵的矩阵的指针。像素值(取决于选择存储的方法取任何维度)。矩阵头大小是恒定的,但是矩阵本身的大小可能随图像而变化,并且通常大几个数量级。OpenCV是一个图像处理库。它包含大量图像处理功能。为了解决计算挑战,大多数时候您最终会使用库的多个功能。因此,将图像传递给函数是一种常见的做法。我们不应该忘记我们正在讨论图像处理算法,这些算法往往计算量很大。我们要做的最后一件事是通过制作不必要的潜在大图像副本来进一步降低程序的速度。为解决此问题,OpenCV使用引用计数系统(Reference Counting System)。这个想法是每个Mat对象都有自己的头,但是矩阵可以通过让它们的矩阵指针指向同一个地址来共享它们的两个实例。此外,复制操作符只会将标题和指针复制到大矩阵,而不是数据本身。

    #实战

    1 基础操作

    1初始化

        //CV_8UC(n), ..., CV_64FC(n)
        Mat A(5,5,CV_64FC1,1);
        std::cout << "A= " << endl << " " << A << endl;
    
        Mat B(5,5,CV_64FC1,2);
        std::cout << "B= " << endl << " " << B << endl;
    
        Mat C(5,5,CV_64FC3,Scalar(6.0f,7.0f,8.0f));
        std::cout << "C= " << endl << " " << C << endl;
    
        Mat D = Mat::eye(3,3,CV_64F);
        std::cout << "D= " << endl << " " << D << endl;
        
        Mat E = Mat::ones(3,3,CV_64F);
        std::cout << "E= " << endl << " " << E << endl;
        
        Mat F = Mat::zeros(3,3,CV_64F);
        std::cout << "F= " << endl << " " << F << endl;    
    

    A=
    [1, 1, 1, 1, 1;
    1, 1, 1, 1, 1;
    1, 1, 1, 1, 1;
    1, 1, 1, 1, 1;
    1, 1, 1, 1, 1]
    B=
    [2, 2, 2, 2, 2;
    2, 2, 2, 2, 2;
    2, 2, 2, 2, 2;
    2, 2, 2, 2, 2;
    2, 2, 2, 2, 2]
    C=
    [6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8;
    6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8;
    6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8;
    6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8;
    6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8, 6, 7, 8]
    D=
    [1, 0, 0;
    0, 1, 0;
    0, 0, 1]
    E=
    [1, 1, 1;
    1, 1, 1;
    1, 1, 1]
    F=
    [0, 0, 0;
    0, 0, 0;
    0, 0, 0]

    2 读取图片

    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    int main(char argc,char** argv){
        cv::Mat img = cv::imread(argv[1],-1);
        if(img.empty()){
            return -1;
        }
        cv::imshow("Image",img);
        cv::waitKey( 0 );
        return 0;
    }
    

    3 图像ROI

    #include <iostream>
    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui.hpp>
    
    using namespace cv;
    using namespace std;
    
    int main(int argc,char* argv[]){
    
        Mat img_ori = imread(argv[1],IMREAD_COLOR);
        std::cout << "row is " << img_ori.rows << std::endl;
        std::cout << "col is " << img_ori.cols << std::endl;
    	// 取img_ori图像中坐标(0,0)为起点长50高50区域的图片
        Mat img_des = img_ori( Rect(0, 0, 50, 50));
        cv::namedWindow("img_des",cv::WINDOW_NORMAL);
        imshow("img_des",img_des);
        waitKey(0);
    }
    

    #参考:
    https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
    https://docs.opencv.org/3.1.0/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56

  • 相关阅读:
    网络摄像头监控中什么情况下需要使用流媒体转发服务器?
    流媒体播放器播放h264编码视频与h265编码视频哪个更清晰?
    RTMP推流视频流媒体服务如何实现网络传输?
    web视频直播服务器更改端口号后录像功能失效问题解决
    互联网视频直播/点播流媒体服务器使用http和rtmp做点播时有什么区别?
    视频互联网直播/点播服务器中关于内容分发CDN的相关问题汇总
    网页直播系统推流端和拉流端都有哪些环节?
    自建视频流媒体服务器需要满足哪些条件?
    线上课堂教育行业选择互动直播时有哪些直播方案?
    互联网直播点播平台在进行iframe直播分享时如何禁止本地视频自动播放?
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783423.html
Copyright © 2020-2023  润新知