访问像素的三种方法

①指针访问:最快

②迭代器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. hdu5073 贪心

    这题说的是给了 n个值每个值 然后 他们的品均值 作为中点 然后每个点到中点的均值的平方 和最小值是多少 有 k 个点可以重新 放过位置 , 这样我们 应该 会选 最近的那个 n-k个点 然后 取他们 ...

  2. 三.野指针和free

    在C语言项目中,经常会遇到需要程序员手动分配内存的地方.这样做能够节省大量的内存空间,也让程序更加灵活.只要你有一定的基础,那么肯定用过 malloc 或者 ralloc和free的组合.这个组合使用 ...

  3. bzoj1605 / P2905 [USACO08OPEN]农场危机Crisis on the Farm

    P2905 [USACO08OPEN]农场危机Crisis on the Farm 发现总步数$k<=30$,考虑用$k$瞎搞 设$f[u][i][j]$表示已经吹$u$次哨,全体奶牛向右走$i ...

  4. 在apache中使用.htaccess文件的注意事项

    在apache的配置文件中: <VirtualHost *:80> ServerName tp5.com DocumentRoot d:/wamp/www/tp5.com/public & ...

  5. Java8 Predicate

    code: package com.qhong; import java.util.ArrayList; import java.util.Arrays; import java.util.List; ...

  6. 关于JS和JSON

    讲得不准确! 看网课,JS也算是面向对象的一门语言,不过其是解释性的脚本语言. JSON是把用JS的表示法将数据包装起来进行传递用的. JS语法是松散型的,没有int String这些像JAVA里的类 ...

  7. Android移动软件开发总结

    目录 Android实验参考目录 常用知识点总结 服务绑定bind Service ThreadService使用总结 Service用法总结 Broadcast Receiver用法 Intent使 ...

  8. node scripts/install.js 停顿解决办法

    参考:node-sass 安装卡在 node scripts/install.js 解决办法 在安装hexo的时候,运行: npm install hexo-cli -g 卡死在了 node scri ...

  9. UVa 12034 比赛名次(递推)

    https://vjudge.net/problem/UVA-12034 题意: A.B两人赛马,最终名次有3种可能:并列第一:A第一B第二:B第一A第二.输入n,求n人赛马时最终名次的可能性的个数除 ...

  10. Builder(建造者)

    意图: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 适用性: 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. 当构造过程必须允许被构造的对象有不同 ...