目录
[1. cv::resize() 介绍](#1. cv::resize() 介绍)
[2. 插值方法(关键)](#2. 插值方法(关键))
[3. 应用示例](#3. 应用示例)
在某些情况下,我们通常需要将图像转换成指定的大小,这就需要调整图像尺寸。
1. cv::resize() 介绍
|-----------------|---|----------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| void cv::resize | ( | InputArray | src, |
| | | OutputArray | dst, |
| | | Size | dsize, |
| | | double | fx = 0, |
| | | double | fy = 0, |
| | | int | interpolation = INTER_LINEAR |
| | ) | | |
参数说明:
src------输入图像
dst------输出图像;其尺寸为 dsize(当 dsize 非零时),或由 src.size()、fx 和 fy 计算得出;dst 的类型与 src 相同。
dsize------输出图像大小,dsize = Size(round(fx*src.cols), round(fy*src.rows)) 。
fx------沿水平轴的缩放因子,当其为0时,计算为: (double)dsize.width/src.cols 。
fy------沿垂直轴的缩放因子,当其为0时,计算为: (double)dsize.height/src.rows 。
interpolation------插值方法。
2. 插值方法(关键)
所谓插值(指内插值 (interpolation),相对于外插值 ,即外推 (extrapolation)),就是通过已有的像素去计算并得出需要填充的像素值 。插值是图像大小调整的关键。原图像中的像素值位于一个整数网格上;例如,我们可以引用 (20,17) 处的像素。当这些整数位置映射到新的图像后,可能存在间隙------因为,原图像中的整数位置像素映射到了目标图像的浮点位置,因此必须四舍五入到最近的整数位置,或者因为映射后目标图像是空的,没有像素填充 (考虑双倍拉伸图像,则新图像有一半的位置没有像素)。这些问题通常称为正向投影问题(forward projection problems)。
为了处理这样一种舍入问题和目标图像间隙问题,我们实际上是反向 (backward)来解决这个问题的:我们逐像素遍历目标图像的每一个像素并问,"源图像中哪一个像素需要用于填充这个目标像素?" 这些源像素将会总是位于分数像素位置,因此我们必须对源像素进行插值来推导出目标位置正确的像素值 。该函数默认使用的方法是双线性(bilinear)插值(即一种基于双变量的插值方法),但你也可以选择其它插值方法。常用的插值方法有:
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 插值方法 | 说明 |
| INTER_NEAREST | 最近领域插值 |
| INTER_LINEAR | 双线性插值 |
| INTER_CUBIC | 双三次插值(bicubic) |
| INTER_AREA | 基于像素面积关系的重采样。对于图像抽取(下采样)而言,这可能是一种首选方法,因为它能产生无Moiré条纹的结果。但在对图像进行放大时,其效果与 INTER_NEAREST 方法相似 |
| INTER_LANCZOS4 | 基于8x8领域的Lanczos 插值 |
| INTER_LINEAR_EXACT | |
| INTER_NEAREST_EXACT | 位精确双线性插值 |
| INTER_MAX | 插值代码掩码插值 |
| WARP_FILL_OUTLIERS | 该标志会填充目标图像的所有像素。如果其中某些像素对应于源图像中的离群点(outliers),则会被置为零。 |
| WARP_INVERSE_MAP | 逆变换标识,例如,linearPolar 或 logPolar 变换 |
填充目标图像最简单的方法就是取源图像中最近像素的值;这就是选择 INTER_NEAREST 能达到的效果。
3. 应用示例
(1) 用宽度和高度调整图像
void Test_resize()
{
// Load the image
cv::Mat image = cv::imread("D:\\TestVideo\\Flower6-2.jpg");
// Define new width and height
int new_width = 600;
int new_height = 400;
// Create an empty Mat object for the resized image
cv::Mat resized_image;
// Resize the image
cv::resize(image, resized_image, cv::Size(new_width, new_height));
// Display the resized image
cv::imshow("Resized Image", resized_image);
cv::waitKey(0);
}
(2) 按长宽比缩放( aspect ratio**)**
void Test_resize()
{
// Load the image
cv::Mat image = cv::imread("D:\\TestVideo\\Flower6-2.jpg");
// Get the original dimensions
int original_width = image.cols;
int original_height = image.rows;
// Define new width while maintaining the aspect ratio
int new_width = 2000;
double aspect_ratio = static_cast<double>(new_width) / original_width;
int new_height = static_cast<int>(original_height * aspect_ratio); // Compute height based on aspect ratio
// Create an empty Mat object for the resized image
cv::Mat resized_image;
// Resize the image
cv::resize(image, resized_image, cv::Size(new_width, new_height));
// Display the resized image
cv::imshow("Resized Image", resized_image);
cv::waitKey(0);
}
(3) 利用 fx 和 fy 参数来对图像进行缩放
与其手动指定宽度和高度,我们可以利用 fx 和 fy 参数来对图像进行缩放。将 fx 设置为等于 fy,即可确保保持图像的纵横比。
void Test_resize()
{
// Load the image
cv::Mat image = cv::imread("D:\\TestVideo\\Flower6-2.jpg");
// Scaling factors
double scale_down = 0.8;
double scale_up = 1.2;
// Create Mat objects for the resized images
cv::Mat resized_down, resized_up;
// Resize the image (scaling down)
cv::resize(image, resized_down, cv::Size(), scale_down, scale_down, cv::INTER_LINEAR);
// Resize the image (scaling up)
cv::resize(image, resized_up, cv::Size(), scale_up, scale_up, cv::INTER_LINEAR);
// Display the images
cv::imshow("Original Image", image);
cv::imshow("Scaled Down Image", resized_down);
cv::imshow("Scaled Up Image", resized_up);
cv::waitKey(0);
}