Mat

Mat对象 面向对象的数据结构

数据结构是指数据对象 以及该数据对象集合中的数据元素之间的相互关系。包括数据的逻辑结构、数据的存储结构和数据的运算(操作)。例如,队列,栈 :线性表   ……

数据结构,数据类型,结构类型?
数据结构简单点指一个问题中用到的数据的值和关系表现在逻辑上是个什么样子,比如是个图表,还是一条直线,等等,
数据类型是指各种数据形态都不一样,比如有的是字母类,有的是整数类,有的是小数类,这些不同的数在计算机中将来所要分配的空间大小是不一样的.所以相当于是用数据类型限定这种数在计算机中该分配多大空间的.
结构类型是如果在计算机中存储数据的时候,是简单直接存储数据,还是要给他绑定一个空间放其他关系,相当于增大了数据的形态.比如结点 那么除了要存数据,还要在数据基础上存关系(指针),这样数据在原来逻辑基础上就变形了.这就是定义的时候重新设置类型了.

构造Mat的方法
构造Mat的方式有很多种,下面把常用的方法一一列出:
  1. 使用构造函数Mat(nrows, ncols, type, fillValue]),例如,
  1. 1
  2. 2
  1. // 构建3×2的4通道8位矩阵,每个元素初始值为(1,2,3,4)
  2. Mat M(3,2,CV_8UC4,Scalar(1,2,3,4));
  1. 使用M.create(nrows,ncols,type),例如,
  1. 1
  2. 2
  1. //构建100×100的10通道8位矩阵
  2. M.create(100,100,CV_8UC(10))
  1. 构建多维的矩阵,
  1. 1
  2. 2
  3. 3
  1. //构建一个100×100×100的8位三维矩阵
  2. int sz[] = {100,100,100}
  3. Mat Cube(3, sz, CV_32F, Scalar::all(0))
  1. 使用复制构造函数或者赋值操作符
  1. 1
  2. 2
  1. Mat A(B);
  2. Mat C = B;
  1. 单独对矩阵的某一行某一列进行操作
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  1. //第4行加上第6行的3倍赋值给第4
  2. M.row(3) = M.row(3) + M.row(5)*3;
  3. // 把第8列拷贝到第2列,通过 M.col(1) = M.col(7)是不起作用的,应该:
  4. Mat M1 = M.col(1);
  5. M.col(7).copyTo(M1);
  1. 构建矩阵的ROI区域,单独操作ROI区域的值
  1. 1
  2. 2
  3. 3
  1. Mat img(Size(320,240),CV_8UC3);
  2. Mat roi(img, Rect(10,10,100,100));
  3. roi = Scalar(0,255,0);
  1. \u2028确定矩阵在原矩阵中的相对位置,使用locateROI,
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  1. Mat A = Mat::eye(10, 10, CV_32S);
  2. Mat B = A(Range::all(), Range(1, 3));
  3. Mat C = B(Range(5, 9), Range::all());
  4. Size size; Point ofs;
  5. //得出ofs为(1,5),size为(10,10),为什么是(10,10)?目前没搞清楚
  6. C.locateROI(size, ofs);
  1. 对于外部数据输入,进行初始化
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  1. //外部输入一个一维数组
  2. void process_video_frame(const unsigned char* pixels, int width, int height, int step)
  3. {
  4.     Mat img(height, width, CV_8UC3, pixels, step);
  5.     GaussianBlur(img, img, Size(7,7), 1.5, 1.5);
  6. }
  7. //用二维数组初始化矩阵
  8. double m[2][3] = { {1, 2, 3}, {4, 5, 6} };
  9. Mat M = Mat(2, 3, CV_64F, m);
  1. IplImage,CvMat和Mat相互转换
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  1. IplImage* img = cvLoadImage("lena.jpg", 1);
  2. Mat mtx(img); // IplImage* -> Mat
  3. IplImage* img1 = mtx; //Mat -> IplImage*
  4. CvMat oldmat = mtx; // Mat -> CvMat
  5. Mat mtx1(oldmat);  //CvMat -> Mat
  1. 类似Matlab方式和<<赋值
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  1. //类似Matlab中的单位矩阵等
  2. M = Mat::ones(10, 10, CV_64F);
  3. M = Mat::eye(10, 10, CV_64F);
  4. M = Mat::zeros(10, 10, CV_64F);
  5. //使用`Mat_`和`<<`配合
  6. Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);


备注:
1 C++中一个类可以有很多个构造函数,但是参数一定要不一样。编译器会自动提供两个构造函数:默认构造函数和复制构造函数。析构函数只能有一个。
2、上述所指的常用方法指的Mat对象的 成员函数

补充两个数据成员:
rows  为像素的行数(int height = src.rows;)
cols   为像素的列数(int width   = src.cols;)


-->用复制(部分、全部)来创建一个Mat对象


备注:
Mat B(A);
单纯复制对象的头和指针部分时,不会复制数据部分,但是通过操作新的对象B时,会影响到我们的旧的对象A。而全部复制无影响,请尽情操作吧。










--> 用构造函数 或者 成员函数 来创建Mat对象

构造函数


格式:CV_ [每一项的位数] [有符号或无符号] [类型前缀] C [通道数]

 Mat dst;
    dst = Mat(src.size(), src.type());
    dst = Scalar(127, 0, 255);

备注: Scalar()向量表示初始化每个像素值, 参数需要和通道数保持一致 ,例如上述。


成员函数 或者先定义图像,再初始化像素值。

代码示例如下:

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

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
	Mat src = imread("liaowenbin.bmp");
	if (src.empty())
	{
		printf("Not file.../n");
		return -1;
	}
	//只会复制对象的头和指针
#if 0
	Mat dst(src);
	namedWindow("Picture",WINDOW_AUTOSIZE);
	imshow("Picture",dst);
#endif

	//完全复制 Mat clone()
#if 0
	Mat dst = src.clone();
	namedWindow("Picture", WINDOW_AUTOSIZE);
	imshow("Picture", dst);
#endif

	//完全复制 void copyTo(Mat Image)

#if 0
	Mat dst;
	src.copyTo(dst);
	namedWindow("Picture", WINDOW_AUTOSIZE);
	imshow("Picture", dst);
#endif

#if 0
	//定义小数组
	Mat dst =(Mat_<uchar>(3, 3) << 0, 5, 6, 
		3,4,5,
		4,2,1);
	cout << "dst = " << dst << endl;

	//单通道的像素指针
	uchar* p = dst.ptr(0); //0表示第1行
	//cout << "*p = " << *(p+1) << endl << endl << "src =" 
	//	<< src << endl;
	printf("*p = %hhd \n",*(p+8));

	system("Pause");
#endif

#if 0
	Mat dst(3,3,CV_8UC3,Scalar(1,23,45));
	cout << "dst = " << dst << endl << endl;
	
	//多通道的像素指针
	uchar* p = dst.ptr(0);
	cout << "p = " << static_cast<const void *>(p) << endl;
	printf("*p = %hhd \n",*(p+5));
	system("Pause");

#endif

	waitKey(0);
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玖零猴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值