2022-5-25:OpenCV入门(七)imgproc组件学习之三——漫水填充、图像金字塔与尺寸缩放

漫水填充

所谓漫水填充,简单来说,就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色,这是个非常有用的功能,经常用来标记或者分离图像的一部分进行处理或分析。

int floodFill(InputOutputArray image, Point seedPoint, Scalar newVal, Rect* rect=0,Scalar loDiff=Scalar(),Scalar upDiff=Scalar(),int flags=4)
//第一个参数:输入输出图像;第二个参数:起始点;第三个参数:像素点被染色的值;第四个参数:重绘区域的最小边界矩形区域;第五个参数:颜色负差的最大值;第六个参数:颜色之正差的最大值;第七个参数:操作标识符。
#include <opencv2/opencv.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  
using namespace cv;

int main()
{
	Mat src = imread("1.jpg");
	imshow("【原始图】", src);
	Rect ccomp;
	floodFill(src, Point(100, 100), Scalar(155, 255, 55), &ccomp, Scalar(20, 20, 20), Scalar(20, 20, 20));
	imshow("【效果图】", src);
	waitKey(0);
	return 0;
}

在这里插入图片描述

图像金字塔

高斯金字塔(Gaussianpyramid)——用来向下采样,主要的图像金字塔。
拉普拉斯金字塔(Laplacianpyramid)——用来从金字塔低层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用。

在这里插入图片描述

高斯金字塔

下采样:(1)对图像G进行高斯内核卷积;(2)将所有偶数行和列去除。
上采样:(1)将图像在每个方向扩大为原来的两倍,新增的行和列以О填充。(2)使用先前同样的内核(乘以4)与放大后的图像卷积,获得“新增像素”的近似值。

拉普拉斯金字塔

在这里插入图片描述

尺寸调整:resize()函数

void resize(InputArray src,OutputArray dst,Size dsize,double fx=0,double fy=0,int interpolation=INTER_LINEAR)
//第一个参数:输入图像;第二个参数:输出图像;第三个参数:输出图像大小;第四个参数:沿水平轴缩放系数;五个参数:沿垂直轴缩放系数;第六个参数:插值方式。

向上采样:pyrUp()函数

void pyrUp(InputArray src,OutputArray dst,const Size&dstsize=Size(),int borderType=BORDER_DEFAULF)
//第一个参数:输入图像;第二个参数:输出图像;第三个参数:输出图像大小;第四个参数:边界模式。

下采样:pyrDown()函数

void pyrDown(InputArray src,OutputArray dst,const Size&dstsize=Size(),int borderType=BORDER_DEFAULF)
//第一个参数:输入图像;第二个参数:输出图像;第三个参数:输出图像大小;第四个参数:边界模式。
#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;

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

	// 创建显示窗口
	namedWindow(WINDOW_NAME, 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));
			printf(">检测到按键【A】被按下,开始进行基于【pyrUp】函数的图片放大:图片尺寸×2 \n");
			break;

		case 'w'://按键W按下,调用resize函数
			resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
			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));
			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;
}

阈值化

固定阈值操作:Threshold()函数

double threshold(InputArray src,OutputArray dst,double thresh,double maxval,int type)
//第一个参数:输入图像;第二个参数:输出图像;第三个参数:阈值的具体值;第四个参数:阈值最大值;五个参数:阈值类型。

在这里插入图片描述

自适应阈值操作:adaptiveThreshold()函数

void adaptiveThreshold(InputArray src,OutputArray dst,double maxValue,double maxval,int type)
//第一个参数:输入图像;第二个参数:输出图像;第三个参数:阈值最大值;第四个参数:使用的自适应阈值算法;五个参数:阈值类型;第六个参数:计算阈值大小的邻域尺寸;第七个参数:常数值。
#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;

void on_Threshold(int, void*);//回调函数

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

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

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

	//【4】创建滑动条来控制阈值
	createTrackbar("模式",
		WINDOW_NAME, &g_nThresholdType,
		4, 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*)
{
	//调用阈值函数
	threshold(g_grayImage, g_dstImage, g_nThresholdValue, 255, g_nThresholdType);

	//更新效果图
	imshow(WINDOW_NAME, g_dstImage);
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值