访问像素的三种方法

①指针访问:最快

②迭代器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. 解决maven的依赖总是无法下载完成

    有时候在eclipse里面刚刚导进一个maven项目,但是总是无法完整下载pom文件里面的依赖 主要有两个原因: 1,需要下载的依赖(jar包)需要开发人员给权限(远程仓库的下载权限),这个可以找开发 ...

  2. Django的FBV和CB

    Django的FBV和CBV FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV C ...

  3. C语言中exit函数的使用

      exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一 ...

  4. Python笔记 #15# Pandas: Missing Data

    10 Minutes to pandas import pandas as pd import numpy as np import matplotlib.pyplot as plt dates = ...

  5. Ubuntu 16.04 (官方命令行)安装MongoDB 3.6.2(社区版)

    概述 使用本教程从 .deb 包在LTS Ubuntu Linux系统上安装MongoDB Community Edition. 虽然Ubuntu包含自己的MongoDB包,但官方的MongoDB社区 ...

  6. ESXi主机遗忘密码重置密码

    ESXi版本:6.0.0 VMware-VMvisor-Installer-6.0.0.update02-3620759.x86_64-Dell_Customized-A00.iso 使用和服务器系统 ...

  7. HDU 3416 Marriage Match IV(ISAP+最短路)题解

    题意:从A走到B,有最短路,问这样不重复的最短路有几条 思路:先来讲选有效边,我们从start和end各跑一次最短路,得到dis1和dis2数组,如果dis1[u] + dis2[v] + cost[ ...

  8. codeforces 11 B.Jumping Jack 想法题

    B. Jumping Jack Jack is working on his jumping skills recently. Currently he's located at point zero ...

  9. postman 安装桌面版

    https://github.com/postmanlabs/postman-app-support

  10. oracle10g连接自动断开,报ORA-03135错误

    问题描述: oracle使用过一段时间,连接断开,报ORA-03135错误. 问题挖掘: 用pl/sql和sqlplus连接oracle,也存在该问题,确定该问题与连接方式无关. 查看服务器,发现没有 ...