OpenCV的Mat数据格式及其遍历的程序资料说明

合集下载

opencv中mat类介绍

opencv中mat类介绍

opencv中mat类介绍The class Mat represents an n-dimensional dense numerical single-channel or multi-channelarray. It can be used to store (Mat类的对象用于表示一个多维度的单通道或者多通道稠密数组,它可以用来存储以下东西)real or complex-valued vectors or matrices 实数值或复合值向量、矩阵) (grayscale or color images (灰度图或者彩色图)voxel volumes (立体元素)vector fields (矢量场)point clouds (点云)tensors (张量) histograms (though, very high-dimensional histograms may be better直方图,高纬度的最好存放在Sparse stored in a SparseMat )Opencv中mat类是核心类,用于存储图像信息,主要包括两部分,矩阵头信息和矩阵的数据信息。

头信息固定大小,数据信息极大。

Mat类的对象进行赋值和拷贝构造时仅仅生成头信息的备份和数据指针1 cv::Mat a ;//创建矩阵头2 a = cv::imread("xxx.jpg");//读入图像3 cv::Mat b = a ;//复制b和a指向同一个矩阵,增加的时引用计数若要实现实际上的独立赋值,需要使用mat的clone()和copyTo()函数1 cv::Mat c = a.clone();2 cv::Mat d ;3 c.copyTo(d);mat的常用属性datauchar型的指针。

Mat类分为了两个部分:矩阵头和指向矩阵数据部分的指针,data就是指向矩阵数据的指针。

dims矩阵的维度,例如5*6矩阵是二维矩阵,则dims=2,三维矩阵dims=3.rows矩阵的行数cols矩阵的列数size矩阵的大小,size(cols,rows),如果矩阵的维数大于2,则是size(-1,-1)channels矩阵元素拥有的通道数。

open cv中的Mat详解

open cv中的Mat详解

通常比矩阵头的尺寸大数个数量级。因此,当在程序中传递图像并创建拷贝时,大的开销 是由矩阵造成的,而不是信息头。OpenCV 是一个图像处理库,囊括了大量的图像处理函数, 为了解决问题通常要使用库中的多个函数,因此在函数中传递图像是家常便饭。同时不要忘 了我们正在讨论的是计算量很大的图像处理算法,因此,除非万不得已,我们不应该拷 贝 大 的图像,因为这会降低程序速度。 二、Mat 的基本操作
如果想建立互不影响的 Mat,是真正的复制操作,需要使用函数 clone()或者 copyTo()。
说到数据的存储,这一直就是一个值得关注的问题,Mat_<uchar>对应的是 CV_8U, Mat_<uchar>对应的是 CV_8U,Mat_<char>对应的是 CV_8S,Mat_<int>对应的是 CV_32S, Mat_<float>对应的是 CV_32F,Mat_<double>对应的是 CV_64F,对应的数据深度如下:
需要注意的是,copy 这样的操作只是 copy 了矩阵的 matrix header 和那个指针,而不是矩 阵的本身,也就意味着两个矩阵的数据指针指向的是同一个地址,需要开发者格外注意。比 如上面这段程序,A、B、C 指向的是同一块数据,他们的 header 不同,但对于 A 的操作 同样也影响着 B、C 的结果。刚刚提高了内存自动释放的问题,那么当我不再使用 A 的时 候就把内存释放了,那时候再操作 B 和 C 岂不是很危险。不用担心,OpenCV 的大神为我 们已经考虑了这个问题,是在最后一个 Mat 不再使用的时候才会释放内存,咱们就放心用 就行了。
在 2001 年刚刚出现的时候,OpenCV 基于 C 语言接口而建。为了在内存(memory) 中存放图像,当时采用名为 IplImage 的 C 语言结构体,时至今日这仍出现在大多数的旧 版教程和教学材料。但这种方法必须接受 C 语言所有的不足,这其中最大的不足要数手动内 存管理,其依据是用户要为开辟和销毁内存负责。虽然对于小型的程序来说手动管理内 一、Mat 简介

OPENCV对于Mat的理解和操作

OPENCV对于Mat的理解和操作

OPENCV对于Mat的理解和操作1,Mat 是⽤来存储图⽚的数据他会把图⽚变成矩阵Mat src;int main(int argc, char** argv){src = imread("F:\\视觉\\opencv\\pic\\MatTest.png");//读图⽚cout << "灰度化后" << endl;cout << src << endl;}矩阵的格式如下图⽚时这样的:⽤dos显⽰是这样的灰度化之后是这样的怎么样是不是看上去有点熟悉没错,灰度化后直接把每个位置的像素的值,组成⼀个矩阵,⽽没有灰度化时是如图⼀所⽰。

2,Mat获取某⼀点坐标的值cout << (int)src.ptr<uchar>(1)[1] << endl;锐化的案例:int cols = (src.cols-1)*src.channels();int rows = src.rows;int channels = src.channels();int offsetx = src.channels();Mat dst1 = Mat::zeros(src.size(), src.type());for (int row = 1; row < (rows - 1); row++){const uchar* previous = src.ptr<uchar>(row - 1);const uchar* current = src.ptr<uchar>(row);const uchar* next = src.ptr<uchar>(row + 1);uchar* output = dst1.ptr<uchar>(row);for (int col = offsetx; col < cols; col++) {output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col])); }}imshow("锐化转化后", dst1);src.ptr<uchar>(row);是获取第⼏⾏的指针src.ptr<uchar>(1)[1];默认是char类型,所以要转成int类型输出才能看得到,不然会输出Hex码表对于的字符信息。

