图像处理过程中,对图像矩阵的每一个元素进行操作是十分重要的。
本博文对OpenCV中的Mat矩阵的操作做了一次总结,方便我自己查阅。
Mat 基础
在计算机中,图像在本质上是一个数组。Mat就是图像在OpenCV中的表现形式。
基本属性
cols:矩阵列数
rows:矩阵行数
channels:通道数
type:数据类型
total:矩阵总元素数
data:指向矩阵数据块的指针
type
图像像素的类型。
cols rows channels total data
指针未显示,但已占位置。
Mat的创建
建立矩阵必须指定其存储的数据类型,常见的几种如下:
CV_8UC1// 8位无符号单通道
CV_8UC3// 8位无符号3通道
CV_8UC4
CV_32FC1// 32位浮点型单通道
CV_32FC3// 32位浮点型3通道
CV_32FC4
创建方法:
cv::Mat a(cv::Size(5,5),CV_8UC1);//单通道
cv::Mat b = cv::Mat(cv::Size(5,5),CV_8UC3); //3通道
初始化方法:与matlab类似,都有相应的函数
cv::Mat z = cv::Mat::zeros(cv::Size(5,5),CV_8UC1); // 全零矩阵
cv::Mat o = cv::Mat::ones(cv::Size(5,5),CV_8UC1); // 全1矩阵
cv::Mat e = cv::Mat::eye(cv::Size(5,5),CV_32FC1); // 对角线为1的对角矩阵
遍历Mat元素
at(i,j)
Mat类为我们提供了at方法,它是一个模板函数,可以获取到任何类型的图像上的点。
image.at<uchar>(i,j)//取出灰度图像第i行j列的点
image.at<Vec3b>(i,j)[k]//取出彩色图像中i行j列第k通道的点
用这种方法比较慢
指针遍历图像
for(int i = 0; i < image.rows; i++){
uchar* inData = image.ptr<uchar>(i);//获取第i行的指针
for(int j = 0; i < image.cols; j++){
cout<<*inData++;
}
}
比较高效的方法
特殊情况
OpenCV存储行时有可能是不连续的,所以读取时只能一行一行读。不过OpenCV提供了在isContinuous()
来判断image存储是否是连续,连续为true,不连续为false。如果连续,就可以将数据看成一行了。
如果不是就按上面的来,这是最高效的做法。
迭代器遍历
这种方法的优点是足够安全。
矩阵运算
矩阵加减法
cv::Mat a= Mat::eye(Size(3,2), CV_32F);
cv::Mat b= Mat::ones(Size(3,2), CV_32F);
cv::Mat c= a+b;
cv::Mat d= a-b;
矩阵乘除法
Mat m1= Mat::eye(2,3, CV_32F);
Mat m2= Mat::ones(3,2, CV_32F);
// Scalar by matrix
cout << "\nm1.*2 = \n" << m1*2 << endl;
// matrix per element multiplication
cout << "\n(m1+2).*(m1+3) = \n" << (m1+1).mul(m1+3) << endl;
// Matrix multiplication
cout << "\nm1*m2 = \n" << m1*m2 << endl;
矩阵转置
Mat m1= Mat::eye(2,3, CV_32F);
Mat m1t = m1.t();
矩阵的逆
Mat meinv = me.inv();
矩阵的非零元素个数
int nonZerosNum = countNonZero(me);
均值和标准差
Mat mean;
Mat stddev;
meanStdDev(me, mean, stddev); //me为前文定义的5×5对角阵
cout<<"mean = "<<mean<<endl;
cout<<"stddev = "<<stddev<<endl;
最大最小值
void minMaxLoc(InputArray src, CV_OUT double* minVal,
CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
CV_OUT Point* maxLoc=0, InputArray mask=noArray());
参数:
- src – 输入单通道矩阵(图像)
- minVal – 指向最小值的指针, 如果未指定则使用NULL
- maxVal –指向最大值的指针,如果未指定则使用NULL
- minLoc – 指向最小值位置(2维情况)的指针, 如果未指定则使用NULL
- maxLoc – 指向最大值位置(2维情况)的指针, 如果未指则使用NULL
- mask – 可选的蒙版,用于选择待处理子区域