2.RV1126-OPENCV Mat理解和AT函数

article/2025/7/19 1:22:14

一.Mat概念

        Mat 是整个图像存储的核心也是所有图像处理的最基础的类,Mat 主要存储图像的矩阵类型,包括向量、矩阵、灰度或者彩色图像等等。Mat由两部分组成:矩阵头,矩阵数据。矩阵头是存储图像的长度、宽度、色彩信息等头部信息;矩阵数据则是存储具体的图像数据。(我的理解就是,Mat是把图像分为一块一块矩阵类型保存,矩阵头显示这张图片基本信息,如这张图片多大,是不是彩色;具体的信息存储由矩阵数据存储)。

二.Mat通道

图中C1,C2,C3,C4代表几通道 ;前面CV_8U,8S,16U,16S,32U,32S代表用什么类型存储,例如:CV_8U就是用8位无符号类型存储,CV_8S就是用8位有符号存储。

  •  单通道(灰度图),就是图片是灰色的

  •  双通道(二值图像),就是黑白照片

  •  三通道(RGB 彩色图像)

  •  四通道(带 Alpha 的四通道图像),就是ARGB图像,更好看一点。

 三.Mat创建和构造方法

  • Mat(int rows, int cols, int type);

 重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols 以及存储类型 type
rows:行数,也指的是图像的高度,height。
cols:列数,也指的是图像的宽度,width。
type:通道类型,具体的看上面的图
示例:Mat t1 = Mat(300,300,CV_8UC1),这指的是创建一个 width:300,height:300,单通道的灰度图像.

  •  Mat(Size size, int type);

 重载的构造函数,这个构造函数在创建的时候,需要传入 Size 类和类型。
第一个传参:Size 结构体,Size(width,height)
第二个传参:type 通道类型,具体的看上面的图
示例:Mat t2 = Mat(Size(300,300),CV_8SC3),这指的是创建一个 width:300,height:300,三通道的灰度图像

  •  Mat(int rows, int cols, int type, const Scalar& s);

 重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols、存储类型 type、还有 Scalar 颜色标量。
第一个传参:rows 行数,也指的是图像的高度,height。
第二个传参:cols 列数,也指的是图像的宽度,width。
第三个传参:type 通道类型,具体的看上面的图
第四个传参:Scalar 颜色标量,Scalar(v0,v1,v2,v3),v0,v1,v2,v3 分别对应 OPENCV 颜色分量的四个值
示例: Mat mat = Mat(300,300,CV_8UC3,Scalar(255,255,255));表示的是创建cols:300,rows:300,三通道的灰度,颜色标量为白色的图像

  • Mat::zeros(rows,cols,type); 

 重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols 以及存储类型 type。ZEROS 相当于创建一张黑色的图片,每个像素通道为 0,并且 Scalar(0,0,0)。
第一个传参:rows 行数,也指的是图像的高度,height。
第二个传参:cols 列数,也指的是图像的宽度,width。
第三个传参:type 通道类型,具体的看上面的图
示例: Mat::zeros(300,300,CV_8SC3);,这指的是创建一个 width:300,height:300,三通道的彩色图像,Scalar(0,0,0),相当于Mat mat = Mat(300,300,CV_8SC3,Scalar(0,0,0));

  •  Mat::ones(rows,cols,type);

 重载的构造函数,这个构造函数在创建的时候,提供矩阵的大小,分别是 rows、cols 以及存储类型 type。ONES 相当于每个像素第一个通道为 1,后面两个通道为 0。
第一个传参:rows 行数,也指的是图像的高度,height。
第二个传参:cols 列数,也指的是图像的宽度,width。
第三个传参:type 通道类型,具体的看上面的图
示例: Mat::ones(300,300,CV_8SC3),这指的是创建一个 width:300,height:300, 三通道的彩色图像,Scalar(1,0,0),这等同于 Mat mat = Mat(300,300,CV_8SC3,Scalar(1,0,0));

四. imread读取图片信息和imwrite写入数据

  1. imread:读取图片信息。

 Mat imread( const String& filename, int flags = IMREAD_COLOR );

