opencv中Mat格式的数据访问.at
opencv3中图形存储基本为Mat格式,如果我们想获取像素点的灰度值或者RGB值,可以通过image.at<uchar>(i,j)的方式轻松获取。
Mat类中的at方法对于获取图像矩阵某点的RGB值或者改变某点的值很方便,对于单通道的图像,则可以使用:
image.at<uchar>(i, j)
其中有一个要注意的地方是i对应的是点的y坐标,j对应的是点的x坐标,而不是我们习惯的(x,y)
来获取或改变该点的值,而RGB通道的则可以使用:
image.at<Vec3b>(i, j)[]
image.at<Vec3b>(i, j)[]
image.at<Vec3b>(i, j)[]
来分别获取B、G、R三个通道的对应的值。下边的代码实现对图像加椒盐噪声:
// created by ning zhang 2018/4/25
// The function of this program is to add noise to the image
#include <opencv2/opencv.hpp>
#include <iostream> using namespace std;
using namespace cv; void salt_noise( Mat image, int time ); int main ( int argc, char** argv )
{
Mat image = imread("../lena.jpg",0); //input the gray image
if ( image.empty() )
{
cout << "Load image error" << endl;
return -1;
}
salt_noise(image, 3000);
namedWindow("image", 1);
imshow("image", image); waitKey();
return 0;
} void salt_noise ( Mat image, int time )
{
for (int k = 0; k < time; k++ ) //time is the number of noise you add
{
int i = rand() % image.rows;
int j = rand() % image.cols;
if (image.channels() == 1) //single channel
{
image.at<uchar>(i,j) = rand() % 255;
}
else if (image.channels() == 3) //RGB channel
{
image.at<Vec3b>(i, j)[0] = rand() % 255;
image.at<Vec3b>(i, j)[1] = rand() % 255;
image.at<Vec3b>(i, j)[2] = rand() % 255;
}
}
}
效果图如下所示,可以为图片增加噪点

