目录
在某些情况下,我们通常需要将图像转换成指定的大小,这就需要调整图像尺寸。
1. cv::resize() 介绍
| void cv::resize | ( | src, | |
| dst, | |||
| 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);
}
721

被折叠的 条评论
为什么被折叠?



