1. 总结

先贴上我总结的Opencv的数据类型, 主要是针对不同Mat类型进行新建,修改和访问时使用, 更详细的数据访问见下文:

2. CV_8UC3解说

新建一个CV_8UC3型的cv::Mat, 其中U代表了unsigned char型的数据, 其表示的范围为0 到 255; C3表示三个通道, 也就是同一个位置能存放几个数字;
最常见的使用位置是用于保存图像类型, C3用于存储RGB彩色图像, C1用于存储灰度图像, 为什么用uchar型数据来存储图像数据, 这里有详细的解释.
总结来讲,就是int型的数据表示范围过大, 如果使用int型, 一副图像所占内存有点大, 而 uchar型数据范围刚好用来保存256级的像素, 节省空间;
具体的访问:

// CV_8UC3 的数据类型集访问
std::string image_path = myRGBimagePath;
cv::Mat input_image = cv::imread(image_path, -1);
std::cout << "input_image type: "<< input_image.type() << std::endl; //CV_8UC3 16
// 对uchar数据的访问, 三通道, 数据为uchar型, 显示时要用(int)进行强制转换
cv::Vec3b a_pixel = input_image.at<cv::Vec3b>(0,0); //127, 130, 128
//三个数字位于相同的像素位置, 但是属于不同的通道
std::cout << "pixel in center: " << (int)a_pixel[0] << ", "<<  (int)a_pixel[1] << ", " <<  (int)a_pixel[2] << std::endl;
//3. 8UC3转换成8UC1, 访问时直接使用uchar
cv::Mat input_gray(input_image.size(), CV_8UC1);
cv::cvtColor(input_image,input_gray,CV_RGB2GRAY);
std::cout << "input_gray <0,0> " << (int)input_gray.at<uchar>(0,0) <<std::endl;

3. CV_8SC2详解

接下来说一下不常见的CV_8S类型的数据, 以CV_8SC2为例, S代表了有符号 signed char, 8就代表了这个数据可以用8bit表示, 上面的unsigned char 型, 8bits 表示范围是0~255, 那么这里的signed char型表示的范围自然就正负各一半: - 128 到 127; C2代表了两个通道; 下面举个例子:

其中的每个元素都是8位的有符号整型;
假如这是5*5的Mat, 那么(0,0) 位置上有两个元素存放, 为(-85, -127);

这里对signed char型多通道Mat的访问, 如何用at实现,我还不太清楚, 这也就是为什么上面表格中第二行没有对应的Vec, 有了解的欢迎不吝赐教啊!!

这里举一个用行指针实现的Mat的访问:

//不同的数据类型的Mat可以通过convertTo() 函数进行转换
cv::Mat input_image_schar;
input_image.convertTo(input_image_schar, CV_8SC3);
//先读取第0行的数据
schar* mypixel = input_image_schar.ptr<schar>(0);
std::cout << "mypixel = " << (int)mypixel[0] << "," <<(int)mypixel[1] << ","<<(int)mypixel[2] << "," << std::endl;

有更多基础知识想要了解的,可以看这个OpenCV Tutorial (查看图片可能需要翻墙)

4. InputArray 与cv::Mat

cv::InputArray() 是opencv建立的一个更包容的类, 一般用在OpenCV的函数接口处; 可以承接Mat、Mat_、Mat_<T, m, n>、vector <T>、vector<vector<T>、vector<Mat> 类型的数据; 这里简单地与Mat做一个转换:

std::vector<cv::Point2f> myPoints_xy;
myPoints_xy.push_back(cv::Point2f(2.45,3.7));
myPoints_xy.push_back(cv::Point2f(3.68,8.8));
myPoints_xy.push_back(cv::Point2f(8.55,8.12));
//可以利用 vector<cv::Point2f>来初始化一个InputArray
cv::InputArray myArray_xy(myPoints_xy);
std::cout << "myArray_xy type: " << myArray_xy.type() << "myArray_xy size: " << myArray_xy.size()<< std::endl;
cv::Mat myMat_xy;//获取到矩阵数据并转换成CV_32FC2的类型
myArray_xy.getMat().convertTo(myMat_xy,CV_32FC2);
//CV_32F数据类型的访问也是比较简单易懂, 直接找到对应的Vec即可
cv::Vec2f tmpPoint = myMat_xy.at<cv::Vec2f>(0,0);
std::cout << "tmpPoint is " << tmpPoint[0] << "," << tmpPoint[1] << std::endl;//output:
myArray_xy.type() = 13: CV_32FC2 size: [3 x 1]
tmpPoint is 2.45,3.7

5. Mat的不同访问方式

int main()
{cv::Mat matF(3, 3, CV_32F);randu(matF, Scalar(0), Scalar(10));int rowIdx = 1;int colIdx = 1;// 1. 直接使用at<数据类型>(行值,列值)来访问float f1 = matF.at<float>(rowIdx, colIdx);// 2. 使用.data 获取数据存储区域的第一个数据的位置, step1() 代表的是一行总共有几个数据,3x3的CV_32FC4 一行有4*3=12个数据float* fData2 = (float*)matF.data;float f2 = fData2[rowIdx*matF.step1() + colIdx];// 3. 使用.ptr<数据类型>(0) 获取第一个元素的地址float* fData3 = matF.ptr<float>(0);float f3 = fData3[rowIdx*matF.step1() + colIdx];// 4.使用.ptr<数据类型>(行数) 的行指针形式进行访问float* fData4 = matF.ptr<float>(rowIdx);float f4 = fData4[colIdx];// 5. typedef Mat_<float> Mat1f, 数据访问会更加快速Mat1f mm(matF); // Or directly create like: Mat1f mm(3, 3);float f5 = mm(rowIdx, colIdx);// f1 == f2 == f3 == f4 == f5return 0;
}