open cv中的Mat详解

open cv中的Mat详解
OpenCV 学习笔记(四十)——再谈 OpenCV 数据结构 Mat 详解
分类: OpenCV2011-12-28 10:33 26348 人阅读 评论(16) 收藏 举报 数据结构 matrixheadernumbers 存储 matlab
我记得开始接触 OpenCV 就是因为一个算法里面需要 2 维动态数组,那时候看 core 这部分 也算是走马观花吧,随着使用的增多,对 Mat 这个结构越来越喜爱,也觉得有必要温故而 知新,于是这次再看看 Mat。
在 2001 年刚刚出现的时候,OpenCV 基于 C 语言接口而建。为了在内存(memory) 中存放图像,当时采用名为 IplImage 的 C 语言结构体,时至今日这仍出现在大多数的旧 版教程和教学材料。但这种方法必须接受 C 语言所有的不足,这其中最大的不足要数手动内 存管理,其依据是用户要为开辟和销毁内存负责。虽然对于小型的程序来说手动管理内 一、Mat 简介
亲,有木有很简单!!!
还有一种快速初始化数据的办法,如下:
[cpp] view plaincopy
1.double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; 2.Mat M = Mat(3, 3, CV_64F, m).inv();
也可以把原来的 IplImage 格式的图片直接用 Mat(IplImage)的方式转成 Mat 结构,也可 以像 Matlab 一样调用 zeros()、ones()、eye()这样的函数进行初始化。
幸运的是,C++出现了,并且带来类的概念,这给用户带来另外一个选择:自动的内存 管理(不严谨地说)。这是一个好消息,如果 C++完全兼容 C 的话,这个变化不会带来兼容 性问题。为此,OpenCV 在 2.0 版本中引入了一个新的 C++接口,利用自动内存管理给出了解 决问题的新方法。使用这个方法,你不需要纠结在管理内存上,而且你的代码会变得简洁(少 写多得)。但 C++接口唯一的不足是当前许多嵌入式开发系统只支持 C 语言。所以,当目标 不是这种开发平台时,没有必要使用 旧 方法(除非你是自找麻烦的受虐狂码农)。

OpenCV中对Mat的遍历访问与赋值

OpenCV中对Mat的遍历访问与赋值

