《Open CV3编程入门》学习笔记3

6访问像素的三种方法以及运行时间计算

#include
#include
#include
using namespace std;
using namespace cv;
//函数说明
void colorReduce(Mat& inputImage,Mat&outputImage,int div);

int main()
{
	Mat srcImage=imread("1.jpg");
	imshow("原始图像",srcImage);
	Mat dstImage;
	dstImage.create(srcImage.rows,srcImage.cols,srcImage.type());//按原始图的参数规格来创建效果图
	double time0=static_cast(getTickCount());//getTickCount()函数返回CPU自某个事件(如启动电脑)以来走过的时钟周期数;getTickFrequency()函数返回CPU一秒钟所走过的时钟周期数,两者结合起来就能以秒为单位对某运算计时
	colorReduce(srcImage,dstImage,32);
	time0=((double)getTickCount()-time0)/getTickFrequency();
	cout<<"此方法运行时间为: "<(i);//获取第i行的首地址
		for(int j=0;j::iterator it=outputImage.begin();//初始位置的迭代器
	Mat_::iterator itend=outputImage.end();//终止位置的迭代器
	//存取彩色图像像素
	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(i,j)[0]=
				outputImage.at(i,j)[0]/div*div+div/2;//蓝色通道
			outputImage.at(i,j)[1]=
				outputImage.at(i,j)[1]/div*div+div/2;//蓝色通道
			outputImage.at(i,j)[2]=
				outputImage.at(i,j)[2]/div*div+div/2;//红色通道
		//成员函数at(int y,int x)可以用来存取图像元素,但是必须在编译期知道图像的数据类型。需要注意的是,一定要确保指定的数据类型要和矩阵中的数据类型相符合,因为at方法本身不会对
		//任何数据类型进行转换;对于彩色图像,每个像数由BGR组成。因此,对于一个包含彩色图像的Mat,会返回一个由三个8位数组成的向量。OpenCV将此类型的向量定义为Vec3b,即由三个unsigned char
		//组成的向量,索引值channel标明了颜色通道号。
		
		}
	
	}

}
*/

7初级图像融合与图像区域选定

#include 
#include 
#include 

using namespace cv;
using namespace std;


bool  ROI_AddImage();
bool  LinearBlending();
bool  ROI_LinearBlending();
void   ShowHelpText();

//-----------------------------------【main( )函数】--------------------------------------------
//	描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main(   )
{
	system("color 6F");
 
	ShowHelpText();

	if(ROI_AddImage( )&& LinearBlending( )&&ROI_LinearBlending( ))
	{
		cout<利用ROI实现图像叠加示例窗口");
	imshow("<1>利用ROI实现图像叠加示例窗口",srcImage1);

	return true;
}


//---------------------------------【LinearBlending()函数】-------------------------------------
// 函数名:LinearBlending()
// 描述:利用cv::addWeighted()函数实现图像线性混合
//--------------------------------------------------------------------------------------------
bool  LinearBlending()
{
	//【0】定义一些局部变量
	double alphaValue = 0.5; 
	double betaValue;
	Mat srcImage2, srcImage3, dstImage;

	// 【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )
	srcImage2 = imread("mogu.jpg");
	srcImage3 = imread("rain.jpg");

	if( !srcImage2.data ) { printf("读取srcImage2错误! \n"); return false; }
	if( !srcImage3.data ) { printf("读取srcImage3错误! \n"); return false; }

	// 【2】进行图像混合加权操作
	betaValue = ( 1.0 - alphaValue );
	addWeighted( srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);
	//第一个参数:src1,表示需要加权的第一个数组,常常填一个Mat;第二个参数double类型alpha,表示第一个数组的权重;第三个参数表示第二个数组,它需要
	//和第一个数组拥有相同的尺寸和通道数;第四个参数double类型的beta,表示第二个数组的权重;第五个参数double类型的gamma,一个加到权重总和上的标量值;
	//第六个参数输出数组;第七个参数有默认值-1.即输出阵列的深度,默认下与输入相同dst=src[1]*alpha+src[2]*beta+gamma;
	//需要注意:当输出数组的深度为CV_32S时,这个函数就不适合了,这时候就会内存溢出或者结果不对

	// 【3】显示原图窗口
	imshow( "<2>线性混合示例窗口【原图】", srcImage2 );
	imshow( "<3>线性混合示例窗口【效果图】", dstImage );

	return true;

}

//---------------------------------【ROI_LinearBlending()】-------------------------------------
// 函数名:ROI_LinearBlending()
// 描述:线性混合实现函数,指定区域线性图像混合.利用cv::addWeighted()函数结合定义
//			  感兴趣区域ROI,实现自定义区域的线性混合
//--------------------------------------------------------------------------------------------
bool  ROI_LinearBlending()
{

	//【1】读取图像
	Mat srcImage4= imread("dota_pa.jpg",1);
	Mat logoImage= imread("dota_logo.jpg");

	if( !srcImage4.data ) { printf("读取srcImage4错误~! \n"); return false; }
	if( !logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }

	//【2】定义一个Mat类型并给其设定ROI区域
	Mat imageROI;
	//方法一
	imageROI= srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));
	//方法二
	//imageROI= srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));

	//【3】将logo加到原图上
	addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);

	//【4】显示结果
	imshow("<4>区域线性图像混合示例窗口",srcImage4);

	return true;
}

