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

RGB图像,矩阵的列会包含多个子列

因为内存足够大,可以实现连续存储,因此,图像中的各行就能一行一行地连接起来,形成一个长行。连续存储,有助于提高图像扫面速度,可以使用isContinuous()来判断矩阵是否是连续存储。
颜色空间缩减
对于三通道图像,一个像素对应的颜色有一千六百多万种,用如此多的颜色可能会影响算法性能。颜色空间缩减即用颜色中具有代表性的一部分表示相近颜色,做法是:将现有颜色空间值除以某个输入值,以获得较少的颜色数。对每个像素进行乘除操作也需要浪费一定的时间(加,减,赋值等代价较低),对于较大的图像,可以预先计算所有可能的值,建立 look up table,
int divideWidth = ;
uchar table[];
for (int i = ; i < ; ++i)
table[i] = divideWidth * (i/divideWidth);
然后遍历图像矩阵的每个像素,对像素应用公式:
p[j] = table[p[j]];
OpenCV官方提供了函数进行图像元素查找、扫描与操作图像
void cv::LUT ( InputArray src,
InputArray lut,
OutputArray dst
)
进行look-up table转换操作,输出矩阵将被赋值为
dst(I)<-lut(src(I)+d)
其中,当src为CV_8U时,d=0,src为CV_8S时,d=128(用于把look up table输入转换到0~255)
- src:矩阵输入,矩阵元素为8-bit色彩值。
- lut:256个色彩值的look-up table,如果src为多通道函数,lut可为单通道(src每通道的处理方式相同)或与src的通道数相同。
- dst:与输入矩阵大小、通道数相同的输出矩阵src, 类型与lut相同(CV_8U或CV_8S)
用法示例如下,
Mat lookUpTable(, , CV_8U);
uchar* p = lookUpTable.data;
for(int i = ; i < ; ++i)
p[i] = table[i];
for(int i=; i < times; ++i)
LUT(Input,lookUpTable, Output);
计时函数
int64 getTickCount()
返回CPU自某个事件(如启动电脑)以来走过的时钟周期
double getTickFrequency()
返回CPU一秒钟所走过的时钟周期数,这样我们就可以以秒为单位对某运算计时
double time0 = stactic_cast<double>(getTickCount());
time0 = ((double) getTickCount() - time0) / getTickFrequency();
cout << "Runing time: " << time0 << "s" << endl;
访问图像中像素的三类方法
用指针访问像素
利用C中的操作符[]或*,这种方法最快,但比较抽象。
用迭代器操作像素
类似于STL中的用法,只需获取图像矩阵的begin和end,然后迭代从begin直至end。比前一种方法安全,不会越界,但速度慢。
动态地址计算
简单明了,直接用at(y,x)找到像素点,但是速度最慢。
上述三种方法的事例程序如下:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream> // function
void colorReduce(cv::Mat& inputImage, cv::Mat& outputImage, int div); // main
int main( int argc, char** argv )
{
// Load image
cv::Mat srcImage = cv::imread("1.jpg");
imshow("orginal image", srcImage); // alocate space for output image
cv::Mat dstImage;
dstImage.create(srcImage.rows, srcImage.cols, srcImage.type()); // get the starting time
double time0 = static_cast<double>(cv::getTickCount()); // call color space reduction function
colorReduce(srcImage, dstImage, ); // estimate runing time
time0 = ((double)cv::getTickCount() - time0)/cv::getTickFrequency();
std::cout << "Running time for this method: " << time0 << "s." << std::endl; imshow("Lab Space", dstImage);
cv::waitKey(); return ;
} #define USESUBS
#ifdef USEPOINTER
void colorReduce(cv::Mat& inputImage, cv::Mat& outputImage, int div)
{
// set parameters
outputImage = inputImage.clone();
int rowNumber = outputImage.rows;
int colNumber = outputImage.cols*outputImage.channels(); for(int i = ;i < rowNumber;i++)
{
uchar* data = outputImage.ptr<uchar>(i);
// get the address of the ith row
for(int j=; j<colNumber; j++)
{
data[j] = data[j]/div*div + div/;
}
} }
#endif
#ifdef USEITERATOR
void colorReduce(cv::Mat& inputImage, cv::Mat& outputImage, int div)
{
// set parameters
outputImage = inputImage.clone(); // get the iterator
cv::Mat_<cv::Vec3b>::iterator it = outputImage.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend = outputImage.end<cv::Vec3b>(); // save new pixel colors
for(;it != itend; ++it)
{
(*it)[] = (*it)[]/div*div + div/; // B
(*it)[] = (*it)[]/div*div + div/; // G
(*it)[] = (*it)[]/div*div + div/; // R
} }
#endif
#ifdef USESUBS
void colorReduce(cv::Mat& inputImage, cv::Mat& outputImage, int div)
{
// set parameters
outputImage = inputImage.clone();
int rowNumber = outputImage.rows;
int colNumber = outputImage.cols; // save new pixel colors
for(int i=; i<rowNumber; i++)
{
for(int j=; j<colNumber; j++)
{
outputImage.at<cv::Vec3b>(i,j)[] = outputImage.at<cv::Vec3b>(i,j)[]/div*div + div/; // B
outputImage.at<cv::Vec3b>(i,j)[] = outputImage.at<cv::Vec3b>(i,j)[]/div*div + div/; // G
outputImage.at<cv::Vec3b>(i,j)[] = outputImage.at<cv::Vec3b>(i,j)[]/div*div + div/; // R
}
} }
#endif
/*
Outputs:
USEPOINTER
Running time for this method: 0.0162628s.
USEITERATOR
Running time for this method: 0.0362183s.
USESUBS
Running time for this method: 0.0518141s.
*/
访问图像中的像素[OpenCV 笔记16]的更多相关文章
- 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整
今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...
- opencv 3 core组件进阶(1 访问图像中的像素)
访问图像像素的三类方法 ·方法一 指针访问:C操作符[ ]; ·方法二 迭代器iterator; ·方法三 动态地址计算. #include <opencv2/core/core.hpp> ...
- 查找并绘制轮廓[OpenCV 笔记XX]
好久没有更新了,原谅自己放了个假最近又在赶进度,所以...更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号...加油加油! 在二值图像中寻找轮廓 void cv::findCo ...
- 图像显示 imshow()[OpenCV 笔记5]
void imshow(const string& winname InputArray mat); winname 窗口表识名称 mat 需要显示的图像.InputArray类型,声明如下 ...
- 视频处理简单实例 [OpenCV 笔记2]
VideoCapture是OpenCV 2.X中新增的类,提供从摄像机或视频文件捕获视频的C++接口.利用它读入视频的方法一般有两种: // method 1 VideoCapture capture ...
- 【OpenCV】访问图像中每个像素的值
http://blog.csdn.net/xiaowei_cqu/article/details/7557063
- 图像储存容器Mat[OpenCV 笔记11]
IplImage 与 Mat IplImage是OpenCV1中的图像存储结构体,基于C接口创建.在退出之前必须release,否则就会造成内存泄露.在一些只能使用C语言的嵌入式系统中,不得不使用. ...
- 图像载入 imread()[OpenCV 笔记4]
Mat imread( ); filename 载入的图像名: flags 指定加载图像的颜色类型,默认载入三通道彩色图像, 如果取枚举类型 (OpenCV3中暂时失效),则定义如下 enum{ CV ...
- 实例:图像载入、显示、混合与输出[OpenCV 笔记8]
是的是的,忍着尿意努力更新,就是为了更到wuli男神的部分,当然要把男神放在前面镇楼,欢迎下载配图,具体操作见code wuliEddie.jpg logo.png results.jpg LoadS ...
随机推荐
- 【Stage3D学习笔记续】山寨Starling(十二):总结和一些没提到的东西
我们的山寨Starling到这里就告一段落了,不得不说这是一个非常优秀的2D框架,他的设计和架构为后来的许多框架都提供了很好的参考,比如现在正在崛起的Egret,我们的一番解读也只是窥见了Starli ...
- Spider Studio 数据挖掘集成开发环境
(最新版本: 2.7.12.1) 传统的多线程蜘蛛程序虽然采集速度快, 但是明明不需要所有内容, 却胡子眉毛一把抓, 将整个网页都下载下来当作一个文本进行处理. 由于网页内容参差不齐, 所以抓取质量常 ...
- UVA 705 Slash Maze
Slash Maze By filling a rectangle with slashes (/) and backslashes ( ), you can generate nice litt ...
- 【10】令operator=返回一个reference to *this
1.令operator= 返回一个reference to *this,为什么? 这只是一个协议,并无强制性.但是,为了与基本类型的行为保持一致性,强烈建议这么做.设计class 有一个宝典:一旦有疑 ...
- PrintJ的设计模式之旅——1.模式之父
好奇设计模式的源头,做了一番搜索和调查,于是便开启了这个系列“PrintJ的设计模式之旅”. 1.模式之父 GOF(Gang of Four) Erich Gamma.Richard Helm.Ral ...
- Floating-Info---Android
https://github.com/alt236/Floating-Info---Android
- [cocos2dx笔记004] android添加�静态库project
(基于2.2.2版本号) 这步比較麻烦,不像vs2013那样好设置.參考了非常多文章.还是不能解决这个问题.仅仅有慢慢摸索了.在这里贴出来,希望能让大家能少走点弯路. 还是其于前面的文章提到的myli ...
- iOS图片元数据的读写
图片的本身就是各种图像数据的载体,包含着像素.色彩.灰度等各种数据信息,除此之外,还包含着曝光数据.日期.位置.版权等元数据(metadata). 何为图片元数据 元数据包括许多重要的信息,常用的有E ...
- Android下实现GPS定位服务
1.申请Google API Key,参考前面文章 2.实现GPS的功能需要使用模拟器进行经纬度的模拟设置,请参考前一篇文章进行设置 3.创建一个Build Target为Google APIs的项目 ...
- [node.js]RPC(远程过程调用)的实现原理
刚接触到RPC(远程过程调用),就是可以在本地调用远程机子上的程序的方法,看到一个简单的nodejs实现,用来学习RPC的原理很不错:nodejs light_rpc 使用示例: //服务端 ...