1.Mat结构
1.几种Mat类复制方法
可以创建只引用部分数据的信息头,如下:
Mat D(A,Rect(10,10,100,100));//使用矩形界定
Mat E=A(Range:all(),Range(1,3));//使用行和列界定
2.显示创建Mat对象的七种方法
(1)使用Mat()构造函数
Mat M(2,2,CV_8UC3,Scalar(0,0,255));//CV_[位数][带符号与否][类型前缀]C[通道数]
cout << "M=" << endl << " " << M << endl << endl;
(2)在C\C++中通过构造函数进行初始化
int sz[3]={2,2,2};
Mat L(3,sz,CV_8UC,Scalar::all(0));//创造超过两维的矩阵
(3)为已存在的IplImage指针创建信息头
IplImage* img=cvLoadImage("1.gpg",1);//OpenCV 4.x已经删去
Mat mtx(img);
(4)利用Create()函数
M.create(4,4,CV_8UC(2));//只是在改变尺寸时使用
cout << "M=" << endl << " " << M << endl << endl;
(5)采用MATLAB式的初始化方式
Mat E=Mat::eye(4,4,CV_64F);
Mat E=Mat::ones(2,2,CV_32F);
Mat E=Mat::zeros(3,3,CV_8UC1);
(6)对小矩阵使用逗号分隔式初始化
Mat C =(Mat_<double>(3,3) <<0,-1,0,-1,5,-1,0,-1,0);
(7)为已存在的对象创建新信息头
Mat RowClone = C.row(1).clone();
3.输出其他常用数据结构
二维点 :Point2f p(6,2);
三维点 :Point3f p3f(8,2,0);
基于Mat的std::vector:
vector<float> v;
v.push_back(3);
v.push_back(5);
v.push_back(7);
cout << "vector=" << endl << " " << Mat(v) << endl << endl;
std::vector点:
vector<Point2f> points(20);
for (size_t i=0;i<points.size();++i)
points[i]=Point2f((float)(i*5),(float)(i%7));
cout<<"points=" <<points<<";";
2.常用数据结构和函数
1.点的表示:Point类
Point point;
point.x = 10;
point.y= 8;
//Point point =Point(10,8);
2.颜色表示:Scalar类
Scalar(a,b,c)//BGR
3.尺寸的表示:Size类
Size(3,4);//宽为3,高为4
4.矩形的表示:Rect类
Rect类成员变量为x,y,width,heigh;
Size();area()返回矩形面积;
contains(Point)判断点在矩形内;
inside(Rect)判断矩形在矩形内;
tl()返回左上角坐标;br()返回右下角坐标
Rect rect = rect1 & rect2;//交集
Rect rect = rect1 | rect2;//并集
Rect rectshift = rect + point;//平移
Rect rectScale = rect + size;//平移
5.颜色空间转换:cvtColor
void cvtColor(InputArray src,OutputArray dst,int code, int dstCn=0);
//第一个参数为输入图像;第二个为输出图像;第三个为颜色空间转换标识符;第四个参数为通道数。
cvtColor(srcImage,dstImage,COLOR_GRAY2BGR)
应用示例
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
int main()
{
Mat srcImage = imread("1.bmp", 1), dstImage;
cvtColor(srcImage, dstImage, COLOR_BGR2Lab);
imshow("效果图",dstImage);
waitKey();
return 0;
}
3.基本图形的绘制
- 直线:line
- 椭圆:ellipse
- 矩形:rectangle
- 圆:circle
- 多边形:fillPoly
void DrawEllipse(Mat img, double angle)//绘制椭圆
{
int thickness = 2;//线宽
int lineType = 8;//线型
ellipse(img,
Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2),//椭圆中心
Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16),//大小
angle,//旋转角度
0,//扩展弧度
360,
Scalar(255, 129, 0),//蓝色
thickness,
lineType);
}
void DrawFilledCircle(Mat img, Point center)//绘制圆
{
int thickness = -1;//线粗为-1,因此绘制的圆是实心的
int lineType = 8;
circle(img,
center,//圆心
WINDOW_WIDTH / 32,//半径
Scalar(0, 0, 255),//红色
thickness,
lineType);
}
void DrawPolygon(Mat img)//绘制多边形
{
int lineType = 8;
//创建一些点
Point rookPoints[1][20];
rookPoints[0][0] = Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
rookPoints[0][1] = Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
rookPoints[0][2] = Point(3 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);
rookPoints[0][3] = Point(11 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);
rookPoints[0][4] = Point(19 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8);
rookPoints[0][5] = Point(3 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);
rookPoints[0][6] = Point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);
rookPoints[0][7] = Point(26 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
rookPoints[0][8] = Point(26 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
rookPoints[0][9] = Point(22 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
rookPoints[0][10] = Point(22 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
rookPoints[0][11] = Point(18 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
rookPoints[0][12] = Point(18 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
rookPoints[0][13] = Point(14 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
rookPoints[0][14] = Point(14 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
rookPoints[0][15] = Point(WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);
rookPoints[0][16] = Point(WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);
rookPoints[0][17] = Point(13 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8);
rookPoints[0][18] = Point(5 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);
rookPoints[0][19] = Point(WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);
const Point* ppt[1] = { rookPoints[0] };//多边形顶点集
int npt[] = { 20 };//多边形顶点数目
fillPoly(img,
ppt,
npt,
1,//多边形数量
Scalar(255, 255, 255),//红色
lineType);
}
void DrawLine(Mat img, Point start, Point end)//绘制线条
{
int thickness = 2;
int lineType = 8;
line(img,
start,//起点
end,//终点
Scalar(0, 0, 0),//黑色
thickness,//线的粗细
lineType);
}
应用示例
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
#define WINDOW_NAME1 "【绘制图1】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【绘制图2】" //为窗口标题定义的宏
#define WINDOW_WIDTH 600//定义窗口大小的宏
int main(void)
{
// 创建空白的Mat图像
Mat atomImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
Mat rookImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
// ---------------------<1>绘制化学中的原子示例图------------------------
//【1.1】先绘制出椭圆
DrawEllipse(atomImage, 90);
DrawEllipse(atomImage, 0);
DrawEllipse(atomImage, 45);
DrawEllipse(atomImage, -45);
//【1.2】再绘制圆心
DrawFilledCircle(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2));
// ----------------------------<2>绘制组合图-----------------------------
//【2.1】先绘制出多边形
DrawPolygon(rookImage);
// 【2.2】绘制矩形
rectangle(rookImage,
Point(0, 7 * WINDOW_WIDTH / 8),
Point(WINDOW_WIDTH, WINDOW_WIDTH),
Scalar(0, 255, 255),
-1,
8);
// 【2.3】绘制一些线段
DrawLine(rookImage, Point(0, 15 * WINDOW_WIDTH / 16), Point(WINDOW_WIDTH, 15 * WINDOW_WIDTH / 16));
DrawLine(rookImage, Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8), Point(WINDOW_WIDTH / 4, WINDOW_WIDTH));
DrawLine(rookImage, Point(WINDOW_WIDTH / 2, 7 * WINDOW_WIDTH / 8), Point(WINDOW_WIDTH / 2, WINDOW_WIDTH));
DrawLine(rookImage, Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8), Point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH));
// ---------------------------<3>显示绘制出的图像------------------------
imshow(WINDOW_NAME1, atomImage);
moveWindow(WINDOW_NAME1, 0, 200);
imshow(WINDOW_NAME2, rookImage);
moveWindow(WINDOW_NAME2, WINDOW_WIDTH, 200);
waitKey(0);
return(0);
}