【OpenCV(C++)】基础图像容器Mat

数字图像存储

通常由显示屏上看到的都是真实的图像,但是这些图像在转化到我们的数字设备中时,记录的却是图像中每个点的数值。
在这里插入图片描述
矩阵就是图像在数码设备中的表现形式,OpenCV作为一个计算机视觉库,其主要的工作就是处理和操作并进一步了解这些形式和信息。

Mat结构的使用

Mat是一个类,由两个数据部分组成:矩阵头和一个指向存储所有像素值的矩阵的指针。
OpenCV使用了引用计数机制,让每个Mat对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;

int main()
{
	Mat A, C;
	A = imread("fg.jpg", CV_LOAD_IMAGE_COLOR);
	Mat B(A);
	C = A;
	Mat D(A, Rect(50, 50, 50, 50));
	Mat F = A.clone();
	imshow("A", F);
	waitKey(0);

	return 0;
}

运行结果如下:
在这里插入图片描述
使用函数clone()或者copyTo()来复制一幅图像的矩阵。

像素值的存储方法

存储像素值需要指定颜色空间和数据类型。

颜色空间

颜色空间是指针对一个给定颜色,如何组合颜色元素以对其编码。

  • 灰度级空间:只处理黑色和白色

  • 彩色空间:把颜色分成三个或四个基元素,通过组合基元素可以产生所有的颜色。

    • RGB——最常见的,因为其与人眼采用相似的工作机制,也被显示设备所采用。有时为了表示透明颜色也会加入第四个元素alpha(A)。
    • HSV和HLS——把颜色分解为色调、饱和度和亮度。这是描述颜色更自然的方式。
    • YCrCb——在JEPG图像格式中广泛使用。
    • CIE L * a * b*——是一种在感知上均匀的颜色空间,适合用来度量两个颜色之间的距离。

数据类型

每个组成元素都有其自己的定义域,而定义域取决于其数据类型,如何存储一个元素决定了我们在其定义域上能控制的精度。

  • char:1字节,8位
  • float: 4字节,32位
  • double: 8字节,64位

增加元素的尺寸,能给出更加精细的颜色分辨能力,但同时也会增加图像所占的内存空间。

显示创建Mat对象的七种办法

1.使用Mat()构造函数

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat A(2, 2, CV_8UC3,Scalar(0,0,225));
	cout << "A=" << endl << "" << A << endl << endl;
	
	return 0;
}

2.在C/C++中构造函数进行初始化

int sz[3] = { 2, 2, 2 };
Mat A(3,sz, CV_8UC,Scalar::all(0));

3.为已存在的IplImage指针创建信息头

IplImage* img = cvLoadImage("pig,jpg", 1);
Mat mtx(img);

4.利用Create()函数

不能为矩阵设初值,只能改变尺寸,为矩阵开辟内存。

A.Create(4, 4, CV_8UC(2));
cout << "A=" << endl << "" << A << endl << endl;

5.采用MATLAB式的初始化方法

Mat A = Mat::eye(4, 4, CV_64F);
cout << "A=" << endl << "" << A << endl << endl;

Mat B = Mat::ones(2, 2, CV_32F);
cout << "B=" << endl << "" << B << endl << endl;

Mat C = Mat::zeros(3, 3, CV_8UC1);
cout << "C=" << endl << "" << C << endl << endl;

6.小矩阵采用逗号分隔开初始化

Mat A = (Mat_<double>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cout << "A=" << endl << "" << A << endl << endl;

7.为已存在的数据创建新的数据头

Mat A = (Mat_<double>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
Mat RowClone = A.row(1).clone();
cout << "RowClone=" << endl << "" << RowClone << endl << endl;
发布了20 篇原创文章 · 获赞 14 · 访问量 852

猜你喜欢

转载自blog.csdn.net/weixin_43645790/article/details/104076791
今日推荐