可以利用OpenCV的函数resize()实现图像的缩放(尺寸变换)。
函数resize()的C++原型如下:
void resize(InputArray src,
OutputArray dst,
Size dsize,
double fx=0,
double fy=0,
int interpolation=INTER_LINEAR )
函数resize()的Python原型如下:
dst=cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
各参数的意义如下:
src—源图像
dst—目标图像,即输出图像
dsize:输出图像的尺寸,当它为0的时候,由参数fx和fy决定其值,计算公式为:dsize = Size(round(fxsrc.cols), round(fysrc.rows))
fx—水平方向上的缩放比例因子,当它为0的时候,其值由dsize决定,计算公式为:fx=(double)dsize.width/src.cols
fy—竖直方向上的缩放比例因子,当它为0的时候,其值由dsize决定,计算公式为:fy=(double)dsize.height/src.rows
注意:当参数dsize、fx、fy都不为0,且表示的输出图像尺寸不一致时,以参数dsize设置的输出图像尺寸为准。
interpolation—插值方式,在OpenCV4中通常有七种可选的插值方法,默认为“INTER_LINEAR”。七种插值方式如下:
- INTER_NEAREST:最近邻插值。
- INTER_LINEAR:双线性插值(默认值)。
- INTER_CUBIC:双三次插值。
- INTER_AREA - 使用像素面积关系重新采样。这可能是图像抽取(decimation)的首选方法,因为它可以获得无莫尔条纹的结果。但是当图像被放大时,它类似于INTER_NEAREST方法。
- INTER_LANCZOS4—8x8邻域上的Lanczos插值。
- INTER_LINEAR_EXACT —位精确双线性插值。
- INTER_MAX—用掩模进行插值。
对于上面的插值方式,具体的数学原理,请大家去查阅相关书籍和文档,这里就不介绍了。
一般来讲,如果要缩小图像,通常用 INTER_AREA会有较好的效果;而放大图像时通常采用INTER_CUBIC和INTER_LINEAR会有比较好的效果,前者的计算速度较慢,后者的速度较快,但前者的效果比后者的效果好。
函数resize()的C++示例代码如下:
代码中用到的图像下载链接:
https://pan.baidu.com/s/1Kr12nBJPqcIlAuyFp78gUw?pwd=e5sx
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术
//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询
//OpenCV版本 OpenCV3.0
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
cv::Mat srcImage = cv::imread("F:/material/images/2022/2022-12/view1.jpg");
if (!srcImage.data)
return -1;
cv::imshow("原图", srcImage);
// 将图像缩小(利用参数dsize设定输出图像的大小)
Mat small_img;
resize(srcImage, small_img, Size(150, 100), 0, 0, INTER_AREA);
cv::imshow("small_img", small_img);
// 最近邻插值(利用参数fx和fy设定输出图像的缩放比例)
Mat big_img1;
double fx = 2, fy = 2;
resize(small_img, big_img1, Size(0, 0), fx, fy, INTER_AREA);
cv::imshow("big_img1", big_img1);
// 双线性插值(利用参数dsize设定输出图像的大小)
Mat big_img2;
resize(small_img, big_img2, Size(300, 200), 0, 0, INTER_LINEAR);
cv::imshow("big_img2", big_img2);
// 双三次插值(利用参数fx和fy设定输出图像的缩放比例)
Mat big_img3;
resize(small_img, big_img3, Size(0, 0), fx, fy, INTER_CUBIC);
cv::imshow("big_img3", big_img3);
cv::waitKey(0);
return 0;
}
运行结果如下图所示:
函数resize()的Python示例代码如下:
代码中用到的图像下载链接:
https://pan.baidu.com/s/1Kr12nBJPqcIlAuyFp78gUw?pwd=e5sx
# -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术
# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询
# OpenCV的版本为4.4.0
import cv2 as cv
import sys
if __name__ == '__main__':
# 读取图像并判断是否读取成功
img = cv.imread('F:/material/images/2022/2022-12/view1.jpg')
if img is None:
print('Failed to read img.')
sys.exit()
cv.imshow('img_src', img)
# 将图像缩小(利用参数dsize设定输出图像的大小)
small_img = cv.resize(img, (150, 100), fx=0, fy=0, interpolation=cv.INTER_AREA)
cv.imshow('small_img', small_img)
# 最近邻插值(利用参数fx和fy设定输出图像的缩放比例)
big_img1 = cv.resize(small_img, (0, 0), fx=2, fy=2, interpolation=cv.INTER_NEAREST)
cv.imshow('big_img1', big_img1)
# 双线性插值(利用参数dsize设定输出图像的大小)
big_img2 = cv.resize(small_img, (300, 200), fx=0, fy=0, interpolation=cv.INTER_LINEAR)
cv.imshow('big_img2', big_img2)
# 双三次插值(利用参数fx和fy设定输出图像的缩放比例)
big_img3 = cv.resize(small_img, (0, 0), fx=2, fy=2, interpolation=cv.INTER_CUBIC)
cv.imshow('big_img3', big_img3)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果如下图所示: