1、一个Mat对象(图片)包含头部和数据部分两部分信息。
2、当使用赋值方式时,并不会重新开辟一块空间来存储这张图片的信息。Mat还有一个克隆/拷贝方法,当调用这两个方法时,才会将另外开辟一块空间来存储这张图片的信息。
如何调用拷贝和克隆方法。
void QuickDemo::mat_creation_demo(Mat& image)
{
Mat m1,m2;
//克隆方法
m1 = image.clone();
//拷贝方法
image.copyTo(m2);
}
如何创建空白图像。
void QuickDemo::mat_creation_demo()
{
//zeros -- 用于创建空白图像
//Returns a zero array of the specified size and type.
Mat m3 = Mat::zeros(Size(8,8),CV_8UC1);//尺寸大小为8*8,每个像素点数据大小为CV_8UC1
// CV_8UC1 中的 8 代表 8 位的,UC代表unsigned char,1表示单通道的。
//通过属性和方法来查看图片的行数、列数和通道数。
std::cout << "width:" << m3.cols << "height:" << m3.rows << "channels:" << m3.channels() << std::endl;
std::cout << m3 << std::endl;
}
输出结果如下:
当我把参数 CV_8UC1 中的 1 改为 3 ,会看到。
输出结果如下:
因为3代表的是3通道,每个通道是8位,3通道就是24位。
注意:行数(高度)不会变。
此外,我还可以将 zeros 改变为 ones
#include <iostream>
#include "03_opencv_mat.h"
using namespace std;
void QuickDemo::mat_creation_demo()
{
Mat m3 = Mat::ones(Size(8,8),CV_8UC1);//尺寸大小为8*8,每个像素点数据大小为CV_8UC1
std::cout << "width:" << m3.cols << "height:" << m3.rows << "channels:" << m3.channels() << std::endl;
std::cout << m3 << std::endl;
}
需要注意:ones 只能在单通道时使用,如果换成三通道的则不行(因为它只会把每个像素点的第一个通道置为 1)
void QuickDemo::mat_creation_demo()
{
Mat m3 = Mat::zeros(Size(8,8),CV_8UC1);
m3 = 127;//当只输入一个数值的时候,第一个通道的值全都变成127
std::cout << m3 << std::endl;
}
改为CV_8UC3再试试
这个时候,如果你要将三个通道全部赋值,应该怎么做呢?
openCV提供了一个Scalar函数。
每个通道分量 可以修改。可以组合成各种各样的颜色。
#include <iostream>
#include "03_opencv_mat.h"
using namespace std;
void QuickDemo::mat_creation_demo()
{
Mat m1 = Mat::zeros(Size(256, 256),CV_8UC3);
Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);
Mat m3 = Mat::zeros(Size(256, 256), CV_8UC3);
Mat m4 = Mat::zeros(Size(256, 256), CV_8UC3);
//当只输入一个数值的时候,第一个通道的值全都变成127
//我事先知道有三个通道。
// B G R
// 0xFFFFFF
m1 = Scalar(127,127,127);//当三个通道的值相同时,就会显示灰度图像
// B G R
m2 = Scalar(255, 0, 0 );
m3 = Scalar( 0, 255, 0 );
m4 = Scalar( 0, 0, 255);
imshow("灰度图像", m1);
imshow("纯蓝色图像", m2);
imshow("纯绿色图像", m3);
imshow("纯红色图像", m4);
}
注意:通道的对应关系
// B G R
// 0xFFFFFF。
不同灰度值对应的灰度图像:
#include <iostream>
#include "03_opencv_mat.h"
using namespace std;
void QuickDemo::mat_creation_demo()
{
Mat m1 = Mat::zeros(Size(256, 256), CV_8UC1);
Mat m2 = Mat::zeros(Size(256, 256), CV_8UC1);
Mat m3 = Mat::zeros(Size(256, 256), CV_8UC1);
Mat m4 = Mat::zeros(Size(256, 256), CV_8UC1);
m1 = Scalar(0);
m2 = Scalar(60);//可直接赋值,如m2 = 60
m3 = Scalar(128);
m4 = Scalar(256);
imshow("灰度 = 0 图像", m1);
imshow("灰度 = 60 图像", m2);
imshow("灰度 = 128 图像", m3);
imshow("灰度 = 256 图像", m4);
}
下面再来验证下使用赋值方式
#include <iostream>
#include "03_opencv_mat.h"
using namespace std;
void QuickDemo::mat_creation_demo()
{
Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
m1 = Scalar(255, 0, 0);
imshow("m1原始图像", m1);
Mat m2 = m1;
m2 = Scalar(255, 255, 0);
imshow("m1图像", m1);
imshow("m2图像", m2);
}
可见当 采用" m2 = m1 ",即赋值方式时,m2和m1指向存储同一张图片的地址(空间),修改m2就相当于是修改m1。