第一个参数:filename 图片的名称,名称可以是绝对路径也可以是相对路径
第二个参数:flags 标识符,flags 标识符默认为 IMREAD_COLOR。flags 一般分为三种:
IMREAD_UNCHANGED(<0)按原样加载图像(包括 alpha 通道(如果存在)
IMREAD_GRAYSCALE(0)将图像作为强度加载(灰白照片)
IMREAD_COLOR(> 0)以 RGB 格式加载图像(彩色照片)

返回值:Mat 矩阵

  • 例如:读取彩色三通道图片

Mat img_mat = imread("frame1.jpg");
printf("width = %d, height = %d, channels = %d\n", img_mat.cols, img_mat.rows, img_mat.channels());
...........................................................................................
输出结果:width = 1920, height = 1080, channels = 3

  • 例如:读取灰白单通道图片

Mat img_mat_gray = imread("gray_frame1.jpg", IMREAD_GRAYSCALE);
printf("img_mat_gray_width = %d, img_mat_gray_height = %d, img_mat_gray_channels = %d\n", img_mat_gray.cols,img_mat_gray.rows, img_mat_gray.channels());
.................................................................................................................
输出的结果:img_mat_gray_width = 1920, img_mat_gray_height = 1080, img_mat_gray_channels = 1 

2. imwrite:保存图片

 imwrite(const String& filename, InputArray image, const std::vector<int>& params);

第一个传参:filename 表示要保存的文件名
第二个传参:image 表示需要保存的图像数据
第三个传参:params 保存图像可选参数,主要是设置图像的质量,设置规则具体的我们来看看,该参数需要按照参数 id+参数值成对出现,可以出现多对参数值(比如 (paramId_1, paramValue_1, paramId_2, paramValue_2, ...)),但必须保证这些参数对是相关的,比如保存 JPG 图像时,只能使用和 JPEG 相关的参数 ID 进行组合使用。这里的 ID 基本上是 cv::ImwriteFlags。

  • 例如:使用默认的方式 imwrite 保存图片

Mat mat = Mat(300,300,CV_8UC3,Scalar(218,112,214));
imwrite("mat_demo.jpg", mat);
。。。。。。。。。。。。。。。。。。
上面是使用默认的方法保存图片,这种方法的所有参数都是默认选项。出来图片就是:

  •  使用 params 的方式 imwrite 保存图片

Mat quality_frame1_mat = imread("frame1.jpg");
std::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 40};
imwrite("quality_mat_demo.jpg", quality_frame1_mat , params);
。。。。。。。。。。。。。。。。。。。。。。。。。
这种方法使用的是 params 参数的方式去设置,上面我们设置了图像的质量在 40,大家如果想设置其他功能可以参考上面的枚举进行设置。经过编码质量 40 的处理后的图像大小小于原图像大小,这说明编码质量关乎着文件的大小和画面的质量

五.代码具体

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace cv; //Must Need Write cv
using namespace std;int main()
{//构造参数Mat t0 = Mat(300,300,CV_8UC1); //Create a 300x300 single channel matrixMat t1 = Mat(Size(200,200),CV_8UC1); //Create a 300x300 single channel matrixMat t2 = Mat(100,100,CV_8UC1,Scalar(255,255,255)); //Create a 300x300 single channel matrixMat t3 = Mat::zeros(300,300,CV_8UC1); //Create a 300x300 single channel matrixMat t4 = Mat::ones(200,200,CV_8UC1); //Create a 300x300 single channel matrixstd::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 40};//imwrite写入数据imwrite("t0.jpg",t0);imwrite("t1.jpg",t1);imwrite("t2.jpg",t2);imwrite("t3.jpg",t3,params);imwrite("t4.jpg",t4);//imread读取数据Mat a0 = imread("t0.jpg");Mat a1 = imread("t3.jpg");Mat a2 = imread("t4.jpg",IMREAD_GRAYSCALE);printf("a0 heigh:%d weigh: %d channel:%d\n",a0.rows,a0.cols,a0.channels());printf("a3 heigh:%d weigh: %d channel:%d\n",a2.rows,a2.cols,a2.channels());return 0;
}

六.AT函数

1.作用         

        AT函数:就是用于修改Mat矩阵的像素值(上面用Mat创建的图片,这个图片都是一格一格像素点形成的,我们要想修改图片颜色,就要用到AT函数对像素点值修改就行)。AT 函数的修改一般需要循环 cols 和 rows 然后对每个像素点进行修改。

2. 定义

        at<typename>(int i, int j)

第一个参数:typename 指的是 OPENCV 的向量类型,(总结:1,2,3,4就是几通道,也可以理解为几维图像;后面b,s,w,i之类就是用什么类型读取,整型,还是字符读取),向量类型如下:

