OpenCV数据结构与基本绘图(Opencv3编程入门第4章)

文章目录

  • OpenCV数据结构与基本绘图(Opencv3编程入门第4章)
    • 第一节 基础图像容器Mat
    • 二、常用数据结构和函数
    • 基本图形的绘制
    • 参考文献:OPenCV3编程入门 电子工业出版社 毛星云 冷雪飞等编著

OpenCV数据结构与基本绘图(Opencv3编程入门第4章)

第一节 基础图像容器Mat

  1. Mat是一个类,由两部分数据组成:矩阵头(包含矩阵尺寸、储存方法、储存地址等信息)和一个指向储存所有像素值的矩阵的指针。

  2. 不到万不得已,不应该进行大图像的复制,因为这会降低程序的运行速度。

  3. Mat类型对象的拷贝

Mat A, C;   //仅创建信息头部分
A = imread("1.jpg");     //为矩阵开辟内存空间
Mat B(A);    //使用拷贝构造函数
C= A;
//----------------------------------------------------------
//以上结果得到的A,B,C均指向同一个矩阵,对其中任意一个进行修改,另外两个的矩阵值也会随之变化。
//-----------------------------------------------------------Mat F = A.clone();
Mat G;
A.copyTo(G);
//----------------------------------------------------------
//使用clone或者cloneTo可以复制矩阵本身,F,G,A分别指向不同的三个矩阵。
//-----------------------------------------------------------
  1. 小结:
  • OpenCV函数中输出图像的内存分配是自动完成的。
  • 使用OpenCV的C++接口时不需要考虑内存释放的问题。
  • 赋值运算符和拷贝构造函数只复制信息头(只复制指针)。
  • 使用函数clone()或者成员方法copyTo()来复制一幅图像的矩阵。
  1. 四种颜色系统
  • RGB
  • HSV和HLS把颜色分解为色调、饱和度和亮度/明度。
  • YCrCb在JPEG图像格式中广泛使用。
  • CIE Lab*是一种在感知上均匀的颜色空间,他适合用来度量两个颜色之间的距离。
  1. 创建Mat对象的几种方法
  • 使用Mat构造函数
Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255));
cout << M;
// 输出:[0, 0, 255, 0, 0, 255; 0, 0, 255, 0, 0, 255]

CV_8UC3表示使用8位的unsigned char类型,每个像素有三个元素组成三通道。
Scalar是个short类型的向量

  • 创建一个超过两维的矩阵:
int sz[3] = {2,2,2};
Mat L(3, sz, CV_8UC, Scalar::all(0));

第一个参数指定维度,然后传递一个指向数组的指针,包含每个维度的尺寸;后续的两个参数与之前的相同。

  • 为已存在的Ipllmage指针创建信息头
IplImage* img = cvLoadImage("1.jpg", 1);
Mat mtx(img);
  • 利用create()函数
M.create(4, 4, CV_8UC(2));

其中CV_8UC(2)表示2通道的8位unsigned char。
此创建方法不能为矩阵设置初值,只是在改变尺寸时重新为矩阵数据开辟内存而已。

  • 采用Matlab式的初始化方式
Mat E = Mat::eye(4, 4, CV_64F);
Mat O = Mat::ones(2,2,CV_32F);
Mat Z = Mat::zeros(3, 3, CV_8UC1);
  • 对小矩阵使用逗号分隔式初始化函数
Mat C = (Mat (3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
  • 为已存在的对象创建新信息头
 Mat RowClone = C.row(1).clone();
  • 先分配内存,在进行初始化赋值
Mat r = Mat(10, 3, CV_8UC3);
randu(r, Scalar::all(0), Scalar::all(255));     //在0 - 255之间取随机数进行赋值
  1. opencv的Mat格式化输出有很多样式,个人认为没有太大的作用,只要使用cout就可以了。

  2. 其他数据结构

  • 二维点:Point2f p(6,2);
  • 三维点:Point3f p3f(8, 2, 0);
  • 基于Mat类的std::vector
vector v;
v.push_back(3);
v.push_back(5);
v.push_back(7);
  • 定义和输出std::vector点
vector points(20);
for (size_t i = 0; i < points.size(); ++i)points[i] = Point2f((float)(i * 5), (float)(i % 7));
cout << points;

二、常用数据结构和函数

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

Point_、Point2i、Point互相等价, Point_、Point2f相互等价

  1. 颜色的表示:Scalar类
    Scalar(a,b,c);三个参数分别为蓝色分量、绿色分量、红色分量。

  2. 尺寸的表示:Size类
    Size_、Size2i、Size这三个类名等价。

  3. Rect类
    成员变量有x,y,width,height;成员函数有Size()返回Size;area()返回矩形的面积;contains(Point)判断点是否在矩形内;tl()返回左上角坐标;br()返回右下角坐标。

Rect rectShitf = rect + point;      //平移矩形
rect rectScale = rect + Size;		//缩放矩形
  1. 颜色空间转换
    void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0);
    src和dst分别表示输入图像和输出图像;code为颜色空间转换的标识符;第四个参数为目标图像的通道数,默认为0表示输出图像取输入图像的通道数。

基本图形的绘制

  • 头文件paint.h
#ifndef PAINT_H
#define PAINT_H
#include 
using namespace cv;
void DrawEllipse(int x, int y, int width, int length, Mat img, float angle);
void DrawFilledCircle(Mat img, Point center, int radium);
#endif // PAINT_H
  • 源文件paint.cpp
#include "paint.h"
#include 
#include 
#include 
using namespace cv;void DrawEllipse(int x, int y, int width, int length, Mat img, float angle) {/*x,y:椭圆中心的位置width,length:椭圆所在的矩形的大小img:Mat对象angle:椭圆旋转的角度*/int thickness = 2;int lineType = 8;ellipse( img,	//将输出的结果存放在imgPoint(x, y),	//椭圆中心的位置Size(width, length),   //椭圆所在的矩形的大小angle,   //椭圆旋转的角度0,		//椭圆扩展的弧度从0-360360,Scalar(255, 129, 0), thickness,  //线宽lineType);	//线型
}void DrawFilledCircle(Mat img, Point center, int radium) {/*center:圆心radium:半径*/int thickness = -1;int lineType = 8;circle(img,center,radium,Scalar(0, 0, 255),thickness,lineType);
}
  • 源文件main.cpp
#include 
#include 
#include 
#include "paint.h"
using namespace cv;#define WINDOW_NAME1 "【绘制图1】"
#define WINDOW_NAME2 "【绘制图2】"
#define WINDOW_WIDTH 600int main() {// 创建空白的Mat图像Mat atomImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);Mat rookImage = atomImage.clone();//线绘制出椭圆DrawEllipse(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2, WINDOW_WIDTH / 4, WINDOW_WIDTH / 16, atomImage, 90);DrawEllipse(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2, WINDOW_WIDTH / 4, WINDOW_WIDTH / 16, atomImage, 0);DrawEllipse(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2, WINDOW_WIDTH / 4, WINDOW_WIDTH / 16, atomImage, -45);DrawEllipse(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2, WINDOW_WIDTH / 4, WINDOW_WIDTH / 16, atomImage, 45);//绘制实心圆DrawFilledCircle(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), WINDOW_WIDTH / 32);imshow(WINDOW_NAME1, atomImage);moveWindow(WINDOW_NAME1, 0, 200);waitKey(0);return 0;
}

结果如下:
在这里插入图片描述

参考文献:OPenCV3编程入门 电子工业出版社 毛星云 冷雪飞等编著


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部