OpenCV中对Mat的遍历访问与赋值⼀、访问对于Mat的访问有两种⽅式第⼀种,利⽤Mat::at进⾏访问//读取3通道彩⾊图像Mat img = imread("图⽚地址");int px;//读取图像中第⼀⾏第⼀列,Blue通道数据int px = img.at<Vec3b>(0, 0)[0];第⼆种,利⽤Mat的成员ptr指针进⾏访问//读取3通道彩⾊图像Mat img = imread("图⽚地址");//将Mat中的第⼀⾏地址赋予pxVecuchar* pxVec=img.ptr<uchar>(0);//遍历访问Mat中各个像素值int i, j;int px;for (i = 0; i < img.rows; i++){pxvec = img.ptr<uchar>(i);//三通道数据都在第⼀⾏依次排列,按照BGR顺序//依次赋值为1for (j = 0; j < img.cols*img.channels(); j++){px=pxvec[j];//do anything}}⼆、赋值不能⽤Mat::at进⾏赋值,只能⽤ptr对Mat中的像素点进⾏赋值⼀个完整的例⼦如下:#include "stdafx.h"#include <opencv2\core\core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2\imgproc\imgproc.hpp>#include <vector>int main(){//对Mat进⾏遍历赋值//初始化Mat数据结构,256*256,三通道8位(256⾊)图像Mat myimg(256,256,CV_8UC3);//取像素数据⾸地址uchar* pxvec = myimg.ptr<uchar>(0);int i, j;for (i = 0; i < myimg.rows; i++){pxvec = myimg.ptr<uchar>(i);//三通道数据都在第⼀⾏依次排列,按照BGR顺序//依次赋值为1for (j = 0; j < myimg.cols*myimg.channels(); j++){pxvec[j] = 1;}}//展⽰图像imshow("abc", myimg); waitKey(10000);}结果如下:。

opencv中Mat使用,很好,顶!

opencv中Mat使用,很好,顶!

opencv中Mat使用,很好,顶!(一)Mat矩阵中数据指针Mat.data是uchar类型指针,CV_8U 系列可以通过计算指针位置快速地定位矩阵中的任意元素。

二维单通道元素可以用Mat::at(i, j)访问,i是行序号,j是列序号。

但对于多通道的非unsigned char类型矩阵来说,以上方法都不好(注:后来知道可以通过类型转换,用指针访问data数据,见后文)。

可以用Mat::ptr()来获得指向某行元素的指针,在通过行数与通道数计算相应点的指针。

参照OpenCV的Mat::at()函数,写了一个访问二维Mat矩阵的两个简单的小函数,没有边界检查。

1#include <opencv2/core/core.hpp>23template<typename ItemType>4ItemType* getMatPointPtr(cv::Mat & src, int i , int j , int c = 0)5{6ItemType* curRow = src.ptr<ItemType>(i); 7return curRow + j * src.channels() + c; 8}9template<typename ItemType>10ItemType getMatPoint(cv::Mat & src, int i , int j , int c = 0)11{12ItemType* curRow = src.ptr<ItemType>(i);13return *(curRow + j * src.channels() + c);14}OpenCV中的Mat::at()代码有严格的边界检测,Mat::ptr()也有边界检测,但代码中没有检测j是否越界。

以上为推荐使用的情况,下边的不推荐使用。

可以通过转换指针类型,访问非uchar类型的Mat元素。

opencv mat类运算

opencv mat类运算

opencv mat类运算OpenCVMat类是一个非常重要的数据结构,可以表示图像、矩阵和向量等,在计算机视觉和图形学领域广泛应用。

本文将介绍Mat类的基本操作,包括创建、访问、赋值、运算等。

1. 创建Mat对象首先,我们可以通过以下两种方式创建一个Mat对象:(1)使用构造函数:Mat(int rows, int cols, int type);(2)使用静态方法:Mat::zeros(int rows, int cols, int type);其中,rows和cols表示矩阵的行数和列数,type表示数据类型和通道数,常用的有CV_8UC1、CV_8UC3、CV_32FC1等。

2. 访问Mat元素访问Mat对象的元素可以使用at()方法或者指针操作符[],例如:Mat img = imread('image.jpg', CV_LOAD_IMAGE_GRAYSCALE); uchar pixel = img.at<uchar>(i, j);或者:uchar* data = img.ptr<uchar>(i);uchar pixel = data[j];3. 赋值操作Mat对象之间可以进行赋值操作,例如:Mat img = imread('image.jpg', CV_LOAD_IMAGE_GRAYSCALE);Mat img2 = img.clone();4. 运算操作Mat对象之间可以进行加、减、乘、除等运算,例如:Mat img1 = imread('image1.jpg', CV_LOAD_IMAGE_GRAYSCALE); Mat img2 = imread('image2.jpg', CV_LOAD_IMAGE_GRAYSCALE); Mat img_add = img1 + img2;Mat img_sub = img1 - img2;Mat img_mul = img1.mul(img2);Mat img_div = img1 / img2;除此之外,还可以进行矩阵转置、矩阵相乘、矩阵求逆、矩阵求特征值等高级运算。

