opencv之访问图像像素
访问像素的三种方法
①指针访问:最快
②迭代器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之访问图像像素的更多相关文章
- opencv 访问图像像素的三种方式
访问图像中的像素 访问图像像素有三种可行的方法方法一:指针访问指针访问访问的速度最快,Mat类可以通过ptr函数得到图像任意一行的首地址,同时,Mat类的一些属性也可以用到公有属性 rows和cols ...
- opencv学习笔记(八)IplImage* 访问图像像素的值
opencv2.1版本之前使用IplImage*数据结构来表示图像,2.1之后的版本使用图像容器Mat来存储.IplImage结构体如下所示. typedef struct _IplImage { i ...
- opencv学习笔记(九)Mat 访问图像像素的值
对图像的像素进行访问,可以实现空间增强,反色,大部分图像特效系列都是基于像素操作的.图像容器Mat是一个矩阵的形式,一般情况下是二维的.单通道灰度图一般存放的是<uchar>类型,其数据存 ...
- opencv学习之路(7)、访问图像像素
一.动态地址访问 #include <opencv2/opencv.hpp> #include<iostream> using namespace cv; using name ...
- 【OpenCV】访问图像中每个像素的值
http://blog.csdn.net/xiaowei_cqu/article/details/7557063
- 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整
今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...
- opencv 3 core组件进阶(1 访问图像中的像素)
访问图像像素的三类方法 ·方法一 指针访问:C操作符[ ]; ·方法二 迭代器iterator; ·方法三 动态地址计算. #include <opencv2/core/core.hpp> ...
- OpenCV坐标系与操作像素的四种方法
像素是图像的基本组成单位,熟悉了如何操作像素,就能更好的理解对图像的各种处理变换的实现方式了. 1.at方法 第一种操作像素的方法是使用"at",如一幅3通道的彩色图像image的 ...
- 访问图像中的像素[OpenCV 笔记16]
再更一发好久没更过的OpenCV,不过其实写到这个部分对计算机视觉算法有所了解的应该可以做到用什么查什么了,所以后面可能会更的慢一点吧,既然开了新坑,还是机器学习更有研究价值吧... 图像在内存中的存 ...
随机推荐
- stringbuffer 和 stringbuilder区别
stringbuffer 和 stringbuilder速度 小于 线程安全 线程非安全 单线程操作大量数据用stringbui ...
- Bootstrap按钮组学习
简介 通过按钮组容器把一组按钮放在同一行里.通过与按钮插件联合使用,可以设置为单选框或多选框的样式和行为. 按钮组中的工具提示和弹出框需要特别的设置 当为 .btn-group 中的元素应用工具提示或 ...
- (15)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第三部分(完)
引言 程序截图: 在第二部分教程中,Ray教大家如何在地图中制作可碰撞的区域,如何使用tile属性,如何制作可以拾取的物品以及如何动态修改地图.如何使用“Heads up display”来显示分数. ...
- 手把手教你学node.js之学习使用外部模块
学习使用外部模块 目标 建立一个 lesson2 项目,在其中编写代码. 当在浏览器中访问 http://localhost:3000/?q=alsotang 时,输出 alsotang 的 md5 ...
- 《大话设计模式》ruby版代码:外观模式
需求: 股民买卖股票 初步代码: # -*- encoding: utf-8 -*- #股票1 class Stock1 def buy puts '股票1买入' end def sell puts ...
- SQL substring()函数
①substring()函数是个截取函数,不同的数据库语法有区别 MySQL: SUBSTR( ), SUBSTRING( ) Oracle: SUBSTR( ) SQL Server: SUBSTR ...
- Horizon代码的层次结构
Horizon中包含多个dashboard,每个dashboard又包含多个panel,每个panel有可以包含多个Tab.
- springcloud15---zuul-fallback
package com.itmuch.cloud; import org.springframework.boot.SpringApplication; import org.springframew ...
- Apache HttpClient4使用教程
基于HttpClient 4.5.2 执行GET请求 CloseableHttpClient httpClient = HttpClients.custom() .build(); Closeable ...
- 20145326 《Java程序设计》课程总结
每周读书笔记链接汇总 20145326第1周学习总结 20145326第2周学习总结 20145326第3周学习总结 20145326第4周学习总结 20145326第5周学习总结 20145326第 ...