typedef Vec<uchar, 2> Vec2b:uchar 类型的数组,长度为 2, 它表示的是二维图像的位置信息、尺寸等等
typedef Vec<uchar, 3> Vec3b:uchar 类型的数组,长度为 3,它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是 uchar 类型
typedef Vec<uchar, 4> Vec4b:uchar 类型的数组,长度为 4,它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 uchar 类型
typedef Vec<short, 2> Vec2s:short 类型的数组,长度为 2, 它表示的是二维图像的位置信息、尺寸等等,但不能做像素处理
typedef Vec<short, 3> Vec3s:short 类型的数组,长度为 3, 它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是 short 类型
typedef Vec<short, 4> Vec4s:short 类型的数组,长度为 4, 它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 short 类型
typedef Vec<ushort, 2> Vec2w:ushort 类型的数组,长度为 2,它表示的是二维图像的位置信息、尺寸等等,但不能做像素处理
typedef Vec<ushort, 3> Vec3w:ushort 类型的数组,长度为 3,它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是 ushort 类型
typedef Vec<ushort, 4> Vec4w:ushort 类型的数组,长度为 4,它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 ushort 类型
typedef Vec<int, 2> Vec2i: int 类型的数组,长度为 2, 它表示的是一个包含 2 个整数的元素向量,并不能直接表示通道数
typedef Vec<int, 4> Vec4i: int 类型的数组,长度为 4, 它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是 int 类型
typedef Vec<int, 6> Vec6i: int 类型的数组,长度为 6, 它常用于表示六维图像,包括:坐标、描述子、颜色直方等等,但是不能对六维图像直接进行处理
typedef Vec<int, 8> Vec8i: int 类型的数组,长度为 8, 它常用于表示八维图像,包括:坐标、描述子、颜色直方等等,但是不能对八维图像直接进行处理
typedef Vec<float, 2> Vec2f:float 类型的数组,长度为 2,它表示的是二维图像的位置信息,但不能做通道处理
typedef Vec<float, 3> Vec3f:float 类型的数组,长度为 3,它常用于彩色图像的像素值以及对 rgb 三个通道的处理,并且通道的像素值都是浮点数
typedef Vec<float, 4> Vec4f:float 类型的数组,长度为 4,它常用于彩色图像的像素值以及对 argb 四个通道的处理,并且通道的像素值都是浮点数
typedef Vec<float, 6> Vec6f: float 类型的数组,长度为 4,他用于处理 6 个维度的图像数据,需要注意的是 Vec6f 仅仅能表示具有 6 个维度的数据,并不可以对数据进行操作.
typedef Vec<double, 2> Vec2d:double 类型的数组,长度为 2,在图像处理中 Vec2d 仅仅只是表示具有 double 类型的图像数据,但是并不能直接操作数据像素
typedef Vec<double, 3> Vec3d:double 类型的数组,长度为 3,它常用于表示图像的彩色三通道,分别是 R(红色)、G(绿色)、B(蓝色),并且对于这三个通道的像素值进行 double 类型数据的处理
typedef Vec<double, 4> Vec4d:double 类型的数组,长度为 4,它常用于表示图像的彩色四通道,分别是 A(透明度)、R(红色)、G(绿色)、B(蓝色),并且对于这四个通道的像素值进行 double 类型数据的处理。
需要注意的是:一般 OPENCV 对像素的处理大部分都是用 uchar 类型,其他类型用的很少。 

第二个参数:i,指的是 rows,图像的行数据
第三个参数:j,指的是 cols,图像的列数据

3.代码示例

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace std;
using namespace cv;int main()
{//修改三通道图片像素点值Mat img_mat = imread("frame1.jpg");//读取图片//用at函数遍历整个图片三通道像素点并修改像素点值for (int i = 0; i < img_mat.rows; i++){for (int j = 0; j < img_mat.cols; j++){img_mat.at<Vec3b>(i, j)[0] = img_mat.at<Vec3b>(i, j)[0] - 10;img_mat.at<Vec3b>(i, j)[1] -= 50;img_mat.at<Vec3b>(i, j)[2] -= 10;}        }//保存修改后的图片imwrite("frame2.jpg", img_mat);//修改单通道图片像素点值Mat grayImage;Mat before_Image;cvtColor(img_mat, before_Image, COLOR_RGB2GRAY);cvtColor(img_mat, grayImage, COLOR_RGB2GRAY);//用at函数遍历整个图片单通道像素点并修改像素点值for (int i = 0; i < grayImage.rows; i++){for (int j = 0; j < grayImage.cols; j++){grayImage.at<uchar>(i, j) = 50 - grayImage.at<uchar>(i, j);}}//保存修改后的图片imwrite("frame3.jpg", before_Image);imwrite("frame4.jpg", grayImage);return 0;
}


