【从零学习openCV】opecv操作像素
1. 存取像素值
//在一张图像上增加椒盐噪声,image为输入图像。n为噪点个数
void salt(Mat &image, int n)
{
for(int k = 0;k < n;k++)
{
//随机产生白色噪点
int i = qrand()%image.cols;
int j = qrand()%image.rows;
//假设是灰度图每一个像素的存取类型为uchar,即8bit整型数
if(image.channels() == 1){
image.at<uchar>(j,i) = 255;
}
//彩色图像有三个通道,像素存取类型为cv::Vec3b,即由三个uchar组成的向量。这里用下标[i]訪问每一个通道
else{
image.at<Vec3b>(j,i)[0] = 255;
image.at<Vec3b>(j,i)[1] = 255;
image.at<Vec3b>(j,i)[2] = 255;
}
}
}
效果例如以下:
//颜色缩减函数,image为输入图像。div为缩减的倍数
void colorReduce(Mat&image, int div = 64)
{
int nl = image.rows; //图像的行数
//图像每行的像素数
int nc = image.cols * image.channels();
for(int j =0;j<nl;j++)
{
//得到第j行的首地址
uchar* data = image.ptr<uchar>(j);
//遍历每行的像素
for(int i =0;i<nc;i++)
{
data[i] = data[i]/div*div; //将每一个像素值都变为div的倍数,即将颜色数缩减了div倍
}
}
}
效果例如以下:
//颜色缩减函数。image为输入图像,div为缩减的倍数
void colorReduce(Mat&image, int div = 64)
{
int nl = image.rows; //图像的行数
//图像每行的像素数
int nc = image.cols * image.channels(); //假设图像连续
if(image.isContinuous())
{
//reshape函数用于改变矩阵维度
//图像行数为1,列数为原先的行数乘上列数
image.reshape(1,image.cols*image.rows);
} for(int j =0;j<nl;j++)
{
//得到第j行的首地址
uchar* data = image.ptr<uchar>(j);
//遍历每行的像素
for(int i =0;i<nc;i++)
{
data[i] = data[i]/div*div; //将每一个像素值都变为div的倍数,即将颜色数缩减了div倍
}
}
}
当然opencv还有更为底层的指针。在cv::Mat中。图像数据以unsigned char形式保存在一块内存中。
这块内存的首地址能够通过data成员变量得到。data是一个unsigned char型的指针,所以循环能够用下面方式:
//获得图像指针
uchar *data = image.data;
//获得第j行,第i列个像素值,step代表图像的行宽(包含填补像素)
data = image.data + j*image.step + i*image.elemSize();
//颜色缩减函数。image为输入图像。div为缩减的倍数
void colorReduce(Mat&image, int div = 64)
{
//得到初始位置的迭代器
Mat_<Vec3b>::iterator it = image.begin<Vec3b>();
//得到终止位置的迭代器
Mat_<Vec3b>::iterator itend = image.end<Vec3b>();
//遍历全部像素
for(; it != itend; ++it){
(*it)[0] = (*it)[0]/div*div;
(*it)[1] = (*it)[1]/div*div;
(*it)[2] = (*it)[2]/div*div;
}
}
效果与用指针遍历的一样。
//at方法
void colorReduce1(Mat&image, int div = 64)
{
int nl = image.rows; //图像的行数
//图像每行的像素数
int nc = image.cols * image.channels();
for(int j =0;j<nl-2;j++)
{
for(int i =0;i<nc-2;i++)
{
image.at<Vec3b>(j,i)[0] = image.at<Vec3b>(j,i)[0]/div*div;
image.at<Vec3b>(j,i)[1] = image.at<Vec3b>(j,i)[1]/div*div;
image.at<Vec3b>(j,i)[2] = image.at<Vec3b>(j,i)[2]/div*div;
}
}
} //行首指针方法
void colorReduce2(Mat&image, int div = 64)
{
int nl = image.rows; //图像的行数
//图像每行的像素数
int nc = image.cols * image.channels();
for(int j =0;j<nl;j++)
{
//得到第j行的首地址
uchar* data = image.ptr<uchar>(j);
//遍历每行的像素
for(int i =0;i<nc;i++)
{
data[i] = data[i]/div*div; //将每一个像素值都变为div的倍数,即将颜色数缩减了div倍
}
}
} //一维数组
void colorReduce3(Mat&image, int div = 64)
{
int nl = image.rows; //图像的行数
//图像每行的像素数
int nc = image.cols * image.channels(); //假设图像连续
if(image.isContinuous())
{
//reshape函数用于改变矩阵维度
//图像行数为1,列数为原先的行数乘上列数
image.reshape(1,image.cols*image.rows);
} for(int j =0;j<nl;j++)
{
//得到第j行的首地址
uchar* data = image.ptr<uchar>(j);
//遍历每行的像素
for(int i =0;i<nc;i++)
{
data[i] = data[i]/div*div; //将每一个像素值都变为div的倍数,即将颜色数缩减了div倍
}
}
} //迭代器方法
void colorReduce4(Mat&image, int div = 64)
{
//得到初始位置的迭代器
Mat_<Vec3b>::iterator it = image.begin<Vec3b>();
//得到终止位置的迭代器
Mat_<Vec3b>::iterator itend = image.end<Vec3b>();
//遍历全部像素
for(; it != itend; ++it){
(*it)[0] = (*it)[0]/div*div;
(*it)[1] = (*it)[1]/div*div;
(*it)[2] = (*it)[2]/div*div;
}
} //測试4种像素遍历方式执行时间
void calrunTime(int v,Mat&image)
{
double duration;
duration = static_cast<double>(getTickCount());
for(int i = 0;i<10;i++) //执行十次取平均值
{
switch(v)
{
case 1:
colorReduce1(image);
break;
case 2:
colorReduce2(image);
break;
case 3:
colorReduce3(image);
break;
case 4:
colorReduce4(image);
break;
default:
break;
}
}
duration = static_cast<double>(getTickCount()) - duration;
duration /= getTickFrequency()/100; //执行时间,以ms为单位
qDebug()<<"duration"<<v<<":"<<duration<<"ms";
}
【从零学习openCV】opecv操作像素的更多相关文章
- 【从零学习openCV】IOS7下的人脸检測
前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...
- 【从零学习openCV】IOS7根据人脸检测
前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app.总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...
- 【从零学习openCV】IOS7人脸识别实战
前言 接着上篇<IOS7下的人脸检測>,我们顺藤摸瓜的学习怎样在IOS7下用openCV的进行人脸识别,实际上非常easy,因为人脸检測部分已经完毕,剩下的无非调用openCV的方法对採集 ...
- 【从零学习openCV】IOS7下的openCV开发起步(Xcode5.1.1&openCV2.49)
前言: 开发IOS7已经有一月的时间了.近期在准备推研的事,有点想往CV方向发展.于是開始自学openCV. 关注CSDN已经非常久了.也从非常多博主那学到了非常多知识,于是我也从这周开启自己的blo ...
- 图像混合学习。运用加权函数,学习opencv基础操作
{ cout<< } { cout<< } ,,logoImage.c ...
- 学习Opencv 2.4.9(二) ---操作像素
作者:咕唧咕唧liukun321 来自:http://blog.csdn.net/liukun321 本质上说一张图像就是由数值组成的矩阵.Opencv 2.x由 cv::Mat 这个数据结构来表示一 ...
- OpenCV学习C++接口 Mat像素遍历详解
OpenCV学习C++接口 Mat像素遍历详解
- OpenCV坐标系与操作像素的四种方法
像素是图像的基本组成单位,熟悉了如何操作像素,就能更好的理解对图像的各种处理变换的实现方式了. 1.at方法 第一种操作像素的方法是使用"at",如一幅3通道的彩色图像image的 ...
- 【学习opencv第六篇】图像的反转操作
考试终于完了,现在终于有时间可以继续学习这个了.写这篇博客主要是因为以前一直搞不清楚图像数据到底是怎么存储的,以及这个step到底是什么,后来查了一下才知道原来step就是数据行的长度.. #incl ...
随机推荐
- linux chmod权限
Linux chmod 命令 chmod用于改变文件或目录的访问权限.用户用它控制文件或目录的访问权限.该命令有两种用法.一种是包含 字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1 ...
- Mac中使用svn进行项目管理
Mac中使用svn进行项目管理,借鉴了http://blog.csdn.net/q199109106q/article/details/8655204 下面方案多人亲測可用 转载请注明出处:http: ...
- Activity的创建和使用
Activity: 1:创建一个类继承Activity或者它的子类 public class MainActivity extends Activity { @Override protected v ...
- 闲扯 Javascript 00
引言 Javascript 的作用在此就不阐述了,相信你已经知道它的用途!那我说点什么呢? 不如就和大家先扯一把,后面的工作 随后后展开吧! 首先声明:我个人对Javascript 认识,我只知道它 ...
- Qt 富文本处理(QTextDocument和QTextBlock和QTextFrame和QTextTable和QTextList和QTextDocument)
最近使用 Qt 做一个离线博客编辑器,因而用到了 Qt 的富文本处理.参考 Qt 的文档,记录下 Qt 的富文本处理的相关技术.文档地址是 http://doc.qt.nokia.com/4.7/ri ...
- C# MVC 自学笔记—5 添加模型
==============================翻译============================== 在本节中,您将添加一些类来管理数据库中的电影.这些类将 ASP.NET M ...
- HDU 4720Naive and Silly Muggles热身赛2 1005题(分锐角钝角三角形讨论)
Naive and Silly Muggles Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- PHP - 接口 - 多接口
/* * 使用多接口 */ //定义接口1 interface IPerosn_one{ public function eat(); } //定义接口2 interface IPerson_two{ ...
- CSS属性总结——思路很清晰
CSS 属性总结 CSS的属性是用来改变文档元素的状态的,其中主要改变两方面的东西,即位置.样式,现在我们就将CSS的属性分为定位和样式两方面来总结,知识结构图如下: 用来定位的属性: 在同一 ...
- ADO.NET 对象 结构图