图像金字塔与图像尺寸缩放:
作用:将某种尺寸的图像转换为其它尺寸的图像
1、尺寸调整:resize()函数
void resize(
InputArray src,OutputArray dst, //输入(入)图像
Size dsize, //输出图像的大小
double fx=0,double fy=0, /沿水平(垂直)轴的缩放系数、
int interpolation=INTER_LINEAR //用于指定插值方式(默认线性插值)
);
可选插值方式如下:
INTER_LINEAR-------线性插值(默认) -------放大图像时优先选用(效率高)
INTER_AREA--------区域插值(利用像素区域关系的重采样插值)--------缩小图像时优先采用
INTER_CUBIC-------三次样条插值(超过4*4像素邻域内的双三次插值)-------放大图像时选用(效率低)
INTER_LANCZOS4-------Lanczos插值(超过8*8像素邻域内的Lanczos插值)
2、pyrUp()函数
void pyrUp(
InputArray src,OutputArray dst, //输入(出)图像
const Size& dstsize=Size(), //输出图像的大小(默认Size(src.cols*2,src.rows*2))
int borderType=BORDER_DEFAULT //边界模式
);
3、pyrDown()函数
void pyrDown(
InputArray src,OutputArray dst, //输入(出)图像
const Size& dstsize=Size(), //输出图像的大小(默认Size((src.cols+1)/2,(src.rows+1)/2))
int borderType=BORDER_DEFAULT //边界模式
);
示例代码:
//--------------【图像金字塔和图像尺寸缩放综合示例】-----------------------
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
//--------------------【宏定义部分】-----------------
// 描述:定义一些辅助宏
//---------------------------------------------------
#define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏
//--------------------【全局变量声明部分】----------------
// 描述:全局变量声明
//--------------------------------------------------------
Mat g_srcImage, g_dstImage, g_tmpImage;
//--------------------【main()函数】-----------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//---------------------------------------------------------
int main() {
//载入原图
g_srcImage = imread("lenna.jpg");
if (!g_srcImage.data) { printf("读取图片错误 \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':
return 0;
break;
//=====================【图片放大相关键值处理】================
case 'a': //按键A按下,调用pryUp函数
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'://按键w按下,调用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),(0,0),(0,0),2);
printf(">检测到按键【2】被按下,开始进行基于【resize】函数的图片缩小:图片尺寸/2 \n");
break;
case '4':
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 //阈值类型
);
阈值类型有:
0--------THRESH_BINARY--------二进制阈值:二值阈值化
1--------THRESH_BINARY_INV--------反二进制阈值:反向二值阈值化并反转
2--------THRESH_TRUNC-------截断阈值:截断阈值化
3--------THRESH_TOZERO-----反阈值化为0:超过阈值被置为0
4---------THRESH_TOZERO_INV---------阈值化为0:低于阈值被置为0
adaptiveThreshold()函数-------对矩阵采用自适应阈值操作
void adaptiveThreshold(
InputArray src,OutputArray dst,//输入输出图像
double maxValue, //给像素赋的满足条件的非零值
int adaptiveMethod, // 用于指定要使用的自适应阈值算法
int thresholdType, //阈值类型
int blockSize, //用于计算阈值大小的一个像素的邻域尺寸(3,5,7。。。)
double c //减去平均或加权平均值后的常数值(通常为正数)
);
示例代码:
//--------------------【阈值化】-----------------------
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.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*);//回调函数
//-----------------【main()函数】-------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//--------------------------------------------------------
int main() {
//【1】读入原图
g_srcImage = imread("lenna.jpg");
if (!g_srcImage.data) { printf("读取图片错误 \n"); return false; }
//【2】存留一份原图的灰度图
cvtColor(g_srcImage,g_grayImage,COLOR_RGB2GRAY);
//【3】创建窗口并显示原始图
namedWindow(WINDOW_NAME,WINDOW_NORMAL);
//【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);
}