[Learning OpenCV入门3] OpenCV数据结构及core组件

来源:互联网 发布:mac去哪放光盘 编辑:程序博客网 时间:2024/06/03 21:36







Vec<>的介绍

*【1】Vec---是一个OpenCv的---向量类模板(向量模板类)----我比较喜欢Vec把称作向量类模板,这是因为“向量类”--首相说明Vec---它是一个类,、*           然后"模板"---说明它是一个---模板类*【2】Vec---向量类模板的类模板原型:*     template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>*【3】我们可以看得出,它其实就是一个“一维的矩阵”,这是因为:* 1--在OpenCv中没有向量(vector)结构,任何时候需要向量,都只需要一个列矩阵(如果需要一个转置或者共轭向量,则需要一个行向量)*2--OpenCv矩阵的概念与我们线性代数课上学习的概念相比,更加抽象,这是因为线性代数中的矩阵,矩阵中的矩阵元素只能存储--数值型数*          据,而OpenCv不是这样的*【4】Vec<int,n>---就是用类型int和将向量模板类做一个实例化,实例化为一个具体的类.其中,第一个参数int--表示Vec中存储的为int类型;第二*     个参数n为一个整型值,表示Vec每个对象中存储n个int值,也就是---n维向量(列向量)

/【1】向量模板类Vec的实例化,并且给相应实例的Vec向量模板类实例---指定新的名字//【1】Vec2b--这是一个具体的--类类型---这个类类型实例话的类对象表示如下所示://【1】Vec2b---表示每个Vec2b对象中,可以存储2个char(字符型)数据typedef Vec<uchar, 2> Vec2b; //【2】Vec3b---表示每一个Vec3b对象中,可以存储3个char(字符型)数据,比如可以用这样的对象,去存储RGB图像中的//一个像素点typedef Vec<uchar, 3> Vec3b;//【3】Vec4b---表示每一个Vec4b对象中,可以存储4个字符型数据,可以用这样的类对象去存储---4通道RGB+Alpha的图//像中的像素点typedef Vec<uchar, 4> Vec4b;





颜色空间转换

#include "stdafx.h"#include<opencv2/opencv.hpp>using namespace cv;using namespace std;int _tmain(int argc, _TCHAR* argv[]){Mat dstImage,srcImage = imread("1.jpg", 188);if (!srcImage.data ){cout << "输入文件不存在" << endl;return -1;}elsecvtColor(srcImage, dstImage, COLOR_BGR2Lab);namedWindow("效果图",WINDOW_AUTOSIZE);imshow("效果图", dstImage);waitKey();return 0;}



访问图像中像素三种方法之,只需要将colorReduce代码进行替换即可以运行

指针访问

#include "stdafx.h"#include<opencv2/opencv.hpp>#include<opencv2/highgui/highgui.hpp>using namespace cv;using namespace std;void colorReduce(Mat& inputImage, Mat& outputImage, int div);void ShowHelpText();int _tmain(int argc, _TCHAR* argv[]){ShowHelpText();Mat srcImage=imread("1.jpg"), dstImage;//初始化两个Mat阵if (!srcImage.data){ cout << "没有读入图片请重新读入" << endl; return -1; }imshow("原始图像", srcImage);//判断是否存在图片并且实施转换dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());double time0 = static_cast<double>(getTickCount());colorReduce(srcImage, dstImage, 32);//执行调用函数并且计算时间time0 = ((double)getTickCount() - time0) / getTickFrequency();cout << "运行程序的总时间为: " << time0 << "秒"<<endl;imshow("通过指针访问像素", dstImage);waitKey();return 0;}void colorReduce(Mat& inputImage, Mat& outputImage, int div){//应该为Mat类型的引用//参数准备outputImage = inputImage.clone();  //拷贝实参到临时变量int rowNumber = outputImage.rows;  //行数int colNumber = outputImage.cols*outputImage.channels();  //列数 x 通道数=每一行元素的个数//双重循环,遍历所有的像素值for (int i = 0; i < rowNumber; i++)  //行循环{uchar* data = outputImage.ptr<uchar>(i);  //获取第i行的首地址for (int j = 0; j < colNumber; j++)   //列循环{// ---------【开始处理每个像素】-------------     data[j] = data[j] / div*div + div / 2;//ptr函数可以获得图像任意行的首地址//ptr为模板函数// ----------【处理结束】---------------------}  //行处理结束}}void ShowHelpText(){cout << "\n\n\t\t\t颜色空间缩减程序题\n";cout << "\n\n\t\t\tOpenCV的当前的使用版本为" << CV_VERSION << endl;cout << "----------------------------华丽的分割线-----------------" << endl;}

采用迭代器操作像素,和STL方法类似,只需获取begin和end,因为为三个通道,所以采用下列三个处理

void colorReduce(Mat& inputImage, Mat& outputImage, int div)  {  //参数准备outputImage = inputImage.clone();  //拷贝实参到临时变量//获取迭代器Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();  //初始位置的迭代器Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();  //终止位置的迭代器//存取彩色图像像素for(;it != itend;++it)  {  // ------------------------【开始处理每个像素】--------------------(*it)[0] = (*it)[0]/div*div + div/2;  (*it)[1] = (*it)[1]/div*div + div/2;  (*it)[2] = (*it)[2]/div*div + div/2;  // ------------------------【处理结束】----------------------------}  }

采用动态地址计算的方法操作像素:调用at成员函数获取地址

void colorReduce(Mat& inputImage, Mat& outputImage, int div)  {  //参数准备outputImage = inputImage.clone();  //拷贝实参到临时变量int rowNumber = outputImage.rows;  //行数int colNumber = outputImage.cols;  //列数//存取彩色图像像素for(int i = 0;i < rowNumber;i++)  {  for(int j = 0;j < colNumber;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;  //红是通道// -------------------------【处理结束】----------------------------}  // 行处理结束     }  }  


0 0