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

图像金字塔与尺寸缩放:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

#define WINDOW_NAME "【程序窗口】"		//为窗口标题定义的宏
Mat g_srcImage, g_dstImage, g_tmpImage;
static void ShowHelpText();
int main( )
{
	//改变console字体颜色
	system("color 2F");  

	//显示帮助文字
	ShowHelpText();

	//载入原图
	g_srcImage = imread("1.jpg");//工程目录下需要有一张名为1.jpg的测试图像,且其尺寸需被2的N次方整除,N为可以缩放的次数
	if( !g_srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	// 创建显示窗口
	namedWindow( WINDOW_NAME, CV_WINDOW_AUTOSIZE );
	imshow(WINDOW_NAME, g_srcImage);

	//参数赋值
	g_tmpImage = g_srcImage;
	g_dstImage = g_tmpImage;

	int key =0;

	//轮询获取按键信息
	while(1)
	{
		key=waitKey(9) ;//读取键值到key变量中

		//根据key变量的值,进行不同的操作
		switch(key)
		{
			//======================【程序退出相关键值处理】=======================  
		case 27://按键ESC
			return 0;
			break; 

		case 'q'://按键Q
			return 0;
			break; 

			//======================【图片放大相关键值处理】=======================  
		case 'a'://按键A按下,调用pyrUp函数
			pyrUp( g_tmpImage, g_dstImage, Size( g_tmpImage.cols*2, g_tmpImage.rows*2 ) );
			/*向上采样并模糊一张图片,即放大一张图片,朝向金字塔下方
			第一个参数:输入图像;
			第二个参数:输出图像;
			第三个const Size&类型的dstsize,输出图像的大小;有默认值Size(),即在默认情况下,由Size(src.cols*2,src.rows*2)来计算,
			且一直需要满足:|dstsize.width-src.cols*2|<=(dstsize.width mode 2)所以各边放大到原来的2倍;
			第四个参数:边界模式
			实现过程:将原来维数扩大一倍,对于增加值用0填充再与高斯矩阵卷积;
			拉普拉斯金字塔:图像首先在每个维度上扩大为原来的两倍,新增的行以0填充,然后给指定的滤波器进行卷积(实际上是一个在每一维上都扩大为2倍的过滤器)
			去估计“丢失”像素的近似值。得到后的图像与原来的图像相比较会发觉比较模糊,丢失了一些信息。为了恢复出原来的图像,我们需要获得这些丢失的信息,
			这些信息就构成了拉普拉斯金字塔。*/
			printf( ">检测到按键【A】被按下,开始进行基于【pyrUp】函数的图片放大:图片尺寸×2 \n" );		
			break; 

		case 'w'://按键W按下,调用resize函数
			resize(g_tmpImage,g_dstImage,Size( g_tmpImage.cols*2, g_tmpImage.rows*2 ));
			/*第一个参数:输入图像;第二个参数:输出图像,当其为非零时,有着第三参数的尺寸,或者由src.size()计算出来;
			第三个参数:Size类型的dsize,输出图像的大小。如果它等于零,则由dsize=Size(round(fx*src.cols),round(fy*src.rows))计算得到round为四舍五入;
			第四个参数:double类型的fx,沿水平轴的缩放系数,有默认值0,且当其为0时,由(double)dsize.width/src.cols计算得到;
			第五个参数:double类型的fy,沿垂直轴的缩放系数,同上;
			第六个参数:int类型的interpolation,用于指定插值方式,默认为INTER_LINEAR(线性插值)具体方式如下:
            INTER_NEAREST - 最近邻插值法
			INTER_LINEAR - 双线性插值法(默认)
			INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
			INTER_CUBIC - 基于4x4像素邻域的3次插值法
			INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
			若要缩小图像,一般情况下最好用CV_INTER_AREA来插值;若要放大图像,一般情况下最好用CV_INTER_CUBIC(效率不高,慢)或CV_INTER_LINEAR(效率较高,速度较快,推荐使用)
			*/
			printf( ">检测到按键【W】被按下,开始进行基于【resize】函数的图片放大:图片尺寸×2 \n" );		
			break; 

		case '1'://按键1按下,调用resize函数
			resize(g_tmpImage,g_dstImage,Size( g_tmpImage.cols*2, g_tmpImage.rows*2 ));
			printf( ">检测到按键【1】被按下,开始进行基于【resize】函数的图片放大:图片尺寸×2 \n" );
			break; 

		case '3': //按键3按下,调用pyrUp函数
			pyrUp( g_tmpImage, g_dstImage, Size( g_tmpImage.cols*2, g_tmpImage.rows*2 ));
			printf( ">检测到按键【3】被按下,开始进行基于【pyrUp】函数的图片放大:图片尺寸×2 \n" );
			break; 
			//======================【图片缩小相关键值处理】=======================  
		case 'd': //按键D按下,调用pyrDown函数
			pyrDown( g_tmpImage, g_dstImage, Size( g_tmpImage.cols/2, g_tmpImage.rows/2 ));
			/*向下采样并模糊一张图片,即缩小一张图片,朝向金字塔上方
			第一个参数:输入图像;
			第二个参数:输出图像;
			第三个const Size&类型的dstsize,输出图像的大小;有默认值Size(),即在默认情况下,由Size((src.cols+1)/2,(src.rows+1)/2)来计算,
			且一直需要满足:|dstsize.width*2-src.cols|<=2,|dstsize.height*2-src.rows|<=2所以各边缩小到原来的0.5倍;
			第四个参数:边界模式
			实现过程:高斯金字塔:金字塔从i层生成第i+1层,我们要先用高斯核对Gi进行卷积,然后,删除所有偶数行和偶数列。这样,新得到的图像面积会变为源图像的四分之一*/

			printf( ">检测到按键【D】被按下,开始进行基于【pyrDown】函数的图片缩小:图片尺寸/2\n" );
			break; 

		case  's' : //按键S按下,调用resize函数
			resize(g_tmpImage,g_dstImage,Size( g_tmpImage.cols/2, g_tmpImage.rows/2 ));
			printf( ">检测到按键【S】被按下,开始进行基于【resize】函数的图片缩小:图片尺寸/2\n" );
			break; 

		case '2'://按键2按下,调用resize函数
			resize(g_tmpImage,g_dstImage,Size( g_tmpImage.cols/2, g_tmpImage.rows/2 ));
			printf( ">检测到按键【2】被按下,开始进行基于【resize】函数的图片缩小:图片尺寸/2\n" );
			break; 

		case '4': //按键4按下,调用pyrDown函数
			pyrDown( g_tmpImage, g_dstImage, Size( g_tmpImage.cols/2, g_tmpImage.rows/2 ) );
			printf( ">检测到按键【4】被按下,开始进行基于【pyrDown】函数的图片缩小:图片尺寸/2\n" );
			break; 
		}

		//经过操作后,显示变化后的图
		imshow( WINDOW_NAME, g_dstImage );

		//将g_dstImage赋给g_tmpImage,方便下一次循环
		g_tmpImage = g_dstImage;
	}

	return 0;
}

//-----------------------------------【ShowHelpText( )函数】----------------------------------
//		描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{

	//输出一些帮助信息
	printf("\n\t欢迎来到OpenCV图像金字塔和resize示例程序~\n\n");
	printf( "\n\n\t按键操作说明: \n\n"
		"\t\t键盘按键【ESC】或者【Q】- 退出程序\n"
		"\t\t键盘按键【1】或者【W】- 进行基于【resize】函数的图片放大\n"
		"\t\t键盘按键【2】或者【S】- 进行基于【resize】函数的图片缩小\n"
		"\t\t键盘按键【3】或者【A】- 进行基于【pyrUp】函数的图片放大\n"
		"\t\t键盘按键【4】或者【D】- 进行基于【pyrDown】函数的图片缩小\n"
		);
}

