OpenCV(4): Mat对象

文章目录

  • 1基础知识
  • 2 代码示例
    • 2.1 创建一张空白图像
    • 2.2 clone
    • 2.3 cvtcolor
    • 2.4 channels
    • 2.5 cols、rows 和 uchar* ptr
    • 2.6 构建一个窗口
    • 2.7 zeros
  • 参考资料


注:转载请标明原文出处链接:https://xiongyiming.blog.csdn.net/article/details/106931100


1基础知识

Mat对象 OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。Mat对象分为头部数据两个部分。

IplImage 是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题。IplImage从本质上讲,它是Mat对象,但它还有其他一些成员变量将矩阵解释为图像。


Mat对象构造函数有:

Mat();
Mat(int rows, int cols, int type);
Mat(Size size, int type)
Mat(int rows, int cols, int type, const Scalar $s);
Mat(int ndims, const int *sizes, int type);
Mat(int ndims, const int *sizes, int type, const Scalar &s);

Mat对象常用的函数有:

void copyTo(Mat mat);
void convertTo(Mat dst, int type);
Mat clone();
int channels();
int depth();
bool empty();
uchar* ptr(i=0);

Mat对象使用的注意事项
(1) 部分复制:一般情况下只会复制Mat对象的头部和指针部分,不会复制数据部分

Mat A= imread(imgFilePath);
Mat B(A)  // 只复制

(2) 完全复制:如果把Mat对象的头部和数据部分一起复制,可以通过如下两个代码

实现
Mat F = A.clone(); 
或 
Mat G; 
A.copyTo(G);

Mat对象使用的四个要点

  1. 输出图像的内存是自动分配的;
  2. 使用OpenCV的C++接口,不需要考虑内存分配问题;
  3. 赋值操作和拷贝构造函数只会复制头部分;
  4. 使用clone与copyTo两个函数实现数据完全复制;




2 代码示例

2.1 创建一张空白图像

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);


	Mat dst; 
	dst = Mat(src.size(), src.type()); //或者用 dst.create(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);


	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第1张图片



2.2 clone

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);

	/*
	Mat dst; 
	dst = Mat(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);
	*/
	Mat dst = src.clone();
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);


	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第2张图片



2.3 cvtcolor

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);

	/*
	Mat dst; 
	dst = Mat(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);
	*/
	Mat dst; 
	src.copyTo(dst);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);


	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第3张图片



2.4 channels

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);

	/*
	Mat dst; 
	dst = Mat(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);
	*/
	Mat dst; 

	
	cvtColor(src, dst, CV_BGR2GRAY);
	printf("原始图像的通道数为:%d\n", src.channels());
	printf("输出图像的通道数为:%d\n", dst.channels());

	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);


	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第4张图片



2.5 cols、rows 和 uchar* ptr

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);

	/*
	Mat dst; 
	dst = Mat(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);
	*/

	Mat dst; 
	
	cvtColor(src, dst, CV_BGR2GRAY);
	printf("原始图像的通道数为:%d\n", src.channels());
	printf("输出图像的通道数为:%d\n", dst.channels());

	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);

	
	int rows = dst.rows;
	int cols = dst.cols;
	printf("rows = %d , cols = %d\n", rows, cols);

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

	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第5张图片



2.6 构建一个窗口

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);

	/*
	Mat dst; 
	dst = Mat(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);
	*/
	Mat dst; 

	
	cvtColor(src, dst, CV_BGR2GRAY);
	printf("原始图像的通道数为:%d\n", src.channels());
	printf("输出图像的通道数为:%d\n", dst.channels());

	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);

	
	int rows = dst.rows;
	int cols = dst.cols;
	printf("rows = %d , cols = %d\n", rows, cols);

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

	Mat M1(3, 3, CV_8UC3, Scalar(255, 255, 255));
	cout << "M1=" << endl << M1 << endl;


	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第6张图片



注意

  1. 对于int类型8位,CvMat矩阵对应的参数类型为 CV_8UC1CV_8UC2CV_8UC3 (其中,数字1、2、3表示通道数,比如 RGB 图像有3通道,就用CV_8UC3,灰度图像就用CV_8UC1)
  2. 对于float类型32位,对应CvMat数据结构参数为:CV_32FC1CV_32FC2CV_32FC3等;
  3. 对于double 类型64位,对应CvMat数据结构参数为:CV_64FC1CV_64FC2CV_64FC3等。



2.7 zeros

代码

#include  
#include  
#include 
#include 
#include 

#include 
#include 




using namespace cv;
using namespace std;
int main(int argc, char** args) {
	Mat src = imread("ZXP1.jpg", IMREAD_UNCHANGED);
	if (src.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	imshow("Original Image", src);

	/*
	Mat dst; 
	dst = Mat(src.size(), src.type());
	dst = Scalar(255, 255, 255);
	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);
	*/
	Mat dst; 

	
	cvtColor(src, dst, CV_BGR2GRAY);
	printf("原始图像的通道数为:%d\n", src.channels());
	printf("输出图像的通道数为:%d\n", dst.channels());

	namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
	imshow("Output Image", dst);

	

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


	waitKey(0);

	return 0;
}

运行结果

OpenCV(4): Mat对象_第7张图片






参考资料

[1] https://edu.51cto.com/course/7521.html?source=so



你可能感兴趣的:(OpenCV学习专栏)