opencv学习记录03:Mat对象简单理解及代码

背景

OpenCV 自 2001 年出现以来。在那些日子里库是围绕C接口构建的。在那些日子里,他们使用名为IplImage C 的结构在内存中存储图像。这是您将在大多数较旧的教程和教材中看到的那个。使用这个结构的问题是将 C 语言的所有负面效果都摆到了桌面上。最大的问题是手动管理。它是建立在用户来负责处理内存分配和解除分配的假设之上的。当程序规模较小时,这是没有问题的,一旦代码基开始变得越来越大它将会越来越挣扎着处理所有这一切而不是着眼于实际解决自己的开发目标。

幸运的是 c + + 出现了,并引入了类的概念,使得为用户开辟另一条路成为可能:

自动内存管理 (或多或少)。好消息是,c + +,如果完全兼容 C 所以进行更改时没有兼容性问题产生。因此, OpenCV其2.0 版本引入一个新的c + + 接口,通过利用这些优点将为你的工作提供新的方法。某种程度上,在其中您不需要拨弄内存管理让你的代码简洁 (写得更少,实现的更多)。C + + 接口的唯一主要缺点在于,目前许多嵌入式的开发系统支持仅 C.因此,除非您的目标是这一平台,否则就没有理由再使用旧的方法(除非你是个受虐狂程序员和喜欢自讨苦吃)。

你需要知道的关于Mat的第一件事是你不再需要手动分配其大小并且当你不需要它的时候你不再需要手动释放它。虽然这样做仍然是可能的,大多数 OpenCV 函数将手动分配其输出数据。还有一个额外的好处是如果传递一个已存在Mat对象,它已经为矩阵分配所需的空间,这段空间将被重用。也就是说我们在任何时候只使用与我们执行任务时所必须多的内存一样多的内存。

Mat

在这里插入图片描述
Mat本质上是由两个数据部分组成的类: (包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等) 的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选择用于存储的方法采用任何维度存储数据)。**矩阵头部的大小是恒定的。**然而,**矩阵本身的大小因图像的不同而不同,通常是较大的数量级。**因此,当你在您的程序中传递图像并在有些时候创建图像副本您需要花费很大的代价生成图像矩阵本身,而不是图像的头部。希望通过制作不必要的可能很大的图像的拷贝进一步加快程序运行速度。

为了解决这一问题 OpenCV 使用引用计数系统。其思想是Mat的每个对象具有其自己的头,但可能他们通过让他们矩阵指针指向同一地址的两个实例之间共享该矩阵。此外,拷贝运算符将只能复制矩阵头部,也还将复制指针到大型矩阵,但不是矩阵本身。

下面是部分参考代码:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace std;
using namespace cv;

int main() {
	Mat src, dst;
	src = imread("F:\\opencv_work\\04Mat对象\\Mat对象\\27.jpg");

	namedWindow("总舵主的自画像", WINDOW_AUTOSIZE);
	imshow("总舵主的自画像", src);
	

	//dst = Mat(src.size(), src.type());
	//dst = Scalar(127,0,255);            //创建一个空白图片
	//imshow("总舵主的对比像", dst);
	//namedWindow("总舵主的对比像", WINDOW_AUTOSIZE);

	//dst = src.clone();                    //克隆图片   API1
	//src.copyTo(dst);                      //克隆   API2

	//imshow("总舵主的对比像", dst);
	//namedWindow("总舵主的对比像", WINDOW_AUTOSIZE);

	cvtColor(src, dst, COLOR_BGR2GRAY);
	printf("input image channels : %d\n", src.channels());
	printf("output image channels : %d\n", dst.channels());       //输出通道数           1

	//imshow("总舵主的对比像", dst);
	//namedWindow("总舵主的对比像", WINDOW_AUTOSIZE);

	int cols = dst.cols;    //得到全部行
	int rows = dst.rows;     //得到全部列


	printf("rows : %d cols : %d\n", rows, cols);
	const uchar* firstRow = dst.ptr<uchar>(0);
	printf("fist pixel value : %d\n", *firstRow);

	Mat M(5, 5, CV_8UC3, Scalar(0,0,127));          ////指定行数、列数、类型的构造函数  CV_8UC3:8位无符号3通道图像 
	cout << "M =" << endl << M << endl;           //打印
	imshow("output", M);

	//Mat p1;
	//p1.create(src.size(), src.type());              //创建对象
	//p1 = Scalar(0, 0, 255);                         //BGR
	//imshow("输出图像", p1);

	Mat zdz;
	Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(src, zdz,-1, kernel);
	imshow("总舵主的对比像", dst);
	namedWindow("总舵主的对比像", WINDOW_AUTOSIZE);

	//Mat m2 = Mat::zeros(src.size(), src.type());
	////Mat m2 = Mat::zeros(2, 2, CV_8UC1);    //eye
	//cout << "m2 =" << endl << m2 << endl;
	//imshow("总舵主脸黑了", m2);

	waitKey(0);

	return(0);
}


参考:
链接: https://blog.csdn.net/guyuealian/article/details/70159660.
链接: https://www.cnblogs.com/wbyixx/p/12241903.html.

猜你喜欢

转载自blog.csdn.net/Cai_Xu_Kun/article/details/107595570
今日推荐