文章目录

  • 前言
  • 一、Opencv是什么?
  • 二、常用api
  • 1. 创建Mat
  • 2. 复制Mat[^1]
  • 2. Mat属性[^2]
  • 3. 遍历Mat



前言

我在深度学习工作当中,对于常用的opencv的c++代码进行的整理总结。后续会进一步的修改和添加内容。部分内容来源于网络,已经说明具体出处。

一、Opencv是什么?

来源于百度百科。

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 [1] 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。

二、常用api

1. 创建Mat

// 初始化设值
cv::Mat M(2, 2, CV_8UC3, Scalar(b, g, r));
// 非初始化设值
cv::Mat M;
M.create(h, w, CV_8UC1);
M.create(cv::Size(w, h), CV_8UC1);
// 使用无参构造方法创建
cv::Mat M = cv::Mat();
M.create(h, w, CV_8UC1);
// 使用带参构造方法创建
Mat m = Mat(h, w, CV_8UC3, Scalar(b, g, r);
Mat m = Mat(Size(h, w), CV_8UC3);
Mat m = Mat(Size(h, w), CV_8UC3, Scalar(b, g, r));
// 小矩阵直接赋值
cv::Mat M = (cv::Mat_<int>(w,h)<<1,2,3,4);
// 从其它Mat创建
cv::Mat M(img.size(), CV_8UC1, img.data);
// 从tensor创建
cv::Mat img(img_tensor.size(1), img_tensor.size(2), CV_8UC1, img_tensor.data_ptr());
cv::Mat img(cv::Size(img_tensor.size(2), img_tensor.size(1)), CV_8UC1, img_tensor.data_ptr());
// 从图像创建
cv::Mat img = cv::imread(imgpath);
// 使用类Matlab方法
cv::Mat M = cv::Mat::eye(4, 4, CV_64F);
cv::Mat M = cv::Mat::zeros(3, 3, CV_64F);
cv::Mat M = cv::Mat::ones(2, 2, CV_64F);

2. 复制Mat1

cv::Mat src = cv::imread(imgpath);
// 浅拷贝
// method 1
cv::Mat dst;
dst = src;
// method 2
cv::Mat dst(src);
// 深拷贝
// method 1
cv::Mat dst = src.clone();
// method22
cv::Mat dst;
src.copyTo(dst);

2. Mat属性2



  • data:uchar类型的指针,指向Mat数据矩阵的首地址。
  • dims:Mat矩阵的维度。
  • rows:Mat矩阵的行数。
  • cols: Mat矩阵的列数。
  • size():定义Mat矩阵内数据(宽,高)的size的结构体。
  • image.size().width=image.cols; image.size().height=image.rows
  • channels():Mat矩阵的通道数。
  • depth():用来度量每一个像素中每一个通道的精度。
  • Opencv中,mat.depth()得到的是一个0~6的数字,分别代表不同的位数,对应关系如下:
    enum{CV_8U=0,CV_8S=1,CV_16U=2,CV_16S=3,CV_32S=4,CV_32F=5,CV_64F=6}
    其中U是unsigned的意思,S表示signed。
  • elemSize():矩阵中每一个元素的数据大小。
  • 如果Mat中的数据类型是CV_8UC1,那么 elemSize=1;如果是CV_8UC3或CV_8SC3,那么elemSize=3;如果是CV_16UC3或者CV_16SC3,那么elemSize=6;即elemSize是以8位(一个字节)为一个单位,乘以通道数和8位的整数倍;
  • elemSize1():表示Mat矩阵中每一个元素单个通道的数据大小。
  • 以字节为一个单位,有:
    eleSize1=elemSize/channels;
  • step:Mat矩阵中每一行的“步长”。
  • 以字节为基本单位,每一行中所有元素的字节总量,是累计了一行中所有元素、所有通道、所有通道的elemSize1之后的值;
  • step1():Mat矩阵中每一个像素的大小。
  • 以字节为基本单位,累计了所有通道、所有通道的elemSize1之后的值,所以有:
    step1=step/elemSize1;
  • type():
    Mat矩阵的类型。
  • 包含有矩阵中元素的类型以及通道数信息,type的命名格式为CV_(位数)+(数据类型)+(通道数)。
  • total()
    所有数组元素的个数,不考虑通道。

3. 遍历Mat

代码如下(示例):

cv::Mat img = (cv::Mat_<int>(3, 2) << 1, 2, 3, 4, 5, 6);
int i, j;
// 访问像素值
for (i = 0;i<img.rows;i++)
{
	for (j=0;j<img.cols;j++)
	{
		cout << img.at<int>(i,j)<<" ";
	}
	cout << endl;
}
// 用指针扫描图像
cv::Mat img1 = (cv::Mat_<int>(3, 2) << 1, 2, 3, 4, 5, 6);
int nl = img1.rows;
int nc = img1.cols*img1.channels();
if (img1.isContinuous())
{
	nc = nc*nl;
	nl = 1;
}
for (i=0;i<nl;i++)
{
	int* data = img1.ptr<int>(i);
	for (j=0;j<nc;j++)
	{
		cout << data[j] << " ";
	}
	cout << endl;
}
// 用迭代器扫描图像
cv::Mat img2 = (cv::Mat_<int>(3, 2) << 1, 2, 3, 4, 5, 6);
// cv::MatIterator_<cv::Vec1b> it;
cv::Mat_<int>::iterator it = img2.begin<int>();
cv::Mat_<int>::iterator itend = img2.end<int>();
for (;it!=itend;it++)
{
	cout << (*it) << " ";
}
cout << endl;