• 第二章:Opencv核心類Mat


    Opecv就是做計算機視覺,就是讲图片转换成计算机所能识别的数据

    Mat类中由大量的内联函数,主要就是用于提高速度。

    一般类型都用rgb,存的时候用CV_8UC3.create函数一般会把原来的空间释放。释放由opencv自动管理。但有时需要手动释放。

     

    有时计算机会按照四字节对齐,所以step[0],表示二维矩阵中一行的字节数,只会比真正的实际存储的字节数多。

    添加计时器:

    #include <opencv2/opencv.hpp>
    #include <iostream>
    using namespace cv;
    using namespace std;
    void PrintMs(const char* test=""){
        static long long last=0;
        long long cur=getTickCount();
        if(last==0){
            last=cur;
            return;
        }
        long long ms;
        ms=(double)((cur-last)/getTickFrequency())*1000;
        if(*test!=0){
            cout<<"time : "<<ms<<endl;
        }
        last=getTickCount();
    }
    int main(int argc, char *argv[])
    {
        Mat mat(3000,4000,CV_8UC3);
        mat.create(3000,4000,CV_8UC3);
        int es=mat.elemSize();
        int size=mat.rows*mat.cols*es;
        cout<<mat.isContinuous()<<endl;
        PrintMs();
        for(int i=0;i!=size;i+=es){
            mat.data[i]=255;//B
            mat.data[i+1]=110;//G
            mat.data[i+2]=60;//R
        }
        PrintMs("mat");
        for(int i=0;i!=mat.rows;++i){
            for(int j=0;j!=mat.cols;++j){
                (&mat.data[i*mat.step[0]])[j*es]=0;//B
                (&mat.data[i*mat.step[0]])[j*es+1]=0;//G
                (&mat.data[i*mat.step[0]])[j*es+2]=0;//R
            }
        }
        PrintMs("Mat");
        namedWindow("mat");
        imshow("mat",mat);
        waitKey(0);
        return 0;
    }

    这种方法会抛出异常

        for(int i=0;i<mat.rows;++i){
            for(int j=0;j <mat.cols;++j){
                Vec3b* c=mat.ptr<Vec3b>(i,j);
                c->val[0]=0;//val[0]就是最基本的那个数据类型。c指向的是一个类
                c->val[1]=255;//G
                c->val[2]=0;
            }
        }
        PrintMs("mat");

     

    try{
        for(int i=0;i!=mat.rows;++i){
            for(int j=0;j!=mat.cols;++j){
                Vec3b& m=mat.at<Vec3b>(i,j);//返回的是一个引用。
                m[0]=100;
                m[1]=100;
                m[2]=100;
            }
        }}
        catch(Exception& ex){
            cout<<ex.what()<<endl;
        }

    for(int i=0;i!=mat.rows;++i){
            for(int j=0;j!=mat.cols;++j){
                Vec3s& m=mat.at<Vec3s>(i,j);
                //m[0]=0;
                //m[1]=0;
                //m[2]=100;
                m.val[0]=0;
                m.val[1]=0;
                m.val[2]=255;
            }
        }

    其中m[0]与m.val[0]是一样的。都代表最基本的那个数据类型。注意Vec3s对应着CV_16SC3

     

    添加OpenGL Widget,将其名称改为mat,class提升为MatView。

    编译运行出错,因为没有定义MatView.h

    MatView.h :

    #ifndef MATVIEW_H
    #define MATVIEW_H
    #include<QOpenGLWidget>
    class MatView:public QOpenGLWidget{
        Q_OBJECT
    public:
        MatView(QWidget* p);
        ~MatView(){}
        void paintEvent(QPaintEvent* e);
    };
    #endif // MATVIEW_H

    MatView.cpp   :

    #include"matview.h"
    #include<QImage>
    #include<QPainter>
    #include <opencv2/opencv.hpp>
    using namespace cv;
    void MatView::paintEvent(QPaintEvent* e){
        Mat src=imread("/home/ubuntu/Downloads/vn.jpg");
        cvtColor(src,src,COLOR_BGR2RGB);
        QImage img(src.data,src.cols,src.rows,QImage::Format_RGB888);
        QPainter painter;
        painter.begin(this);//clean
        painter.drawImage(QPoint(0,0),img);
        imwrite("/home/ubuntu/Downloads/nv.jpg",src);
    }
    MatView::MatView(QWidget* p):QOpenGLWidget(p){

    }

  • 相关阅读:
    C/C++ 构造函数不能是虚函数
    C/C++ STL迭代器失效
    Linux fork函数
    算法和数据结构 限流算法
    数据库 redis底层实现
    C/C++ 虚析构函数
    万物皆可 Serverless 之使用云函数 SCF 快速部署验证码识别接口
    万物皆可 Serverless 之使用云函数 SCF+COS 免费运营微信公众号
    腾讯云云函数 SCF 日志检索最佳实践
    江娱互动「世界争霸」产品迁移至腾讯云云函数的实践
  • 原文地址:https://www.cnblogs.com/invisible2/p/9096036.html
Copyright © 2020-2023  润新知