OpenCV基本数据类型:Vec,Point,Rect,Scalar,Size,Matx,Mat等

基本数据类型

  1. cv::Vec类

    cv::Vec<>固定向量类,不同与STL的vector是动态向量,更像是STL的array,长度固定;如cv::Vec ivec6;
    有已经内置的别名:cv::Vec{2,3,4,6}{b,w,s,i,f,d}

    cv::Vec{2,3,4,6}{b,w,s,i,f,d}
    //内置的类型重命名:typedef Vec Vec3b
    //b  unsigned char 常用
    //i  int    常用
    //f  float  常用
    //w  unsigned short
    //s  short
    //d  double
    

    声明格式如下:

    cv::Vec<float,3> vec1;
    cv::Vec3b vec2;  //默认构造函数
    cv::Vec3f vec3(vec4); //拷贝构造
    cv::Vec3f vec3(x0,x1,x2);   //值构造
    //*********************成员访问,下标,和C++的数组很像
    vec3[i];vec3(i)//中括号,小括号都可以,都被重载了
    vec3.cross(vec4); //叉乘
    
  2. cv::Point类 二维或者三维点

    cv::Point类不是从cv::Vec继承过来的,它访问成员不是用下标,而是.x, .y访问,也有如下别名:分别对应二维和三维的整型和浮点型的点
    cv::Point2i, cv::Point2f, cv::Point2d, cv::Point3i, cv::Point3f, cv::Point3d

    cv::Point3i p1;  //默认构造函数
    cv::Point3i p2(p1);  //拷贝构造函数
    cv::Point3i p3(x0,x1,x2);  //值构造函数
    //******************************
    int x=p3.x, y=p3.y, z=p3.z;  //成员的访问,类似是个结构对象
    float x=p2.dot(p3);  //点乘
    p1.cross(p2)  //叉乘,三维的才有,二维没有
    p.inside(r); //点在矩形内
    
  3. cv::Scalar类,四维点,四元数,元素都是double型

    cv::Scalar s; //默认构造函数
    cv::Scalar s2(s1); //拷贝构造函数
    cv::Scalar s(x0,x1,x2,x3);  //值构造函数
    s1.mul(s2);   //元素相乘
    s.conj(); //共轭(return cv::Scalar(x0,-x1,-x2,-x3))
    s.isReal();  //(return true, if s1==s2==s3==0)
    
  4. cv::Size类
    二维的数,表示矩阵的尺寸嘛,肯定长和宽啦,和Point类似不是用下标取值,是用.width, .height

    cv::Size sz;//默认构造函数 和Size2i一样
    cv::Size2i sz;
    cv::Size2f sz;
    cv::Size sz2(sz);  //拷贝构造函数
    cv::Size sz(w,h);  //值构造函数
    //*****************************
    sz.width; sz.height ///访问成员
    sz.area(); //return sz.width*sz.height
    
  5. cv::Rect类 矩形类,包含Point(左上角)和Size(尺寸)

    cv::Rect r; //默认构造函数
    cv::Rect r2(r1);  //拷贝构造
    cv::Rect r2(x,y,w,h);  //值构造
    cv::Rect r(p,sz);  //Point和Size
    cv::Rect r(p1,p2); //两个Point
    //**********************访问成员
    r.x; r.y; r.width; r.height; //来自Point的x,y,来自Size的width,hwight
    r.area(); //面积
    r.tl(); //左上角
    r.br(); //右下角
    r.contains(p); //判断点在矩形内
    
  6. RotatedRect类 带旋转角度的矩形,不常用

  7. cv::Matx类
    cv::Matx<> 固定矩阵类,用于小型矩阵,如22,33;如cv::Matx<5,5,float>,注意,竟然是尺寸在前,类型在后,和Vec不一样; 也有别名cv::Matx{1,2,3,4,6}{1,2,3,4,6}{f,d}, 因为是固定尺寸,所以效率比cv::Mat高;
    当提前就知道矩阵尺寸的时候,就用cv::Matx,不知道尺寸的大型矩阵,再用cv::Mat

    cv::Matx34f m34f; //默认构造函数
    cv::Matx22d m22d(n22d);  //拷贝构造
    cv::Matx33d m33d(x0,x1,x2,x3,x4,x5,x6,x7,x8); //值构造
    cv::Matx33f m33f=cv::Matx33f::all(x); //元素一样的矩阵,类的静态成员函数
    cv::Matx33f m33f=cv::Matx33f::zeros(); //元素全为0
    cv::Matx33f m33f=cv::Matx33f::ones(); //元素全为1
    cv::Matx33f m33f=cv::Matx33f::eye(); //单位矩阵
    //************************成员访问
    m33f(i,j),m31f(i);  //用小括号,不是下标,在C++少见
    m91f=m33f.reshape<9,1>();  //reshape 
    //**********************************************/
    m41f=m44f.row(i);  //**********第i行
    m41f=m44f.col(j);  //********第j列
    m44f.diag();  //取对角
    m44f.t();  //*****************转置******
    m44f.inv();  //************求逆*********
    m1.mul(m2);  //每个元素乘
    

