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; } else cvtColor(srcImage, dstImage, COLOR_BGR2Lab); namedWindow("效果图",WINDOW_AUTOSIZE); imshow("效果图", dstImage); waitKey(); return 0; }
指针访问
#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; // ------------------------【处理结束】---------------------------- } }
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; //红是通道 // -------------------------【处理结束】---------------------------- } // 行处理结束 } }