http://www.hkcw.cn/article/NjlvyxQRFO.shtml

相关文章

梅州村民鸡舍惊现50斤重蟒蛇 警民联手成功捕获

6月1日早上6时30分,正当小朋友们开始庆祝儿童节的时候,五华县公安局丁畲派出所的值班电话突然响起。村民温先生求助称家中鸡舍出现一条大蛇,导致鸡鹅四散奔逃。接到报警后,丁畲派出所的民辅警迅速赶往现场,并联系了专业的捕蛇师傅一同前往。到达现场后,他们发现大蛇蜷缩在…

【笔记】基于 MSYS2(MINGW64)的 Poetry 虚拟环境创建指南

#工作记录 基于 MSYS2&#xff08;MINGW64&#xff09;的 Poetry 虚拟环境创建指南 一、背景说明 在基于 MSYS2&#xff08;MINGW64&#xff09;的环境中&#xff0c;使用 Poetry 创建虚拟环境是一种高效且灵活的方式来管理 Python 项目依赖。本指南将详细介绍如何在 PyChar…

波兰新总统是谁 纳夫罗茨基胜选引发关注

根据波兰国家选举委员会网站当地时间6月2日公布的统计结果,独立候选人卡罗尔纳夫罗茨基赢得了波兰总统选举,他获得了50.89%的选票,与得票率为49.11%的公民联盟候选人、华沙市长拉法尔恰斯科夫斯基展开了激烈竞争。自两周前的首轮投票后,波兰国内的选情持续胶着,反映出这个…

给散装江苏发明省内足球联赛简直天才 比赛第一,友谊第十四!

“友谊第一,比赛第二”这句口号在一场足球比赛中被戏谑地改成了“友谊第一,比赛第十四”,随后又变成了“比赛第一,友谊第十四”。这种幽默的表达方式让江苏省首届城市足球联赛迅速走红。这个被称为“苏超”的足球联赛吸引了大量观众。盐城的一场比赛有22613名观众到场,现场…

奇瑞集团前五月累销突破100万辆 销量创历史新高

奇瑞集团宣布,今年1月至5月累计销售汽车1,026,517辆,同比增长14%,创下历史最快销售速度。其中,新能源汽车销量达到287,798辆,同比增长111.5%;出口量为443,940辆,继续保持中国车企出口第一的位置。5月份,奇瑞集团共销售汽车205,732辆,同比增长9.1%。奇瑞汽车股份有限公…

江苏十三太保把足球踢出圈 热梗频出带火赛事

近日,一场名为“苏超”的足球盛事在江苏火了起来。这场赛事没有假球,只有激烈的竞争,口号是“比赛第一,友谊第十四”。这一系列的热梗不仅带火了足球赛事,也让江苏13个地市的文化旅游产业备受关注。“苏超”全称为“江苏省城市足球联赛”,由江苏省体育局与各设区市政府联…

【人工智能】deepseek七篇论文阅读笔记大纲

七篇文章看了整整五天&#xff0c;加上整理笔记和问ds优化&#xff0c;大致的框架是有了。具体的公式细节比较多&#xff0c;截图也比较麻烦&#xff0c;就不列入大纲去做笔记了。 DeepSeek-LLM&#xff1a;一切的起点&#xff0c;所以探索的东西比较多&#xff0c;包括&#x…

黄金大涨 国际金价显著走强

国际金价因外围消息刺激大幅走强,港股黄金股也受到提振。潼关黄金上涨12.50%,中国黄金国际上涨2.41%,山东黄金上涨2.04%,赤峰黄金上涨1.62%。美国总统特朗普宣布,从6月4日起将进口钢铁和铝关税从25%提高至50%,声称此举旨在保护美国产业免受不公平竞争。他还表示,包括特斯…

气象部门回应西藏现精灵闪电 罕见现象揭秘

5月31日至6月1日,中国摄影师在西藏山南拍到红色精灵闪电。精灵闪电形成于大气中间层,是雷击产生电磁波的结果。据中国天气科普,它在空中存在几十分之一秒,如鬼魅一般难以捉摸。责任编辑:zhangxiaohua

夫妻端午冒雨攀爬野长城 忽视安全酿事故

