OpenCV Mat的基本操作

Mat 矩阵创建

方法1. 使用Mat()构造函数

cv::Mat M1(2,2,CV_8UC3,Scalar(0,0,255))

这个函数的意思是,创建了一个名为M1的Mat,该Mat的尺寸为2,2,类型
为CV_8UC3,即8位uchar类型,该Mat通道数为3。这个mat的每一个元素
包含了3个通道或者说3个数值。然后用0,0,255为每一个元素赋值。
这里8位uchar型的取值为0~255,实际上如果一个Mat是用来表示RGB图像
的时候应该声明为CV_8UC3型

Mat型可以定义各种类型,可按F12快捷键查看头文件中的定义。定义的方式如下:CV_(位数)+(数据类型)+(通道数)
如CV_32FC1表示32位float型数据,有如下类型

  • CV_8UC1
  • CV_8UC2
  • CV_8UC3
  • CV_8UC4
  • CV_8SC1
  • CV_8SC2
  • CV_8SC3
  • CV_8SC4
  • CV_16UC1
  • CV_16UC2
  • CV_16UC3
  • CV_16UC4
  • CV_16SC1
  • CV_16SC2
  • CV_16SC3
  • CV_16SC4
  • CV_32SC1
  • CV_32SC2
  • CV_32SC3
  • CV_32SC4
  • CV_32FC1
  • CV_32FC2
  • CV_32FC3
  • CV_32FC4
  • CV_64FC1
  • CV_64FC2
  • CV_64FC3
  • CV_64FC4

方法2:使用create()函数,代码如下

cv::Mat M3;
M3.create(3,4,CV_8UC3);

表示首先声明一个mat型,名叫M3,其尺寸为3行,4列。

方法3: 使用内置函数初始化

  • 全初始化为0
Mat initZero=Mat::zeros(2,2,CV_32F);
  • 全初始化为1
Mat initOne= Mat::ones(2,2,CV_32F);
  • 全初始化为对角阵
Mat initEye=Mat::eye(2,2,CV_32F);

Mat 矩阵复制

1. 浅复制

cv::Mat srcM(2,2,CV_8UC3,Scalar(0,0,255))
cv::Mat dstM;
dstM=srcM;

表示首先声明一个mat名为 srcM,并初始化。然后声明一个mat名为dstM通过“=”把srcM复制给dstM。这样生成的矩阵,只是新生成一个矩阵头,dstM的data依然指向矩阵srcM的data,类似C++中的浅拷贝。
:

2. 深复制

cv::Mat srcM(2,2,CV_8UC3,Scalar(0,0,255))
cv::Mat dstM;
srcM.copyTo(dstM);

通过copyTo函数,可以实现深复制。也就是dstM是一个全新的矩阵,他在内存中的地址和srcM是不一样的。另外copyTo函数还可以加上掩模参数

Mat 矩阵复制遍历

当我们想读取或者修改Mat的任意内容时候,可以用以下方式访问Mat。

1. 利用指针.ptr

int height= image.rows; //行数
Int width = image.cols * image.channels(); //每行元素的总元素数量
for (int j=0; j(j);
for (int i=0; i

2.利用.at

遍历3通道的RGB图像

int height= image.rows; //行数
Int width = image.cols ; //每行元素的总元素数量
for (int j=0; j(j,i)[0]= image.at(j,i)[0]/div*div + div/2;
image.at(j,i)[1]= image.at(j,i)[1]/div*div + div/2;
image.at(j,i)[2]= image.at(j,i)[2]/div*div + div/2;
//-------------结束像素处理------------------------
} //单行处理结束
}

遍历单通道的灰度图

int height= image.rows; //行数
Int width = image.cols * image.channels(); //每行元素的总元素数量
for (int j=0; j(j,i)= image.at(j,i)/2;
//-------------结束像素处理------------------------
} //单行处理结束
}

3.利用迭代器

Mat M = Mat(100, 150, CV_8UC3);
cout << "rows=" << M.rows << ",cols=" << M.cols << endl;

Mat_::iterator it = M.begin();//初始位置的迭代器
Mat_::iterator itend = M.end();//终止位置的迭代器
for (; it != itend; it++)
{
    //处理BGR三个通道
    (*it)[0] = 182;//B
    (*it)[1] = 194;//G
    (*it)[2] = 154;//R
}

Mat 数学运算

Mat 加减乘除

相同类型的Mat 矩阵可以直接使用运算符进行加减乘除,其中代码矩阵对应位置的元素进行加减乘除

#include 
#include 
#include 
using namespace std;
using namespace cv;
int main() {
    Mat a=(Mat_(2,2)<<1,1,1,1);
    Mat b=(Mat_(2,2)<<1,2,3,4);
    Mat show;
    //1.add 
    //show=r.rows(0);
    show=a+b;
    cout<
结果如下:
[2, 3;
  4, 5]
[0, -1;
  -2, -3]
[4, 6;
  4, 6]
[1, 0.5;
  0.33333334, 0.25]

Mat 位运算

mat的位运算包含与或非、异或操作等。

  • 按位与:bitwise_and
  • 按位或:bitwise_or
  • 按位异或:bitwise_xor
  • 按位非:bitwise_not

Mat 矩阵求逆和求转置

  • 用inv()求逆
  • 用t()求转置
#include 
#include 
using namespace std;
using namespace cv;
int main() {
    Mat r=(Mat_(2,2)<<1,1,0,2);
    cout<

你可能感兴趣的:(opencv,opencv,计算机视觉,人工智能)