本系列代码托管于:https://github.com/chintsan-code/opencv4-tutorials

本篇使用的项目为:mat_creation

图像文件的内存数据对象:

opencv4入门笔记(4):图像对象的创建与赋值-萤火

Mat基本结构:

opencv4入门笔记(4):图像对象的创建与赋值-萤火

Mat由头部(header)和数据部分(Data Block)组成。头部包含着图像的属性。如大小、宽高、数据类型、通道数等。

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

using namespace cv;
using namespace std;

int main(int argc, const char** argv) {
	Mat src = imread("../sample/lena512color.bmp");
	if (src.empty())
	{
		cout << "could not load image..." << endl;
		return -1;
	}
	Mat m1, m2;
	m1 = src.clone(); // 克隆
	m1.copyTo(m2);  //拷贝
	imshow("src", src);
	imshow("m1", m1);
	imshow("m2", m1);

	// 创建空白对象
	//Mat m3 = Mat::zeros(Size(512, 512), CV_8UC1);
	Mat m3 = Mat::ones(Size(512, 512), CV_8UC3);
	cout << "Width: " << m3.cols << endl
		<< "Height: " << m3.rows << endl
		<< "Channels: " << m3.channels() << endl;
	//cout << m3 << endl;
	m3 = 127; // 注意:这样只会将第一个通道赋值为127
	//cout << m3 << endl;
	m3 = Scalar(0, 0, 255); //这样赋值三个通道
	cout << m3 << endl;
	imshow("m3", m3);  //m3也是图像
	Mat m4 = m3;  // 赋值
	Mat m5 = m3.clone();
	m4 = Scalar(255, 0, 0);  // 改变m4,m3也会改变
	m5 = Scalar(0, 255, 0);  // 改变m5,m3不会改变
	imshow("m3-2", m3);
	imshow("m4", m4);
	imshow("m5", m5);


	waitKey(0);
	destroyAllWindows();
	return 0;
}

当对Mat对象进行赋值操作时,只是相当于将指针指向同一区域;只有对Mat指向克隆(clone())/拷贝(copyTo())操作时才会真正复制一个新的对象。

copyTo:拷贝一个Mat对象到另一个,属于深拷贝

void cv::Mat::copyTo( cv::OutputArray m );
  • m:目标Mat对象

clone:效果同copyTo

Mat Mat::clone();
  • 返回值:目标Mat对象

cv::Mat::channels():获取Mat对象的通道数

int cv::Mat::channels();
  • 返回值:Mat对象的通道数

cv::Mat::cols、cv::Mat::rows:获取Mat对象的的columns和rows(Mat对象要大于等于2个维度)

注意:cv::Mat::cols还与图像的通道数有关系,例如图像是宽高都没8,单通道,则cols为8,如果为三通道,则cols为24

cv::Mat::zeros:创建Mat对象,将图像的每个像素的每个通道都赋值为0

static cv::MatExpr cv::Mat::zeros(cv::Size size, int type);
  • size:要创建的Mat对象的宽高尺寸
  • type:要创建的Mat对象的类型,如
    • CV_8UC1:8-bit无符号单通道图像
    • CV_8UC3:8-bit无符号三通道图像

cv::Mat::ones:创建Mat对象,将图像的每个像素的第一个通道赋值为1

static cv::MatExpr cv::Mat::ones(cv::Size size, int type);

注意:是将第一个通道赋值为1,其他通道是0