访问像素的三种方法

①指针访问:最快

②迭代器iterator:较慢,非常安全,指针访问可能出现越界问题

③动态地址计算:更慢,通过at()实现。适用于访问具体某个第i行,j列的像素,而不适用遍历像素

Mat在内存中存储形式

  灰度图的存储形式

    

  RGB的存储形式

  

一般情况下,Mat是连续存储的,按行连接。可以通过isContinuous()函数,判断矩阵是否连续存储,若连续返回true。

访问像素的三种方法

1.指针访问

 void VisitImgByPointer(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
int rows = dstImg.rows;
int cols = dstImg.cols * dstImg.channels(); for(int i = ; i < rows; i++)
{
uchar* data = dstImg.ptr<uchar>(i);
for(int j = ; j < cols; j++)
{
data[j] = ; //处理每一个像素
//add code
}
}
}

当Mat按行连续存储时,可以用指针直接访问所有数据。

 void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
int rows = dstImg.rows;
int cols = dstImg.cols;
int channels = dstImg.channels(); if(dstImg.isContinuous())
{
cols *= rows;
rows = ;
//cout << "is continuous " << endl;
} for(int i = ; i < rows; i++)
{
uchar* data = dstImg.ptr<uchar>(i);
for(int j = ; j < cols * channels; j++)
{
data[j] = ; //处理每一个像素
//add code
}
}
//若存储连续,等效于以下代码
//uchar* data = dstImg.data;
//for(int i = 0; i < cols * rows * channels; i++)
// data[i] = 155; //处理每一个像素 }

2.迭代器访问

 void VisitImgByIterator(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
const int channels = dstImg.channels(); switch(channels)
{
case :
{
Mat_<uchar>::iterator it= dstImg.begin<uchar>();
Mat_<uchar>::iterator itend= dstImg.end<uchar>();
for ( ; it!= itend; it++) //处理每一个像素
{
*it = ;
}
break;
}
case :
{
Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>();
Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>();
for ( ; it3!= itend3; it3++) //处理每一个像素
{
(*it3)[]= ;
(*it3)[]= ;
(*it3)[]= ;
}
break;
}
}
}

3.动态地址访问

 void VisitImgByAt(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
int rows = dstImg.rows;
int cols = dstImg.cols;
int channels = dstImg.channels(); switch(channels)
{
case :
{
for(int i = ; i < rows; i++)
for(int j = ; j < cols; j++)
dstImg.at<uchar>(i,j) = ;
break;
}
case :
{
for(int i = ; i < rows; i++)
for(int j = ; j < cols; j++)
{
dstImg.at<Vec3b>(i,j)[] = ;
dstImg.at<Vec3b>(i,j)[] = ;
dstImg.at<Vec3b>(i,j)[] = ;
}
break;
}
}
}

测试代码-总

 #include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std; void VisitImgByPointer(Mat &inputImg, Mat &dstImg);
void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg);
void VisitImgByIterator(Mat &inputImg, Mat &dstImg);
void VisitImgByAt(Mat &inputImg, Mat &dstImg); int main()
{
Mat srcImg = imread("pig.png"), dstImg;
Mat grayImg;
cvtColor(srcImg, grayImg, CV_BGR2GRAY);
//VisitImgByPointer(srcImg,dstImg);
//VisitContinueImgByPointer(grayImg,dstImg); //VisitImgByIterator(srcImg,dstImg);
//VisitImgByIterator(grayImg,dstImg); //VisitImgByAt(srcImg,dstImg);
VisitImgByAt(grayImg,dstImg); //imshow("原始图", srcImg);
//imshow("灰度图", grayImg);
imshow("生成图", dstImg); waitKey();
return ;
} void VisitImgByPointer(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
int rows = dstImg.rows;
int cols = dstImg.cols * dstImg.channels(); for(int i = ; i < rows; i++)
{
uchar* data = dstImg.ptr<uchar>(i);
for(int j = ; j < cols; j++)
{
data[j] = ; //处理每一个像素
//add code
}
}
} void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
int rows = dstImg.rows;
int cols = dstImg.cols;
int channels = dstImg.channels(); if(dstImg.isContinuous())
{
cols *= rows;
rows = ;
//cout << "is continuous " << endl;
} for(int i = ; i < rows; i++)
{
uchar* data = dstImg.ptr<uchar>(i);
for(int j = ; j < cols * channels; j++)
{
data[j] = ; //处理每一个像素
//add code
}
}
//若存储连续,等效于一下代码
//uchar* data = dstImg.data;
//for(int i = 0; i < cols * rows * channels; i++)
// data[i] = 155; //处理每一个像素 } void VisitImgByIterator(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
const int channels = dstImg.channels(); switch(channels)
{
case :
{
Mat_<uchar>::iterator it= dstImg.begin<uchar>();
Mat_<uchar>::iterator itend= dstImg.end<uchar>();
for ( ; it!= itend; it++) //处理每一个像素
{
*it = ;
}
break;
}
case :
{
Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>();
Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>();
for ( ; it3!= itend3; it3++) //处理每一个像素
{
(*it3)[]= ;
(*it3)[]= ;
(*it3)[]= ;
}
break;
}
}
} void VisitImgByAt(Mat &inputImg, Mat &dstImg)
{
dstImg = inputImg.clone();
int rows = dstImg.rows;
int cols = dstImg.cols;
int channels = dstImg.channels(); switch(channels)
{
case :
{
for(int i = ; i < rows; i++)
for(int j = ; j < cols; j++)
dstImg.at<uchar>(i,j) = ;
break;
}
case :
{
for(int i = ; i < rows; i++)
for(int j = ; j < cols; j++)
{
dstImg.at<Vec3b>(i,j)[] = ;
dstImg.at<Vec3b>(i,j)[] = ;
dstImg.at<Vec3b>(i,j)[] = ;
}
break;
}
}
}