阈值与自适应阈值操作

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME "【程序窗口】"        //为窗口标题定义的宏 
int g_nThresholdValue = 100;
int g_nThresholdType = 3;
Mat g_srcImage, g_grayImage, g_dstImage;

static void ShowHelpText( );//输出帮助文字
void on_Threshold( int, void* );//回调函数
int main( )
{
	//【0】改变console字体颜色
	system("color 1F"); 

	//【0】显示欢迎和帮助文字
	ShowHelpText( );

	//【1】读入源图片
	g_srcImage = imread("1.jpg");
	if(!g_srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }  
	imshow("原始图",g_srcImage);

	//【2】存留一份原图的灰度图
	cvtColor( g_srcImage, g_grayImage, CV_RGB2GRAY );

	//【3】创建窗口并显示原始图
	namedWindow( WINDOW_NAME, CV_WINDOW_AUTOSIZE );

	//【4】创建滑动条来控制阈值
	createTrackbar( "模式",
		WINDOW_NAME, &g_nThresholdType,
		5, on_Threshold );

	createTrackbar( "参数值",
		WINDOW_NAME, &g_nThresholdValue,
		255, on_Threshold );

	//【5】初始化自定义的阈值回调函数
	on_Threshold( 0, 0 );

	// 【6】轮询等待用户按键,如果ESC键按下则退出程序
	while(1)
	{
		int key;
		key = waitKey( 20 );
		if( (char)key == 27 ){ break; }
	}

}

