opencv学习笔记(二)
2015-06-26 16:21
435 查看
首先推荐一本书:《OpenCV 2 Computer Vision Application Programming Cookbook》网上可以下载到这本书的英文版,貌似没有翻译的。这本书的特点是里面的程序不是那种为了演示函数功能而写的面向过程的小程序,而是用面向对象的思路写的大程序,不过他是一步一步教你写出来的,也不要有太大压力。
任何图像处理算法,都是从操作每个像素开始的。即使你不会使用OpenCV提供的各种图像处理函数,只要你了解图像处理算法的基本原理,也可以写出具有相同功能的程序。在OpenCV中,提供了种访问每个像素的方法:使用at方法、使用迭代器、使用指针。
这三种方法在访问速度上略有差异。debug模式下,这种差异非常明显,不过在release模式下,这种差异就不太明显了。我们通过一组程序来说明这几种方法,程序的目的是减少图像中颜色的数量,比如原来的图像是是256中颜色,我希望将它变成64种颜色,那我只需要将原来的颜色除以4(整除)以后再乘以4就可以了。
先看主程序:
[cpp] view
plaincopy
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
int main()
{
Mat image = imread("D:/picture/img.tif");
imshow("源图像",image);
Mat result;//用来保存结果
result.create(image.rows,image.cols,image.type());//它的大小、类型与原图片相匹配
double duration;
duration = static_cast<double>(cv::getTickCount());
colorReduce(image,result,64);
duration = static_cast<double>(cv::getTickCount())-duration;
duration /= cv::getTickFrequency(); // the elapsed time in m
cout<<"time is"<<duration<<endl;
imshow("显示结果",result);
waitKey(0);
}
主程序中调用colorReduce函数来完成减少颜色的工作:
下面是使用at方法的colorReduce函数,这种方法简洁明了,符合大家对像素的直观认识。运行时间为0.334131。
[cpp] view
plaincopy
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
int rows = outputImage.rows;
int cols = outputImage.cols;
for(int i = 0;i < rows;i++)
{
for(int j = 0;j < cols;j++)
{
outputImage.at<Vec3b>(i,j)[0] = outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;
outputImage.at<Vec3b>(i,j)[1] = outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;
outputImage.at<Vec3b>(i,j)[2] = outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;
}
}
}
下面是使用迭代器的colorReduce函数,这种方法与STL库的用法类似。运行时间为0.375629
[cpp] view
plaincopy
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
//模板必须指明数据类型
Mat_<Vec3b>::iterator it = inputImage.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = inputImage.end<Vec3b>();
//也可以通过指明cimage类型的方法不写begin和end的类型
Mat_<Vec3b> cimage= outputImage;
Mat_<Vec3b>::iterator itout = cimage.begin();
Mat_<Vec3b>::iterator itoutend = cimage.end();
for(;it != itend;it++,itout++)
{
(*itout)[0] = (*it)[0]/div*div + div/2;
(*itout)[1] = (*it)[1]/div*div + div/2;
(*itout)[2] = (*it)[2]/div*div + div/2;
}
}
最后是使用指针的方法,这种方法最快,但是略有点抽象。运行时间为0.00705378!
[cpp] view
plaincopy
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
int rows = outputImage.rows;
int cols = outputImage.cols*outputImage.channels();
for(int i = 0;i < rows;i++)
{
uchar* data = inputImage.ptr<uchar>(i);
uchar* dataout = outputImage.ptr<uchar>(i);
for(int j = 0;j < cols;j++)
{
dataout[j] = dataout[j]/div*div + div/2;
}
}
}
[cpp] view
plaincopy
顺便说一句,OpenCV中的彩色图像不是以RGB的顺序存放的,而是BGR,所以程序中的outputImage.at<Vec3b>(i,j)[0]代表的是该点的B分量。同理还有(*it)[0]。
任何图像处理算法,都是从操作每个像素开始的。即使你不会使用OpenCV提供的各种图像处理函数,只要你了解图像处理算法的基本原理,也可以写出具有相同功能的程序。在OpenCV中,提供了种访问每个像素的方法:使用at方法、使用迭代器、使用指针。
这三种方法在访问速度上略有差异。debug模式下,这种差异非常明显,不过在release模式下,这种差异就不太明显了。我们通过一组程序来说明这几种方法,程序的目的是减少图像中颜色的数量,比如原来的图像是是256中颜色,我希望将它变成64种颜色,那我只需要将原来的颜色除以4(整除)以后再乘以4就可以了。
先看主程序:
[cpp] view
plaincopy
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
int main()
{
Mat image = imread("D:/picture/img.tif");
imshow("源图像",image);
Mat result;//用来保存结果
result.create(image.rows,image.cols,image.type());//它的大小、类型与原图片相匹配
double duration;
duration = static_cast<double>(cv::getTickCount());
colorReduce(image,result,64);
duration = static_cast<double>(cv::getTickCount())-duration;
duration /= cv::getTickFrequency(); // the elapsed time in m
cout<<"time is"<<duration<<endl;
imshow("显示结果",result);
waitKey(0);
}
主程序中调用colorReduce函数来完成减少颜色的工作:
下面是使用at方法的colorReduce函数,这种方法简洁明了,符合大家对像素的直观认识。运行时间为0.334131。
[cpp] view
plaincopy
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
int rows = outputImage.rows;
int cols = outputImage.cols;
for(int i = 0;i < rows;i++)
{
for(int j = 0;j < cols;j++)
{
outputImage.at<Vec3b>(i,j)[0] = outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;
outputImage.at<Vec3b>(i,j)[1] = outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;
outputImage.at<Vec3b>(i,j)[2] = outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;
}
}
}
下面是使用迭代器的colorReduce函数,这种方法与STL库的用法类似。运行时间为0.375629
[cpp] view
plaincopy
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
//模板必须指明数据类型
Mat_<Vec3b>::iterator it = inputImage.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = inputImage.end<Vec3b>();
//也可以通过指明cimage类型的方法不写begin和end的类型
Mat_<Vec3b> cimage= outputImage;
Mat_<Vec3b>::iterator itout = cimage.begin();
Mat_<Vec3b>::iterator itoutend = cimage.end();
for(;it != itend;it++,itout++)
{
(*itout)[0] = (*it)[0]/div*div + div/2;
(*itout)[1] = (*it)[1]/div*div + div/2;
(*itout)[2] = (*it)[2]/div*div + div/2;
}
}
最后是使用指针的方法,这种方法最快,但是略有点抽象。运行时间为0.00705378!
[cpp] view
plaincopy
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
outputImage = inputImage.clone();
int rows = outputImage.rows;
int cols = outputImage.cols*outputImage.channels();
for(int i = 0;i < rows;i++)
{
uchar* data = inputImage.ptr<uchar>(i);
uchar* dataout = outputImage.ptr<uchar>(i);
for(int j = 0;j < cols;j++)
{
dataout[j] = dataout[j]/div*div + div/2;
}
}
}
[cpp] view
plaincopy
顺便说一句,OpenCV中的彩色图像不是以RGB的顺序存放的,而是BGR,所以程序中的outputImage.at<Vec3b>(i,j)[0]代表的是该点的B分量。同理还有(*it)[0]。
相关文章推荐
- Linux学习笔记(二)——主机规划及磁盘分区
- hadoop学习
- Linux中cp文件或目录时如何显示进度?
- Linux下安装与使用本地的perl模块
- nginx rewrite
- 实战Tomcat配置SSL,使用openssl制作证书
- Impersonation option 设置
- Django1.4 python2.7 apache mod_python 安装与部署实例
- opencl+opencv实现sobel算法
- Linux sed 批量替换多个文件中的字符串
- 11个超棒的iOS开发学习网站
- poj 1456 Supermarket(并查集维护区间)
- 获取.propertys文件获取文件内容
- 在 linux 下使用 CMake 构建应用程序
- memcopy和memmove的区别
- opencv学习笔记(一)
- 大型网站技术架构
- mac下安装 xampp 无法启动apache
- linux进程间通讯总结
- iTOP-4412开发板低功耗高性能的开源硬件平台——上手评测