1. Mat图像容器
图片是一个包括众多强度值得像素点矩阵。
1.1. Mat得结构
Mat是一个类,由两部分数据组成:
- 矩阵头(包括矩阵尺寸、存储方法、存储地址等)。
- 一个指向存储所有像素值得矩阵得指针,根据所选存储方式不同,矩阵可以是不同的维数。
为了解决OpenCV处理大量图片数据的效率问题。OpenCV使用引用计数机制,思路是每个Mat对象有自己的信息头而共享一个矩阵。通过指针指向同一个地址实现。
/**
创建和复制Mat
*/
-(void)creatCloneMat{
/**
matA,matB,matC对象指向同一个也是唯一一个数据矩阵
*/
Mat matA,matC; //仅仅创建Mat信息头部分
matA=[OpenCVUtility cvMatFromUIImage:_image]; //为矩阵matA开辟内存
Mat matB(matA); //使用拷贝构造函数
matC = matA; //赋值运算
Mat matD(matA,cv::Rect(0,0,100,100)); //使用矩阵界定
Mat matE=matA(cv::Range::all(),cv::Range(1,3)); //使用行和列界定
/**
复制信息头和矩阵
*/
Mat matF=matA.clone(); //clone Mat
Mat matG;
matA.copyTo(matG);
self.srcImgView.image=[OpenCVUtility UIImageFromCVMat:matC];
self.dstImgView.image=[OpenCVUtility UIImageFromCVMat:matF];
}
1.2. 创建Mat的几种方式
- 使用Mat()构造函数
/**
1. 使用Mat()构造函数
参数1:行数
参数2:列数
参数3:存储元素的数据类型以及每一个矩阵点的通道数
CV_[位数][是否带符号][类型前缀]C[通道数]
CV_8UC3:表示使用8位unsigned char型,每个像素由三个通道组成三通道
参数4:short型向量,表示颜色
*/
Mat mat1(2,2,CV_8UC3,Scalar(0,0,255));
print(mat1);
- 利用Mat类的creat()成员函数
/**
2. 利用Mat类的creat()成员函数进行
参数1:行数
参数2:列数
参数3:存储元素的数据类型以及每一个矩阵点的通道数
注意:此方法不能为矩阵设置初值,只是在改变尺寸时重新为矩阵数据开辟内存
*/
Mat mat2;
mat2.create(2, 2, CV_8UC3);
print(mat2);
- 采用Matlab式的初始化
/**
3. 采用Matlab式的初始化
*/
Mat mat3=Mat::eye(2, 2, CV_8UC3);
mat3=Mat::ones(2, 2, CV_8UC3);
mat3=Mat::zeros(2, 2, CV_8UC3);
//print(mat3);
- 小矩阵使用逗号分隔式初始化
/**
4. 小矩阵使用逗号分隔式初始化
*/
Mat mat4=(Mat_(2,6)<<0,0,255,0,0,255,0,0,255,0,0,255);
print(mat4);
- 为已经存在的对象创建信息头
/**
5. 为已经存在的对象创建信息头
*/
Mat mat5=mat1.row(1).clone();
2. 基本绘图
/**
绘图
*/
-(void)drawMat{
Mat mat(1120,800,CV_8UC3,Scalar(255,255,255));
//绘制椭圆
ellipse(mat, //绘图的Mat
cv::Point(400,400), //中心
cv::Size(200,100), //大小
50, //椭圆旋转角度
0, //弧度开始度数
360, //弧度结束角度
Scalar(255,129,0), //颜色
2, //线宽
8); //线型
//绘制圆
circle(mat,
cv::Point(400,700), //圆心
100, //半径
Scalar(255,0,255),
2,
8);
//绘制线
line(mat,
cv::Point(50,50), //开始点
cv::Point(50,300), //结束点
Scalar(0,0,255),
2,
8);
//绘制矩形
rectangle(mat,
cv::Point(100,20), //左上角
cv::Point(500,150), //右下角
Scalar(0,0,255),
2,
8);
//绘制填充的多边形
cv::Point rookPoints[1][3];
rookPoints[0][0]=cv::Point(200,900);
rookPoints[0][1]=cv::Point(200,1100);
rookPoints[0][2]=cv::Point(600,900);
const cv::Point * pts[1]={rookPoints[0]};
int npts=3;
fillPoly(mat,
pts, //顶点集合
&npts, //顶点数量
1, //要绘制的多边形数量
Scalar(0,0,255),
8);
self.srcImgView.image=[OpenCVUtility UIImageFromCVMat:mat];
}
代码
https://github.com/DavidJi80/iosOpenCV3
v0.1.4