//-----------------------------------【on_Threshold( )函数】------------------------------------
//		描述:自定义的阈值回调函数
//-----------------------------------------------------------------------------------------------
void on_Threshold( int, void* )
{
	//调用阈值函数
	if(g_nThresholdType<5){threshold(g_grayImage,g_dstImage,g_nThresholdValue,255,g_nThresholdType);}
	/*阈值可以被视作最简单的图像分割方法,基本思想是:给定一个数组(图像)和一个阈值,然后根据数组中的每个元素是高于还是低于阈值而进行一些处理
	该函数针对单通道数组应用固定阈值操作,该函数的典型应用是对灰度图像进行阈值操作得到二值图像,(compare()函数也可达到此目的)或者是去掉噪声,
	例如过滤掉很大或很小像素值的图像点。
	第一个参数:输入图像,为单通道8位或32位浮点类型的Mat;
	第二个参数:输出图像;
	第三个参数:double类型的thresh,阈值的具体值;
	第四个参数:double类型的maxval,当第五个参数阈值类型type取CV_THRESH_BINARY或CV_THRESH_BINARY_INV时阈值类型时的最大值;
	第五个参数:int类型的type,阈值类型,具体如下:
	0: THRESH_BINARY 二进制阈值 ,当前点值大于阈值时,取Maxval,也就是第四个参数,否则设置为0
	1: THRESH_BINARY_INV (INV为逆)反二进制阈值, 当前点值大于阈值时,设置为0,否则设置为Maxval
	2: THRESH_TRUNC 截断阈值 ,当前点值大于阈值时,设置为阈值,否则不改变
	3: THRESH_TOZERO 阈值化为0 ,当前点值大于阈值时,不改变,否则设置为0
	4: THRESH_TOZERO_INV 反阈值化为0 , 当前点值大于阈值时,设置为0,否则不改变
	*/
	//更新效果图
	else adaptiveThreshold(g_grayImage,g_dstImage,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,5,g_nThresholdValue);
	/*自适应阈值操作:能够根据不同区域亮度不均,自动改变相应阈值,支持两种自适应方法,即cv::ADAPTIVE_THRESH_MEAN_C(平均)和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。
	在两种情况下,自适应阈值T(x, y)。通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。其中,b由blockSize给出,大小必须为奇数;
	如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。
	第一个参数:输入图像单通道;
	第二个参数:输出图像;
	第三个参数:double类型的maxValue;
	第四个参数:int类型的指定要使用的自适应阈值算法,ADAPTIVE_THRESH_MEAN_C(平均)和ADAPTIVE_THRESH_GAUSSIAN_C(高斯);
	第五个参数:int类型的阈值类型:THRESH_BINARY、THRESH_BINARY_INV其中之一;
	第六个参数:int类型的blockSize用于计算阈值大小的一个像素的邻域尺寸,为奇数;
	第七个参数:double类型的C,减去的常数值,通常为正数,但少数情况下也可以为0或负数
	最后的阈值为每个像素周围bxb大小像素块的加权均值并减去常量C得到*/
	imshow( WINDOW_NAME, g_dstImage );
}

//-----------------------------------【ShowHelpText( )函数】----------------------------------  
//      描述:输出一些帮助信息  
//----------------------------------------------------------------------------------------------  
static void ShowHelpText()  
{   printf(	"\n\t欢迎来到【基本阈值操作】示例程序~\n\n");  
	printf(	"\n\t按键操作说明: \n\n"  
		"\t\t键盘按键【ESC】- 退出程序\n"  
		"\t\t滚动条模式0- 二进制阈值\n"  
		"\t\t滚动条模式1- 反二进制阈值\n"  
		"\t\t滚动条模式2- 截断阈值\n"  
		"\t\t滚动条模式3- 反阈值化为0\n"  
		"\t\t滚动条模式4- 阈值化为0\n" 
		"\t\t滚动条模式5- 自适应阈值操作\n" );  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值