8颜色通道分离和融合

                                                                               
#include 
#include 
#include 

//-----------------------------------【命名空间声明部分】---------------------------------------
//	描述:包含程序所使用的命名空间
//-------------------------------------------------------------------------------------------------   
using namespace cv;
using namespace std;


//-----------------------------------【全局函数声明部分】--------------------------------------
//	描述:全局函数声明
//-----------------------------------------------------------------------------------------------
bool  MultiChannelBlending();
void ShowHelpText();

int main(   )
{
	system("color 9F");

	ShowHelpText( );

	if(MultiChannelBlending( ))
	{
		cout< channels;
	Mat  imageBlueChannel;

	//=================【蓝色通道部分】=================
	//	描述:多通道混合-蓝色分量部分
	//============================================

	// 【1】读入图片
	logoImage= imread("dota_logo.jpg",0);
	srcImage= imread("dota_jugg.jpg");

	if( !logoImage.data ) { printf("Oh,no,读取logoImage错误~! \n"); return false; }
	if( !srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	//【2】把一个3通道图像转换成3个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的蓝色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageBlueChannel= channels.at(0);
	//【4】将原图的蓝色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageBlueChannel中
	addWeighted(imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
		logoImage,0.5,0,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow(" <1>游戏原画+logo蓝色通道");
	imshow(" <1>游戏原画+logo蓝色通道",srcImage);


	//=================【绿色通道部分】=================
	//	描述:多通道混合-绿色分量部分
	//============================================

	//【0】定义相关变量
	Mat  imageGreenChannel;

	//【1】重新读入图片,重新更新图片,因为该图片已经被修改了
	logoImage= imread("dota_logo.jpg",0);
	srcImage= imread("dota_jugg.jpg");

	if( !logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }
	if( !srcImage.data ) { printf("读取srcImage错误~! \n"); return false; }

	//【2】将一个三通道图像转换成三个单通道图像
	split(srcImage,channels);//分离色彩通道
	/*第一个参数为多通道数组InputArray类型的m或const Mat&类型的src;第二个参数输出数组或vector容器,下一语句为具体引用,B,G,R:0,1,2*/

	//【3】将原图的绿色通道的引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageGreenChannel= channels.at(1);
	//【4】将原图的绿色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageGreenChannel中
	addWeighted(imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
		logoImage,0.5,0.,imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个独立的单通道重新合并成一个三通道
	merge(channels,srcImage);
	//第一个参数,mv。填需要被合并的输入矩阵或vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度;
	//另一基本原型:第二个参数,count。当mv为一个空白的C数组时,代表输入矩阵的个数,这个参数显然必须大于1
	//第三个参数:dst。即输出矩阵,和mv【0】拥有一样的尺寸和深度,并且通道数的数量是矩阵阵列中的通道数的总数
	//【6】显示效果图
	namedWindow("<2>游戏原画+logo绿色通道");
	imshow("<2>游戏原画+logo绿色通道",srcImage);



	//=================【红色通道部分】=================
	//	描述:多通道混合-红色分量部分
	//============================================

	//【0】定义相关变量
	Mat  imageRedChannel;

	//【1】重新读入图片
	logoImage= imread("dota_logo.jpg",0);
	srcImage= imread("dota_jugg.jpg");

	if( !logoImage.data ) { printf("Oh,no,读取logoImage错误~! \n"); return false; }
	if( !srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	//【2】将一个三通道图像转换成三个单通道图像
	split(srcImage,channels);//分离色彩通道

	//【3】将原图的红色通道引用返回给imageBlueChannel,注意是引用,相当于两者等价,修改其中一个另一个跟着变
	imageRedChannel= channels.at(2);
	//【4】将原图的红色通道的(500,250)坐标处右下方的一块区域和logo图进行加权操作,将得到的混合结果存到imageRedChannel中
	addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,
		logoImage,0.5,0.,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)));

	//【5】将三个独立的单通道重新合并成一个三通道
	merge(channels,srcImage);

	//【6】显示效果图
	namedWindow("<3>游戏原画+logo红色通道 ");
	imshow("<3>游戏原画+logo红色通道 ",srcImage);

	return true;
}
/*复杂的通道组合,可以使用mixChannels()函数:函数功能:
mixChannels主要就是把输入的矩阵(或矩阵数组)的某些通道拆分复制给对应的输出矩阵(或矩阵数组)的某些通道中,其中的对应关系就由fromTo参数指定.
参数说明:
src– Input array or vector of matrices. All the matrices must have the same size and the same depth.
输入矩阵,可以为一个也可以为多个,但是矩阵必须有相同的大小和深度.
nsrcs– Number of matrices in src.
输入矩阵的个数。
dst– Output array or vector of matrices. All the matrices must be allocated. Their size and depth must be the same as in src[0].
输出矩阵,可以为一个也可以为多个,但是所有的矩阵必须事先分配空间(如用create),大小和深度须与输入矩阵等同.
ndsts– Number of matrices in dst.
输出矩阵的个数。
fromTo – Array of index pairs specifying which channels are copied and where. fromTo[k*2] is a 0-based index of the input channel in src. fromTo[k*2+1] is an index of the outputchannel in dst. The continuous channel numbering is used: the first input image channels are indexed from 0 to src[0].channels()-1 , the second input image channels areindexed from src[0].channels() to src[0].channels() + src[1].channels()-1, and so on. The same scheme is used for the output image channels. As a special case, whenfromTo[k*2] is negative, the corresponding output channel is filled with zero .
设置输入矩阵的通道对应输出矩阵的通道,规则如下:首先用数字标记输入矩阵的各个通道。输入矩阵个数可能多于一个并且每个矩阵的通道可能不一样,第一个输入矩阵的通道标记范围为:0 ~ src[0].channels()-1,第二个输入矩阵的通道标记范围为:src[0].channels() ~ src[0].channels()+src[1].channels()-1,以此类推;其次输出矩阵也用同样的规则标记,第一个输出矩阵的通道标记范围为:0 ~ dst[0].channels()-1,第二个输入矩阵的通道标记范围为:dst[0].channels()~ dst[0].channels()+dst[1].channels()-1,以此类推;最后,数组fromTo的第一个元素即fromTo[0]应该填入输入矩阵的某个通道标记,而fromTo的第二个元素即fromTo[1]应该填入输出矩阵的某个通道标记,这样函数就会把输入矩阵的fromTo[0]通道里面的数据复制给输出矩阵的fromTo[1]通道。fromTo后面的元素也是这个道理,总之就是一个输入矩阵的通道标记后面必须跟着个输出矩阵的通道标记。
npairs– Number of index pairs in fromTo.
即参数fromTo中的有几组输入输出通道关系,其实就是参数fromTo的数组元素个数除以2.
示例代码:
Mat rgba(3,4,CV_8UC4,Scalar(1,2,3,4));//1,2,3,4为自己赋值,不代表通道数值
Mat bgr(rgba.rows,rgba.cols,CV_8UC3);
Mat alpha(rgba.rows,rgba.cols,CV_8UC1);
Mat out[]={bgr,alpha};
//rgba[0]->bgr[2],rgba[1]->bgr[1],rgba[2]->bgr[0],rgba[3]->alpha[0]
int from_to[]={0,2,1,1,2,0,3,3};
mixChannels(&rgba,1,out,2,from_to,4);
*/





你可能感兴趣的:(《Open CV3编程入门》学习笔记3)