大型动态矩阵类型

  1. cv::Mat类
    OpenCV的C++实现的核心,几乎所有函数都是:cv::Mat的成员,或者将cv::Mat作为参数,或者返回一个cv::Mat类型;
    cv::Mat用于表示任意维度的稠密数组。OpenCV中图像的存储方式就是cv::Mat大型矩阵,有单通道或者三通道等等。
    cv::Mat中的元素可以是一个数字,也可以包含多个数字,此时是“多通道数组”。
    数据类型:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}。比如CV_32FC3表示三通道的32位浮点数;CV_8UC3常用.

    cv::Mat m;//默认构造函数,没有指明存储数据类型和矩阵大小
    m.create(3,10,CV_32FC3);  //.create()成员函数,指定行数,列数,数据类型
    //常用
    cv::Mat m(int rows, int cols, int type);
    // cv::Mat(rows,cols,type,初始化);
    cv::Mat m(3,4,CV_32FC3,cv::Scalar(0,1,2)); //每个数据元素的三通道都是[1,2,3]
    //则  m.at(2,3) = [1,2,3]
    cv::Mat m(cv::Size sz, int type);  //Size是宽cols,高rows
    cv::Mat m(cv::Size(640,480),CV_8UC1);
    //有时候初始化小型矩阵  类型是CV_32FC1,4行2列
    cv::Mat mat = (cv::Mat_<float>(4,2)<<0,1,2,3,4,5,6,7);
    // 注意****************是浅拷贝,只是指针指向m1;修改了m2则m1也变了
    cv::Mat m(const Mat& mat);  //复制构造*******浅复制
    cv::Mat m2(m1);
    //或者
    cv::Mat m2=m1;
    //*******************************************************
    
    cv::Mat m = cv::Mat::zeros(rows,cols,type);
    cv::Mat m = cv::Mat::ones(rows,cols,type);
    cv::Mat m = cv::Mat::eye(rows,cols,type);
    
    //   访问数据  .at<>(,)
    cv::Mat m=cv::Mat::eye(10,10,32FC1);
    m.at<float>(3,3);
    cv::Mat m1=cv::Mat::eye(10,10,32FC3);
    m1.at<cv::Vec3f>(3,3);  //是个cv::Vec3f
    m1.at<cv::Vec3f>(3,3)[0];
    m1.at<cv::Vec3f>(3,3)[1];
    m1.at<cv::Vec3f>(3,3)[2];
    //  访问数据,迭代器
    cv::MatIterator_<float> it=m.begin<float>();  //*it
    auto it=m.end<float>();
    
    //访问图像第row行,第col列,第c通道的数据
    image.at<Vec3b>(row,col)[c]  //前提得知道: 3通道,unsigned char
    image.data[row*image.step + col*image.channels() + c] //image.step 一行占用的最小元素个数
    

    访问区块(也都是浅拷贝,只是指针指向了那里)

    cv::Mat m(10,20,CV_8UC1,0);
    m.row(i);  //第i行
    m.col(j);  //第j列
    m.rowRange(i0,i1); //i0到i1-1行
    m.colRange(j0,j1); //j0到j1-1列
    m.diag(d);//偏移为d的对角元素数组
    m(cv::Range(i0,i1),cv::Range(j0,j1)); //矩阵内的数组
    m(cv::Rect(i0,i1,w,h)); 矩阵内的,起点,长高
    

    cv::Mat的运算操作

    m1+m2; m1-m2;  //矩阵加减法,矩阵尺寸要一样
    m1+num; m1-num; //矩阵加减单个数
    num*m1; //矩阵乘以一个数
    m1.mul(m1); //两个矩阵按元素相乘
    m1*m2;  //矩阵乘法
    m1.inv();//对矩阵求逆
    m1.t(); //转置
    m1>m2;  //按元素比较,返回值只有0或255
    m1&m2; m1|m2; ~m1;//与或非
    min(m1,m2);max(m1,m2);  //按元素
    cv::abs(m1);//绝对值
    cv::norm();
    cv::mean();
    cv::sum();
    //等等
    

    深拷贝
    m2=m1是浅拷贝,m2只是数组头,指向m1,同一个数据,修改m2影响m1;
    深拷贝如下:

    //两个一样,用第一个就好
    m2=m1.clone();
    m1.copyTo(m2);
    

    .reshape(channel, row) 通道数:0表示不变, 行数:0表示不变

    cv::Mat m1(2,50,CV_8UC1,1);
    cv::Mat m2=m1.reshape(0,10); //通道数不变,尺寸变成10*10
    

