请选择 进入手机版 | 继续访问电脑版

Hello Mat

 找回密码
 立即注册
查看: 7865|回复: 2

关于opencv中Mat类的基本操作

  [复制链接]

10

主题

15

帖子

0

金钱

新手上路

Rank: 1

积分
15
发表于 2016-10-25 20:19:18 | 显示全部楼层 |阅读模式
对于新手学习opencv,了解Mat类是最基本的要求。为了方便大家学习,对Mat的用法做了一些总结,希望对各位opencv初学者有所帮助。总结大部分是基于例子来写的,感觉这样更容易理解。
1. 创建 Mat  对象
1.1 构造函数方法
Mat M(3,2, CV_8UC3, Scalar(0,0,255));
第一行代码创建一个行数(高度)为 3,列数(宽度)为 2 的图像,图像元素是 8 位无符号整数类型,且有三个通道。图像的所有像素值被初始化为(0, 0,255)。
常用的构造函数有:
 Mat::Mat()
无参数构造方法;
 Mat::Mat(int rows, int cols, int type)
创建行数为 rows,列数为 col,类型为 type 的图像;
 Mat::Mat(Size size, int type)
创建大小为 size,类型为 type 的图像;
 Mat::Mat(int rows, int cols, int type, const Scalar& s)
创建行数为 rows,列数为 col,类型为 type 的图像,并将所有元素初始
化为值 s;
 Mat::Mat(Size size, int type, const Scalar& s)
创建大小为 size,类型为 type 的图像,并将所有元素初始化为值 s;
 Mat::Mat(const Mat& m)
将 m 赋值给新创建的对象, 此处不会对图像数据进行复制, m 和新对象共用图像数据;
 Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
创建行数为 rows,列数为 col,类型为 type 的图像,此构造函数不创建图像数据所需内存, 而是直接使用 data 所指内存, 图像的行步长由 step指定。
 Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
创建大小为 size,类型为 type 的图像,此构造函数不创建图像数据所需内存,而是直接使用 data 所指内存,图像的行步长由 step 指定。
 Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
创建的新图像为 m 的一部分,具体的范围由 rowRange 和 colRange 指定, 此构造函数也不进行图像数据的复制操作, 新图像与 m 共用图像数据;
 Mat::Mat(const Mat& m, const Rect& roi)
创建的新图像为 m 的一部分,具体的范围 roi 指定,此构造函数也不进行图像数据的复制操作,新图像与 m 共用图像数据。
这些构造函数中, 很多都涉及到类型type。 type可以是CV_8UC1, CV_16SC1, …,CV_64FC4 等。里面的 8U 表示 8 位无符号整数,16S 表示 16 位有符号整数,64F表示 64 位浮点数(即 double 类型) ;C 后面的数表示通道数,例如 C1 表示一个通道的图像,C4 表示 4 个通道的图像,以此类推。
1.2 create() 函数创建对象
Mat M(2,2, CV_8UC3);//构造函数创建图像
M.create(3,2, CV_8UC2);//释放内存重新创建图像
2 像素值的读写
很多时候, 我们需要读取某个像素值, 或者设置某个像素值; 在更多的时候,我们需要对整个图像里的所有像素进行遍历。OpenCV 提供了多种方法来实现图像的遍历。
2.1 at() 函数
uchar value = grayim.at<uchar>(i,j);//读出第 i 行第 j 列像素值
grayim.at<uchar>(i,j)=128; //将第 i 行第 j 列像素值设置为 128
下面是个简单的图像遍历程序
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
Mat grayim(600, 800, CV_8UC1);
Mat colorim(600, 800, CV_8UC3);
//遍历所有像素,并设置像素值
for( int i = 0; i < grayim.rows; ++i)
for( int j = 0; j < grayim.cols; ++j )
grayim.at<uchar>(i,j) = (i+j)%255;
//遍历所有像素,并设置像素值
for( int i = 0; i < colorim.rows; ++i)
for( int j = 0; j < colorim.cols; ++j )
{
Vec3b pixel;
pixel[0] = i%255; //Blue
pixel[1] = j%255; //Green
pixel[2] = 0; //Red
colorim.at<Vec3b>(i,j) = pixel;
}
//显示结果
imshow("grayim", grayim);
imshow("colorim", colorim);
29
waitKey(0);
return 0;
}
2.2 使用迭代器
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
Mat grayim(600, 800, CV_8UC1);
Mat colorim(600, 800, CV_8UC3);
//遍历所有像素,并设置像素值
MatIterator_<uchar> grayit, grayend;
30
for(  grayit  =  grayim.begin<uchar>(),  grayend  =
grayim.end<uchar>(); grayit != grayend; ++grayit)
*grayit = rand()%255;
//遍历所有像素,并设置像素值
MatIterator_<Vec3b> colorit, colorend;
for(  colorit  =  colorim.begin<Vec3b>(),  colorend  =
colorim.end<Vec3b>(); colorit != colorend; ++colorit)
{
(*colorit)[0] = rand()%255; //Blue
(*colorit)[1] = rand()%255; //Green
(*colorit)[2] = rand()%255; //Red
}
//显示结果
imshow("grayim", grayim);
imshow("colorim", colorim);
waitKey(0);
return 0;
}
3 从图像中抠出感兴趣的部分
//创建宽度为 320,高度为 240 的 3 通道图像
Mat img(Size(320,240),CV_8UC3);
//roi 是表示 img 中 Rect(10,10,100,100)区域的对象
Mat roi(img, Rect(10,10,100,100));
4 Mat之间的运算
同样给出一个简单程序
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
Mat A = Mat::eye(4,4,CV_32SC1);
Mat B = A * 3 + 1;
Mat C = B.diag(0) + B.col(1);
cout << "A = " << A << endl << endl;
cout << "B = " << B << endl << endl;
cout << "C = " << C << endl << endl;
cout << "C .* diag(B) = " << C.dot(B.diag(0)) << endl;
return 0;
}
5. Mat和IplImage、cvMat之间的相互转换
Mat img(Size(320, 240), CV_8UC3);
...
IplImage iplimg = img; //转为 IplImage 结构
mycvOldFunc( & iplimg, ...);//对 iplimg 取地址
CvMat cvimg = img; //转为 CvMat 结构
IplImage * iplimg = cvLoadImage("lena.jpg");
Mat im(iplimg, true);

回复

使用道具 举报

1288

主题

1514

帖子

90

金钱

管理员

Rank: 9Rank: 9Rank: 9

积分
22589
发表于 2016-10-25 20:29:27 | 显示全部楼层
最好能全部使用Mat格式,并且给出可执行代码,而不只是复制粘贴啊,不然也就浪费网络资源了
算法QQ  3283892722
群智能算法链接http://halcom.cn/forum.php?mod=forumdisplay&fid=73
回复 支持 反对

使用道具 举报

10

主题

15

帖子

0

金钱

新手上路

Rank: 1

积分
15
 楼主| 发表于 2016-10-25 20:36:37 | 显示全部楼层
Halcom 发表于 2016-10-25 20:29
做好能全部使用Mat使用,并且给出可执行代码,而不只是复制粘贴啊,不然也就浪费网络资源了

里面给了好多的可执行代码呢,知识不知道怎样加载图片啊,就没把运行结果放上去。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Python|Opencv|MATLAB|Halcom.cn ( 蜀ICP备16027072号 )

GMT+8, 2024-3-29 20:49 , Processed in 0.264237 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表