代码地址:https://github.com/feifanrensheng/salt_noise
还有比较省时的方法使用Mat的模板子类Mat_<T>,,对于单通道的具体使用:
Mat_<uchar> img = image;
img(i, j) = rand() % ;
对于RGB通道的使用:
Mat_<Vec3b> img = image;
img(i, j)[] = rand() % ;
img(i, j)[] = rand() % ;
mg(i, j)[] = rand() % ;
还可以用指针的方法遍历每一像素:(耗时较小)
void colorReduce(Mat image, int div = )
{
int nrow = image.rows;
int ncol = image.cols*image.channels();
for (int i = ; i < nrow; i++)
{
uchar* data = image.ptr<uchar>(i);//get the address of row i;
for (int j = ; j < ncol; j++)
{
data[i] = (data[i] / div)*div ;
}
}
}
我们要尤其注意OpenCV坐标系与row&col的关系 (Mat::at(x,y)和Mat::at(Point(x, y))的区别)
直接给出对应关系吧
row == heigh == Point.y col == width == Point.x Mat::at(Point(x, y)) == Mat::at(y,x)
因为还有点的坐标,所以建议在访问时都用Mat::at(Point(x, y))这种形式吧,免去了点坐标和行列的转换
详细说明:
坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。该坐标体系在诸如结构体Mat,Rect,Point中都是适用的。(虽然网上有学着说OpenCV中有些数据结构的坐标原点是在图片的左下角,但是我暂时还没碰到过)。
在使用image.at(x1, x2)来访问图像中点的值的时候,x1并不是图片中对应点的x轴坐标,而是图片中对应点的y坐标。因此其访问的结果其实是访问image图像中的Point(x2, x1)点,即与image.at(Point(x2, x1))效果相同。
如果所画图像是多通道的,比如说image图像的通道数时n,则使用Mat::at(x, y)时,其x的范围依旧是0到image的height,而y的取值范围则是0到image的width乘以n,因为这个时候是有n个通道,所以每个像素需要占有n列。但是如果在同样的情况下,使用Mat::at(point)来访问的话,则这时候可以不用考虑通道的个数,因为你要赋值给获取Mat::at(point)的值时,都不是一个数字,而是一个对应的n维向量。
参考:https://blog.csdn.net/xiao_lxl/article/details/69568963
https://blog.csdn.net/wangxuwen2/article/details/52443978
https://blog.csdn.net/u013203733/article/details/73742247
https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=mat.at()&rsv_pq=ca3aed07000036c0&rsv_t=24317bhASyuKaxOgeSdlua%2FIqMWm7sRcP%2F1SQu5FhmelisfC2AWVqZaIMPk&rqlang=cn&rsv_enter=1&rsv_sug3=10&rsv_sug1=8&rsv_sug7=100&rsv_sug2=0&inputT=6442&rsv_sug4=7626
opencv中Mat格式的数据访问.at的更多相关文章
- Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 2016年09月02日 00:00:36 -牧野- 阅读数:59593 标签: Opencv矩阵相乘点乘dotmul 更多 个人分类: O ...
- opencv中mat类介绍
The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It ...
- OpenCV中Mat操作clone() 与copyto()的区别
OpenCV中Mat操作clone() 与copyto()的区别 // Mat is basically a class with two data parts: the matrix header ...
- OpenCV中Mat的属性
OpenCV中Mat的属性 最近在做一OpenCV的图像轮廓检验,但当用到霍夫变换时才发现对Mat的属性了解不足.Mat在OpenCV中的地位是及其重要的,因此有必要做一个总结. 大体上来说,Mat是 ...
- OpenCV中Mat的基本用法:创建、复制
OpenCV中Mat的基本用法:创建.复制 一.Mat类的创建: 1.方法一: 通过读入一张图像,直接将其转换成Mat对象. Mat image = imread("test.jpg&quo ...
- 【转】在Spring中基于JDBC进行数据访问时怎么控制超时
http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...
- OpenCV中Mat的列向量归一化
OpenCV中Mat的列向量归一化 http://blog.csdn.net/shaoxiaohu1/article/details/8287528 OpenCV中Mat的列向量归一化 标签: Ope ...
- C#操作数据表中XML格式的数据
以前还真没有见过数据表中存储XML格式的数据,刚开始听说的时候,还以为是数据表中有XML的字段类型, 再了解,其实也就是字符串类型的,只不过字符串的格式是XML格式的.确实孤陋寡闻!汗... (可添加 ...
- opencv中Mat类型数据操作与遍历
Mat作为opencv中一种数据类型常常用来存储图像,相对与以前的IplImgae类型来说,Mat类型省去了人工的对内存的分配与释放,转而自动分配释放.Mat Class主要包括两部个数据部分:一个是 ...
随机推荐
- ftp传输出现问题
将文件打包压缩之后,从ftp服务器下载到本地,进行解压,出现下面的问题. 原来是传输文件的时候是默认按照netascii的格式进行传输的,没有按照二进制文件的形式传输. 再传输之前,使用bin指定传输 ...
- Spring 4 官方文档学习(十)数据访问之DAO支持
1.介绍 Spring 中 Data Access Object (DAO)支持 的目标是以一种一致的方式更简单的使用JDBC.Hibernate.JPA或JDO等数据访问技术.可以在前面说的几种数据 ...
- 直接拿来用!最火的Android开源项目(转)
摘要:对于开发者而言,了解当下比较流行的开源项目很是必要.利用这些项目,有时能够让你达到事半功倍的效果.为此,CSDN特整理了GitHub上最受欢迎的Android及iOS开源项目,本文详细介绍了20 ...
- erlang的Socket的积压的消息的数量
转自:http://blog.csdn.net/pkutao/article/details/8572216 {ok, Listen} = gen_tcp:listen(?defPort, [bina ...
- R语言低级绘图函数-title
title 函数用来在一张图表上添加标题 基本用法: main 表示主标题,通常位于图像的上方, sub 表示副标题,位于图像的下方, xlab 表示x轴的标签,ylab 表示y轴的标签 par(om ...
- Centos下查看和修改网卡Mac地址
linux/Centos下查看网卡Mac地址,输入命令: #ifconfig -a eth0 Link encap:Ethernet HWaddr 00:e4:56:2E:D8:20 00:e4:56 ...
- jQuery-处理css样式
1.css方法 获取匹配元素集合中的第一个元素的样式属性的值 或 设置每个匹配元素的一个或多个CSS属性 1)获取并设置单个css值 jQuery对象.css('css属性'); jQuery对象.c ...
- ASP.NET MVC传递参数(model), 如何保持TempData的持久性
一看到此标题,相信你也会.因为路由是可以从URL地址栏传过去的. 但是Insus.NET不想在地址栏传递,还是一个条件是jQuery的Ajax进行POST的.Insus.NET不清楚别人是怎样处理的, ...
- ASP.NET自带对象JSON字符串与实体类的转换
关于JSON的更多介绍,请各位自行google了解!如果要我写的话,我也是去Google后copy!嘿嘿,一直以来很想学习json,大量的找资料和写demo,总算有点了解! 切入正题! 还是先封装一个 ...
- 详解MathType快捷键使用技巧
巧妙使用MathType数学公式编辑器可加快数学符号的录入速度和效率,这将节约大量的时间成本,本教程将详解MathType快捷键使用的诸多技巧. 在MathType界面,将鼠标轻轻的放在某个符号上,在 ...