雨淅淅沥沥下个不停,但这并没有阻止一对夫妻爬山的脚步。他们在享受雨中游玩的快乐时,也忽视了自身安全。5月31日端午节,在阴雨天气中,这对中年夫妻前往京郊一处野长城游玩。爬山过程中,妻子脚滑不慎摔伤,无法下山。消防员接警后立即赶赴现场。当天,山路泥泞湿滑,消防员…

传统文化引领“新国潮” 激活经济新动力

传统文化引领“新国潮”旅途之中,走进博物馆打卡“国宝”必不可少;走进乡村,非遗工坊里游客们仔细挑选心仪的手工艺品;打开购物软件,马面裙、国货彩妆是年轻人的“心头好”。不知不觉中,传统文化已在人们生活中繁盛存在。国潮是“国”与“潮”的融合体——“国”指的是中…

关于MySQL的索引

一、索引 1、索引概述 1.1、介绍 索引&#xff08; index &#xff09;是帮助 MySQL 高效获取数据的数据结构 ( 有序 ) 。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&…

52岁局长涉性侵女子 职务信息被撤 案件引发广泛关注

今年4月,湖南省机场管理集团党委书记、董事长,湖南省机场管理局局长邱继兴,因涉嫌性侵一女子被警方刑拘一事引发广泛关注。6月2日,大皖新闻记者注意到,该集团已迎来新任党委书记、董事长,官网已撤下邱继兴职务信息,集团官方微信公众号中大量关于他的内容也已消失。邱继兴…

马斯克评论乌对俄无人机特种作战 无人机主宰未来战场

马斯克评论“乌对俄发动大规模无人机特种作战”时称,无人机正在成为现代战争的关键工具。他表示,无人机才是未来战场的主宰,而不是有人驾驶飞机。2025年6月1日,乌克兰国家安全局在社交媒体上宣布,当天对俄罗斯实施了特种作战行动,袭击了俄军的战略轰炸机。乌克兰总统泽连…

男子委托网友炒股8个月亏40万 盲目信任酿苦果

山东沂南的王某和李某都是某炒股群网友。王某听说李某具有丰富的炒股经验,便把自己的股票账户和密码交给李某代为炒股,并承诺把盈利的20%分给李某,而李某则表示如果亏了钱会转给王某。从2021年12月至2022年8月期间,王某委托李某炒股累计投入资金60万元,结果亏损40万元,王…

VMware(威睿)公司

本文来源 &#xff1a;腾讯元宝 VMware&#xff08;威睿&#xff09;是一家全球领先的虚拟化和云计算基础架构解决方案提供商&#xff0c;成立于1998年&#xff0c;总部位于美国加利福尼亚州帕洛阿尔托。以下是其关键信息&#xff1a; 1. ​​公司概况​​ ​​成立时间​​&…

西安一男子谎报火警被拘留 醉酒报复引发关注

5月22日凌晨1时57分,西安消防接到报警称一火锅店发生火灾。接警后,西安市消防救援支队西华门消防站立即出动3车15人赶赴现场处置。出警途中,消防员多次联系报警人核实情况,但报警人只提供了店主的电话号码,拒绝提供店铺的具体位置和火灾详情等关键信息。消防员抵达现场后,…

利雅得胜利调整合同以求C罗留下 提交引援计划吸引续约

北京时间6月2日,意大利知名转会专家罗马诺透露,利雅得胜利正计划提交引援方案以吸引C罗续约。俱乐部准备向C罗展示他们的转会规划,希望能借此与他达成新的续约协议。为了获得C罗的续约批准,利雅得胜利正在积极筹备一系列改变,希望他能签署新合同继续留在球队。夏季转会窗口…

武汉入境游同比增长45% 端午旅游热度攀升

端午假期结束,携程发布了2025年端午旅游报告。报告显示,在五一和暑假之间的端午小长假期间,国内多地酒店价格较五一有所下降,民俗体验、周边短途游和避暑游成为主要增长点。热门景区前十中近一半为水上乐园类景区,龙舟赛作为“水”上非遗活动吸引了大量游客。湖北入境游订…

Ai视频翻译神器来袭!pyVideoTrans一键搞定字幕与配音,免费开源

1.前言 各位小伙伴们&#xff0c;大家好呀&#xff01;欢迎关注 天夏Ai&#xff0c;全网同名&#xff0c;我们致力于为大家挖掘和分享各种 精品实用的人工智能&#xff08;Ai&#xff09;资源&#xff0c;包括但不限于**&#xff1a;Ai黑科技工具软件、Ai副业创业项目、Ai智能硬…