昊虹AI笔记网

 找回密码
 立即注册
搜索
查看: 733|回复: 0
收起左侧

利用OpenCV的函数resize()实现图像的缩放(尺寸变换)

[复制链接]

238

主题

241

帖子

931

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
931
昊虹君 发表于 2022-12-23 13:10 | 显示全部楼层 |阅读模式
利用OpenCV的函数resize()实现图像的缩放(尺寸变换)

可以利用OpenCV的函数resize()实现图像的缩放(尺寸变换)。

函数resize()的C++原型如下:
  1. void resize(InputArray src,
  2.             OutputArray dst,
  3.             Size dsize,
  4.             double fx=0,
  5.             double fy=0,
  6.             int interpolation=INTER_LINEAR )
复制代码

函数resize()的Python原型如下:
  1. 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
[C++] 纯文本查看 复制代码
//出处:昊虹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
[Python] 纯文本查看 复制代码
# -*- 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()

运行结果如下图所示:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|昊虹AI笔记网 ( 蜀ICP备2024076726 )

GMT+8, 2024-5-19 11:03 , Processed in 0.025735 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表