opencv mat类运算

opencv mat类运算

opencv mat类运算OpenCVMat类是OpenCV中最基本的数据类型之一。

它代表一个多维数组,可以用于存储图像、矩阵、点云等数据。

在实际应用中,我们经常需要对Mat对象进行各种运算,本文将介绍一些常用的Mat 类运算。

1. Mat对象的创建和初始化在使用Mat对象之前,我们需要创建它并对其进行初始化。

创建Mat对象的方法如下:Mat image;//创建一个空的Mat对象Mat image(rows,cols,type);//创建指定大小和类型的Mat对象其中,rows表示矩阵的行数,cols表示矩阵的列数,type表示矩阵的数据类型,常用的类型有CV_8UC1(8位无符号单通道)、CV_8UC3(8位无符号三通道)、CV_32FC1(32位浮点单通道)等。

Mat对象的初始化可以通过赋值、拷贝、从文件读取等方式进行。

2. Mat对象的运算Mat对象支持各种数学运算,包括加、减、乘、除、逻辑运算等。

下面以加法运算为例,介绍Mat对象的运算。

Mat a(rows,cols,CV_8UC1,Scalar(1));//创建一个大小为rows*cols,类型为CV_8UC1,值为1的Mat对象Mat b(rows,cols,CV_8UC1,Scalar(2));//创建一个大小为rows*cols,类型为CV_8UC1,值为2的Mat对象Mat result = a + b;//将a和b相加,结果保存在result中在进行运算时,需要注意Mat对象的大小和数据类型必须相同,否则会导致运算失败。

此外,Mat对象的运算速度较慢,应尽量避免在循环中使用。

3. Mat对象的转换Mat对象可以进行类型转换和通道分离,以便在不同的应用场景中使用。

下面以类型转换为例,介绍Mat对象的转换。

Mat a(rows,cols,CV_8UC1,Scalar(1));//创建一个大小为rows*cols,类型为CV_8UC1,值为1的Mat对象Mat b;//创建一个空的Mat对象a.convertTo(b, CV_32FC1);//将a转换为CV_32FC1类型,结果保存在b中在进行类型转换时,需要注意目标类型应该能够容纳源类型的值,否则会丢失精度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

OpenCV 的Mat 数据格式及其遍历的程序资料说明
在opencv 早期的版本中,图像通过一个叫做IplImage 的结构(structure)存储在内存中。

由于C 语言对程序员高度的信任,因此它需要手动地对内存
进行管理,比如内存的分配和回收,这在大型程序设计中是比较麻烦的。


运地是,C++可以很好地帮助程序员管理内存,因此opencv2.0 后就引入了
C++接口。

但是C++也有缺点,比如说目前大部分的嵌入式系统只支持C 语言,在这些平台上开发opencv 程序的话用C++就不是很好。

cv::Mat 是一个C++类,包含两部分:1)Matrix header,包括矩阵的size、存储方式、矩阵的存储地址等信息;2)指向Marix 的指针ji。

由于图
像处理算法通常都是计算密集型算法,出于程序速度上的考虑,opencv 的设
计应尽可能地避免拷贝大图像,为了解决这个问题,opencv 使用了引用计数
机制(reference counter system)【python 也使用了这个机制,参考之前的博客】。

简单来说,灭个Mat 对象都有自己的header,在进行copy 运算时,只
有headers 和指向矩阵的指针会被拷贝,而矩阵本身不会被拷贝,举个栗子:
上面的三个Mat 对象srcImg,dstImg,C 最终都只想同一个数据矩阵,虽然
它们的headers 是不同的。

对它们其中的任意一个进行修改都会影响另外两个对象。

上面程序的运行结果如图:
当然,如果想拷贝矩阵本身也是有办法的,opencv 提供了两个方法:。

相关文档
最新文档