目录

第四章、OpenCV基本结构与数据绘图

4.1、基础图像容器Mat

4.1.1、数字图像存储概述

4.1.2、Mat结构的使用

4.1.3、像素值的存储方法

4.1.4、显式创建Mat对象的七种方法

4.1.5、OpenCV中的格式化输出方法

4.1.6、输出其他常用数据机构

4.2、常用数据结构和函数

4.2.1、点的表示:Point类

4.2.2、颜色的表示:Scalar类

4.2.3、尺寸的表示:Size类

4.2.4、矩阵的表示:Rect类

4.2.5、颜色空间转换:cvtColor()

4.2.6、其他常用知识点

4.3、基本图形的绘制


第四章、OpenCV基本结构与数据绘图

4.1、基础图像容器Mat

4.1.1、数字图像存储概述

4.1.2、Mat结构的使用

  • Mat是一个类,有两个数据部分组成:矩阵头(矩阵尺寸、存储方法、存储地址);指向存储所有像素值的矩阵(根据所选存储方法的不同,矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比及枕头的尺寸大数个数量级。
  • 赋值运算符和拷贝构造函数值复制信息头
  • 使用函数clone()和copyTo()来复制一副图像的矩阵

4.1.3、像素值的存储方法

  • 存储像素值需要指定颜色空间和数据类型。颜色空间是指针对一个给定的颜色,如何组合颜色元素对其编码。
  • RGB+A(透明颜色)

4.1.4、显式创建Mat对象的七种方法

  • 1、使用Mat()构造函数
  • Mat m(2,2,CV_8UC3,Scalar(0,0,255))
  • 对于二维多通道图像,首先要定义其尺寸,即行数和列数。然后需要指定存储元素的数据类型以及每个矩阵点的通道数。
  • CV_[位数][带符号与否][类型前缀]C[通道数]
  • 2、在c++中通过构造函数进行初始化
  • int sz[3]={2,2,2}
  • Mat m(3,sz,CV_8UC,Scalar::all(0))
  • 创建一个超过两维的矩阵:指定维数,传递一个指向一个数组的指针,数组包括每个维度的尺寸;后续的两个参数与第一种方法一样
  • 3、为已存在的IplImage指针创建信息头
  • IplImage* img = cvLoadImage("1.jpg",1)
  • Mat mtx(img);转换
  • 4、利用Create()函数
  • M.Create(4,4,CV_8UC(2));此方法不能为矩阵设初值,只是在改变尺寸时重新为矩阵数据开辟内存而已
  • 5、采用Matlab的初始化方式
  • Mat e=Mat::eye(4,4,CV_64F)
  • 6、对小矩阵使用逗号分隔式初始化函数
  • Mat c = (Mat_<double>(3,3)<<0,-1,0,-1,0,-1,0)
  • 7、为已存在的对象创建新信息头
  • Mat R=C.row(1).clone();

4.1.5、OpenCV中的格式化输出方法

  • Mat r = Mat(10,3,CV_8UC3);
  • randu(r,Scalar::all(0),Scalar::all(255))
  • 初始化完r矩阵:
  • opencv默认风格
  • cout<<r
  • python风格
  • cout<<format(r,Formatter::FMT_PYTHON)
  • 逗号分隔符风格
  • cout<<format(r,Formatter::FMT_CSV)
  • Numpy
  • format(r,Formatter::FMT_NUMPY)
  • c语言风格
  • format(r,Formatter::FMT_C)

4.1.6、输出其他常用数据机构

  • 1、定义和输出二维点
  • Point2f p(6.2);cout<<p
  • 2、定义和输出三维点
  • Point3f p3f(8,2,0)
  • 3、定义和输出基于Mat的vector
  • vector<float> v
  • v.push_back(3);v.push_back(5);v.push_back(7)
  • 4、定义和输出vector点
  • points[i]=Point2f((float)(i*5),(float)(i%7))

4.2、常用数据结构和函数

  • 4

4.2.1、点的表示:Point类

  • Point point; point.x =10; point.y =8
  • Point point = Point(10,8)

4.2.2、颜色的表示:Scalar类

  • Scalar()表示具有4个元素的数组,用于传递像素值,对于此函数用不到第四个参数则不需要写出来,Scalar(a,b,c)表示RGB颜色,红c,绿b,蓝a

4.2.3、尺寸的表示:Size类

  • Size(5,5);

4.2.4、矩阵的表示:Rect类

  • Rect的成员变量有x,y,width,height,分别为左上角点的坐标和矩形的宽和高。常见的成员函数有Size()返回值为Size;area()返回矩形的面积;contains(Point)判断点是否在矩形内、inside(Rect)判断矩形是非在该矩形内;tl()返回左上角点坐标,br()返回右下角坐标。
  • 求两个矩形的交集和并集:rect1 & rect2; rect1 | rect2
  • 进行平移和缩放:rect+point; rect+size

4.2.5、颜色空间转换:cvtColor()

  • void cvtColor(InputArray src,OutputArray dst, int code, int dstCn=0)
  • 第一个参数为输入图像,第二个为输出图像,第三个为颜色空间转换的标识符,第四个为目标图像的通道数,为0表示目标图像取源图像的通道数
  • cvtColor(srcImage,dstImage.COLOR_GRAY2BGR)转换原始图为灰度图

4.2.6、其他常用知识点

4.3、基本图形的绘制

  • 用于绘制椭圆的ellipse函数
  • 实心圆的绘制
  • 多边形
  • 线
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

#define WINDOWNAME1 "【绘制图1】"

#define WINDOWNAME2 "【绘制图2】"

#define WINDOWWIDTH 600 //定义窗口大小的宏

//--------[DrawEllipse]函数--------------

//自定义的绘制函数,实现了绘制不同角度、相同尺寸的椭圆

void DrawEllipse(Mat img, double angle)

{

int thickness = 2;

int lineType = 8;

ellipse(img,

Point(WINDOWWIDTH / 2, WINDOWWIDTH / 2),

Size(WINDOWWIDTH / 4, WINDOWWIDTH / 16),

angle, 0, 360, Scalar(255, 129, 0),

thickness, lineType);

}

//-----------DrawFilledCircle()函数------------

//自定义的绘制函数,实现实心圆的绘制

void DrawFilledCircle(Mat img, Point center)

{

int thickness = -1;

int lineType = 8;

circle(img, center, WINDOWWIDTH / 32,

Scalar(0,0,255),thickness,lineType);

}

//--------DrawPolygon

//实现了凹多边形的绘制

void DrawPolygon(Mat img)

{

int lineType = 8;

//创建一些点

Point rookPoints[1][20];

rookPoints[0][0] = Point(WINDOWWIDTH / 4, 7 WINDOWWIDTH / 8);

rookPoints[0][1] = Point(3 WINDOWWIDTH / 4, 7 WINDOWWIDTH / 8);

rookPoints[0][2] = Point(3 WINDOWWIDTH / 4, 13 WINDOWWIDTH / 16);

rookPoints[0][3] = Point(11 WINDOWWIDTH / 16, 13 WINDOWWIDTH / 16);

rookPoints[0][4] = Point(19 WINDOWWIDTH / 32, 3 WINDOWWIDTH / 8);

rookPoints[0][5] = Point(3 WINDOWWIDTH / 4, 3 WINDOWWIDTH / 8);

rookPoints[0][6] = Point(3 WINDOWWIDTH / 4, WINDOWWIDTH / 8);

rookPoints[0][7] = Point(26 WINDOWWIDTH / 40, WINDOWWIDTH / 8);

rookPoints[0][8] = Point(26 WINDOWWIDTH / 40, WINDOWWIDTH / 4);

rookPoints[0][9] = Point(22 WINDOWWIDTH / 40, WINDOWWIDTH / 4);

rookPoints[0][10] = Point(22 WINDOWWIDTH / 40, WINDOWWIDTH /8);

rookPoints[0][11] = Point(18 WINDOWWIDTH / 40, WINDOWWIDTH / 8);

rookPoints[0][12] = Point(18 WINDOWWIDTH / 40, WINDOWWIDTH / 4);

rookPoints[0][13] = Point(14 WINDOWWIDTH / 40, WINDOWWIDTH / 4);

rookPoints[0][14] = Point(14 WINDOWWIDTH / 40, WINDOWWIDTH / 8);

rookPoints[0][15] = Point( WINDOWWIDTH / 4, WINDOWWIDTH / 8);

rookPoints[0][16] = Point(WINDOWWIDTH / 4, WINDOWWIDTH / 8);

rookPoints[0][17] = Point(13 WINDOWWIDTH /32, 3WINDOWWIDTH / 8);

rookPoints[0][18] = Point(5 WINDOWWIDTH / 16, 13 WINDOWWIDTH / 16);

rookPoints[0][19] = Point(WINDOWWIDTH / 4, 13WINDOWWIDTH / 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);

}

int main(void)

{

//创建空白的Mat图像

Mat atomImage = Matzeros(WINDOWWIDTH, WINDOWWIDTH, CV8UC3);

Mat rookImage = Matzeros(WINDOWWIDTH, WINDOWWIDTH, CV8UC3);

//-------------1、绘制化学中的原子示例图------------

//1.1、先绘制椭圆

DrawEllipse(atomImage, 90);

DrawEllipse(atomImage, 0);

DrawEllipse(atomImage, 45);

DrawEllipse(atomImage, -45);

//1.2、绘制圆心

DrawFilledCircle(atomImage, Point(WINDOWWIDTH / 2, WINDOWWIDTH / 2));

//----------2、绘制组合图------------

//2.1、绘制椭圆

DrawPolygon(rookImage);

//2.2、绘制矩形

rectangle(rookImage,

Point(0, 7 WINDOWWIDTH / 8),

Point(WINDOWWIDTH, WINDOWWIDTH),

Scalar(0, 255, 255),

-1, 8

);

//2.3、绘制一些线段

DrawLine(rookImage, Point(0, 15 WINDOWWIDTH / 16), Point(WINDOWWIDTH, 15 WINDOWWIDTH / 16));

DrawLine(rookImage, Point(WINDOWWIDTH/4, 7 WINDOWWIDTH / 8), Point(WINDOWWIDTH/4, WINDOWWIDTH));

DrawLine(rookImage, Point(WINDOWWIDTH /2, 7 WINDOWWIDTH / 8), Point(WINDOWWIDTH / 2, WINDOWWIDTH));

DrawLine(rookImage, Point(3WINDOWWIDTH / 4, 7 WINDOWWIDTH / 8), Point(3WINDOWWIDTH / 4, WINDOWWIDTH));

//-----------3、显示绘制出的图像

imshow(WINDOWNAME1, atomImage);

moveWindow(WINDOWNAME1, 0, 200);

imshow(WINDOWNAME2, rookImage);

moveWindow(WINDOWNAME2, WINDOWWIDTH, 200);

waitKey(0);

return 0;

}