示例

1、对cv::Mat操作,获取值,赋值; 1、位置.at<>() ;2、迭代器cv::MatIterator_<> .begin<>() .end<>()

#include
#include
using namespace std;
int main(int argc,char** argv)
{
	cv::namedWindow("Window1",cv::WINDOW_AUTOSIZE);

	cv::Mat m1(3,4,CV_8UC3,cv::Scalar(1,2,3));  //三行四列,三通道八位unsigned char,都初始化为[1,2,3]

	cout<<"channels = "<<m1.channels()<<endl;  //通道数:3
	cout<<"size = "<<m1.size()<<endl;   //size: 4*3 是宽和高,不是行和列
	cout<<"width = "<<m1.cols<<endl<<"height = "<<m1.rows<<endl;  //rows:3  cols:4
	cout<<"m1.at(2,3) = "<<m1.at<cv::Vec3f>(2,3)<<endl;

	cv::Mat m2(4,4,CV_8UC1,8);  //四行四列,单通道八位unsigned char, 都初始化为8
	cout<<"m2 = "<<endl<<m2<<endl;
	cv::Size sz=m2.size();  //sz=[4 * 4]
	int num=sz.area();  //16
	//用.at<>()获取每个元素,修改每个元素
	for(int i=0;i<num;i++)
		m2.at<uchar>(i)=i+1;
	cout<<"m2 = "<<endl<<m2<<endl;
	
	//用迭代器cv::MatIterator_<> 获取每个元素,修改每个元素
	cv::MatIterator_<uchar> it=m2.begin<uchar>();
	int i=16;
	for(;it!=m2.end<uchar>();it++)
	{
		*it=i;
		i--;
	}
	cout<<"m2 = "<<endl<<m2<<endl;
	
	return 0;
}

2、取cv::Mat数据块(范围)

#include
#include
using namespace std;
int main(int argc,char** argv)
{
	cv::Mat m(10,20,CV_8UC1,(unsigned char)0);
	cout<<"0 = "<<endl<<m<<endl;

	int i=1;
	for(auto it=m.begin<uchar>();it!=m.end<uchar>();it++)  //迭代器赋值
	{
		*it=i;
		i++;
	}
	cout<<"i = "<<endl<<m<<endl;
	//单行,列
	cout<<"m.row(2) = "<<endl<<m.row(2)<<endl;
	cout<<"m.col(1) = "<<endl<<m.col(1).t()<<endl;  //转置,不然是按列显示的
	//行范围,列范围	
	cout<<"m.rowRange(1,3) = "<<endl<<m.rowRange(1,3)<<endl;
	cout<<"m.colRange(1,3) = "<<endl<<m.colRange(1,3).t()<<endl;
	//对角
	cout<<"m.diag() = "<<endl<<m.diag()<<endl;
	//矩形范围内,以下两个效果相同
	cout<<"m(cv::Rect(1,1,5,5) = "<<endl<<m(cv::Rect(1,1,5,5))<<endl; //cv::Rect()矩形
	cout<<"m(cv::Range(1,6),cv::Range(1,6) = "<<endl<<m(cv::Range(1,6),cv::Range(1,6))<<endl;  //两个cv::Range()范围

	return 0;
}
#运行结果
0 = 
[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]
i = 
[  1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20;
  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40;
  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60;
  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80;
  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 100;
 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120;
 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140;
 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160;
 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180;
 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200]
m.row(2) = 
[ 41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60]
m.col(1) = 
[  2,  22,  42,  62,  82, 102, 122, 142, 162, 182]
m.rowRange(1,3) = 
[ 21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40;
  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60]
m.colRange(1,3) = 
[  2,  22,  42,  62,  82, 102, 122, 142, 162, 182;
   3,  23,  43,  63,  83, 103, 123, 143, 163, 183]
m.diag() = 
[  1,  22,  43,  64,  85, 106, 127, 148, 169, 190]
m(cv::Rect(1,1,5,5) = 
[ 22,  23,  24,  25,  26;
  42,  43,  44,  45,  46;
  62,  63,  64,  65,  66;
  82,  83,  84,  85,  86;
 102, 103, 104, 105, 106]
m(cv::Range(1,6),cv::Range(1,6) = 
[ 22,  23,  24,  25,  26;
  42,  43,  44,  45,  46;
  62,  63,  64,  65,  66;
  82,  83,  84,  85,  86;
 102, 103, 104, 105, 106]

你可能感兴趣的:(计算机视觉,opencv,计算机视觉,c++)