这部分代码参考: SO上的问题
对于Mat的访问想进一步了解的, 可以参考我的这篇小白学习OpenCV Mat, 可能对于Step, Channel那些会有进一步的了解.

有什么问题,欢迎大家多多交流~~

OpenCV入门: Mat数据类型及其转换,访问相关推荐

  1. OpenCV中将Mat RGBA4通道转换成RGB3通道

    在OpenCV中,有一种数据结构是Mat,我们一般会定义一个frame的变量,这个变量可以是4通道的,也可以说3通道的. 前不久在一个项目中遇到了这个问题,要求是用ZED相机来实时拍摄视频并实时显示. ...

  2. 浮点数,字符串入门,基本数据类型自动转换,JDK7新特性, 变量.

    8.1 浮点型 **√ **float**类型又被称作单精度类型,尾数可以精确到7位有效数字,在很多情况下,float类型的精度很难满足需求. √ ****double表示这种类型的数值精度是floa ...

  3. OpenCV:Mat数据类型/16to8bit/RECT/画线填充

    Mat类型与数据类型对应关系: Unsigned 8bits uchar 0~255 Mat: CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4 Signed 8bits char ...

  4. C++读写txt文件方式以及基于opencv的Mat数据类型读写txt文件

    一.打开文件 在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是: void open(const char* filename,int mode,int access); ...

  5. python str转int_Python入门丨数据类型与转换

    数据类型 Python常见数据类型有三种:字符串(str).整数(int).浮点数(float) 字符串 字符串英文string,简写str 只要被单/双/三引号括起来的内容,无论内容是中文.英文还是 ...

  6. OpenCV中Mat,图像二维指针和CxImage类的转换

    在做图像处理中,常用的函数接口有OpenCV中的Mat图像类,有时候需要直接用二维指针开辟内存直接存储图像数据,有时候需要用到CxImage类存储图像.本文主要是总结下这三类存储方式之间的图像数据的转 ...

  7. opencv的mat赋值_OpenCV Mat 类型定义和赋值

    1.一般的Mat定义方法:cv::Mat M(height,width,),例: cv::Mat M(480,640,CV_8UC3); 表示定义了一个480行640列的矩阵,矩阵的每个单元的由三个( ...

  8. c++版opencv中的Mat数据类型的说明

    一直使用mat,很好用,但是细扣又说不清楚到底是怎样的一种数据类型,今天学习下. 一.先上硬货结论: 浅拷贝:拷贝构造函数和赋值运算符只复制信息头,即实际上还是同个图像数据.mat中存储同个数据地址: ...

  9. OpenCV 4.x API 详解与C++实例-Mat数据类型详解

    第二节 Mat数据类型详解 1.Mat数据类型描述 我们有多种从现实世界中获取数字图像的方法:数码相机,扫描仪,计算机断层扫描和磁共振成像等等. 在每种情况下,我们(人类)看到的都是图像. 但是,当将 ...

最新文章

  1. centos7安装mongodb3.4
  2. 睡前刷8分钟手机,身体兴奋1小时
  3. Linux System Programming --Chapter Eight
  4. python绘制3维图-Python 画出来六维图
  5. 使用Silverlight3中的DataPager实现服务器端分页
  6. 用ExayX在VS2019上输出文本有误的解决方案
  7. Spring boot maven 搭建框架
  8. ajax: jquery get request
  9. body里写注释 postman_是时候扔掉 Postman 了,试试 IntelliJ IDEA 自带的高能神器!
  10. Atitit. Toast alert loading js控件   atiToast v2新特性
  11. 显卡刷bios改型号_显卡BIOS刷新方法(详细)
  12. linux内存扩展,linux 扩展内存
  13. 计算机WIN7动态硬盘分区,如何创建Win7虚拟磁盘分区
  14. 弱网测试究竟要怎么做,才能防止漏测?
  15. [益智]:猴子搬香蕉
  16. Hydra-口令破解神器
  17. docker镜像指定安装源_如何修改docker pull镜像源
  18. 无纸化车间是怎样实现的,能给企业生产带来什么?
  19. VSCode Run code插件运行机制和配置文件的意思解释
  20. python梨视频爬虫下载,反反爬

热门文章

  1. bzoj 4548: 小奇的糖果 bzoj 3658: Jabberwocky(双向链表+树状数组)
  2. Java 图形化界面 实现ASCII码的转换和查看
  3. 各大厂大数据精品分享汇总(进阶版)
  4. 判断Mouse事件源类型
  5. struts2_struts2线程安全吗?
  6. 文件上传的几个 - 示例
  7. 2-9 prev + next选择器 “远亲不如近邻” 返回且只返回唯一-个元素。 而通过prev + next选择器就可以查找与“prev”元素紧邻的下一个“next”元素...
  8. install intel c/c++ compiler
  9. Spark Streaming源码解读之Driver中ReceiverTracker架构设计以具体实现彻底研究
  10. 【接口测试】FitNesse中文指南