首先推荐一本书:《OpenCV 2 Computer Vision Application Programming Cookbook》网上可以下载到这本书的英文版,貌似没有翻译的。这本书的特点是里面的程序不是那种为了演示函数功能而写的面向过程的小程序,而是用面向对象的思路写的大程序,不过他是一步一步教你写出来的,也不要有太大压力。
任何图像处理算法,都是从操作每个像素开始的。即使你不会使用OpenCV提供的各种图像处理函数,只要你了解图像处理算法的基本原理,也可以写出具有相同功能的程序。在OpenCV中,提供了种访问每个像素的方法:使用at方法、使用迭代器、使用指针。
这三种方法在访问速度上略有差异。debug模式下,这种差异非常明显,不过在release模式下,这种差异就不太明显了。我们通过一组程序来说明这几种方法,程序的目的是减少图像中颜色的数量,比如原来的图像是是256中颜色,我希望将它变成64种颜色,那我只需要将原来的颜色除以4(整除)以后再乘以4就可以了。
先看主程序:
#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。
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
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!
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;
}
}
}
顺便说一句,OpenCV中的彩色图像不是以RGB的顺序存放的,而是BGR,所以程序中的outputImage.at<Vec3b>(i,j)[0]代表的是该点的B分量。同理还有(*it)[0]。
分享到:
相关推荐
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 005】 操作像素》 博文链接: http://blog.csdn.net/davebobo/article/details/52541612 OpenCV版本:2.4.9
OpenCV 3计算机视觉:Python语言实现,代码+pdf文档,适合于计算机视觉研究者
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 007】使用直方图统计像素》 博文链接: http://blog.csdn.net/davebobo/article/details/52554968 OpenCV版本:2.4.9
Opencv学习笔记 辛苦收集希望和大家交流
这个一个很基础的opencv学习笔记,一些常会遇到的问题,在这里做了肤浅的介绍,还有很多问题没有提及,以后会陆续整理,并上传
OpenCV学习笔记入门版,真正的入门级别,自己写的
opencv的学习资料:OpenCV2.1.pdf OpenCV中文手册 learning opencv电子版
OpenCV 3计算机视觉:Python语言实现 (Joe Minichino)
标题学习opencv第一天: 一、图像基本操作: 1.图像读取:cv.imread(“文件位置:D:/python/picture.png” ) 函数功能:从文件路径中读取图片文件并显示出来,可读取的文件类型有JPG、JPEG、PNG、Webp等 函数原型:...
OpenCV学习笔记,(基础概念,归纳总结),相信你所选择的。
OpenCV学习笔记(C++版OpenCV学习笔记,主要包括基础模块和DNN模块)带详细注释源码!!!
OpenCv学习笔记(六):使用opencv画线、矩形、椭圆、多边形线、多边形体等.pdf
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 008】基于形态学运算的图像变换》 博文链接: http://blog.csdn.net/davebobo/article/details/52561463 OpenCV版本:2.4.9
基础学习笔记(注释)之opencv(12):改变图像对比度和亮度.doc
Duanxx的OpenCV学习:视频操作
学习笔记
有关学习opencv与C++过程中的一些学习笔记
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 013】处理视频序列》 博文链接: http://blog.csdn.net/davebobo/article/details/52677657 OpenCV版本:2.4.9
OpenCV算法精解:基于Python与C(优秀教材,值得一看),需要请自行下载