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







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;
}



访问图像中像素三种方法之,只需要将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;  //红是通道
			// -------------------------【处理结束】----------------------------
		}  // 行处理结束     
	}  
}  


你可能感兴趣的:([Learning OpenCV入门3] OpenCV数据结构及core组件)