opencv之访问图像像素的更多相关文章

  1. opencv 访问图像像素的三种方式

    访问图像中的像素 访问图像像素有三种可行的方法方法一:指针访问指针访问访问的速度最快,Mat类可以通过ptr函数得到图像任意一行的首地址,同时,Mat类的一些属性也可以用到公有属性 rows和cols ...

  2. opencv学习笔记(八)IplImage* 访问图像像素的值

    opencv2.1版本之前使用IplImage*数据结构来表示图像,2.1之后的版本使用图像容器Mat来存储.IplImage结构体如下所示. typedef struct _IplImage { i ...

  3. opencv学习笔记(九)Mat 访问图像像素的值

    对图像的像素进行访问,可以实现空间增强,反色,大部分图像特效系列都是基于像素操作的.图像容器Mat是一个矩阵的形式,一般情况下是二维的.单通道灰度图一般存放的是<uchar>类型,其数据存 ...

  4. opencv学习之路(7)、访问图像像素

    一.动态地址访问 #include <opencv2/opencv.hpp> #include<iostream> using namespace cv; using name ...

  5. 【OpenCV】访问图像中每个像素的值

    http://blog.csdn.net/xiaowei_cqu/article/details/7557063

  6. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  7. opencv 3 core组件进阶(1 访问图像中的像素)

    访问图像像素的三类方法 ·方法一 指针访问:C操作符[ ]; ·方法二 迭代器iterator; ·方法三 动态地址计算. #include <opencv2/core/core.hpp> ...

  8. OpenCV坐标系与操作像素的四种方法

    像素是图像的基本组成单位,熟悉了如何操作像素,就能更好的理解对图像的各种处理变换的实现方式了. 1.at方法 第一种操作像素的方法是使用"at",如一幅3通道的彩色图像image的 ...

  9. 访问图像中的像素[OpenCV 笔记16]

    再更一发好久没更过的OpenCV,不过其实写到这个部分对计算机视觉算法有所了解的应该可以做到用什么查什么了,所以后面可能会更的慢一点吧,既然开了新坑,还是机器学习更有研究价值吧... 图像在内存中的存 ...

随机推荐

  1. 162. Find Peak Element(二分查找 )

      A peak element is an element that is greater than its neighbors. Given an input array where num[i] ...

  2. VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)

    前面几节鸡啄米为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为“计算”按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但是还有个遗留的 ...

  3. Ubuntu16.04安装wireshark

    Wireshark是一个非常强大的抓包工具,适用于各种场合,安装配置也简单.这里仅对在Ubuntu上的安装做介绍. 首先通过apt安装WireShark: $ sudo apt-add-reposit ...

  4. CentOS下 Nginx1.13.5 + PHP7.1.10 + MySQL5.7.19 源码编译安装

    一.安装Nginx ①安装依赖扩展 # yum -y install wget openssl* gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng l ...

  5. 20145303 刘俊谦《网络对抗》逆向及BOF基础实践

    20145303 刘俊谦<网络对抗>逆向及BOF基础实践 1 逆向及Bof基础实践说明 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调 ...

  6. [javaScript]身份证号信息解析

    之前一直在思考是不是该把工作中一些问题写出来(可能是简单的问题),现在的想法是应该写出来这些简单的问题.虽然工作中可能并没有很多特别难的问题让你去解决,因为公司的招人就是根据你的能力来匹配的嘛. 简单 ...

  7. UVa 1210 连续素数之和

    https://vjudge.net/problem/UVA-1210 题意: 输入整数n,有多少种方案可以把n写成若干个连续素数之和? 思路: 先素数打表,然后求个前缀和. #include< ...

  8. python strip()函数 os.popen()

    函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除序列的字符 s.lstrip(rm) 删除s字符串中开头处,位于 rm删除序列的字 ...

  9. python 作用域,命名空间

    def scope_test(): def do_local(): spam = "local spam" def do_nonlocal(): nonlocal spam spa ...

  10. TensorFlow实现FM

    看了网上的一些用tf实现的FM,很多都没有考虑FM实际使用中数据样本稀疏的问题. 我在实现的时候使用 embedding_lookup_sparse来解决这个问题. 对于二阶部分,由于embeddin ...