OpenCV的resize方法4种插值方法效果对比器

54 篇文章 0 订阅
本文详细介绍了OpenCV库中的resize方法,以及其支持的四种插值算法(最近邻、双线性、双三次和区域像素混合),并通过示例代码展示了它们在图像缩放过程中的效果。
摘要由CSDN通过智能技术生成

resize方法

OpenCV中的resize方法是一种用于调整图像尺寸的函数。它可以将图像缩放到指定的尺寸,或者按比例放大或缩小图像。

dst = cv2.resize(src, dsize, fx=None, fy=None,
interpolation=cv2.INTER_LINEAR)

参数说明:

  • src:输入的原始图像。
  • dsize:输出图像的目标尺寸,是一个包含宽度和高度的元组(width, height)。当dsize不为零时,它表示输出图像的确切尺寸。
  • fx:沿水平轴的缩放因子。默认为None,表示不进行水平缩放。如果dsize为零,则可以通过fx和fy来指定缩放因子。
  • fy:沿垂直轴的缩放因子。默认为None,表示不进行垂直缩放。
  • interpolation:插值方法,用于指定如何在原始图像和目标图像之间进行插值。

插值方法介绍

最近邻插值(cv2.INTER_NEAREST):

  • 该方法是从输入图像中最接近目标像素的位置获取像素值。
  • 优点:计算速度快。
  • 缺点:在放大图像时可能会导致图像出现像素化的效果,质量较差。

双线性插值(cv2.INTER_LINEAR):

  • 该方法通过对周围像素进行加权平均来计算目标像素的值。
  • 优点:速度较快,质量较好,可以有效减少图像的锯齿和模糊。
  • 缺点:可能导致一些细节丢失。

双三次插值(cv2.INTER_CUBIC):

  • 该方法使用周围4x4像素的立方函数来计算目标像素的值。
  • 优点:速度适中,质量较好。
  • 缺点:相比双线性插值计算更复杂。

区域像素混合插值(cv2.INTER_AREA)

  • 该方法通过考虑目标像素周围的像素值来计算目标像素的值。
  • 优点:在图像抽取(decimation)时能提供较好的效果。
  • 缺点:在放大图像时,效果可能类似于最近邻插值法。

效果

在这里插入图片描述

代码

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QLabel, QGridLayout, QHBoxLayout, QVBoxLayout, \
    QWidget, QPushButton
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt
import cv2


class ImageResizeWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Image Resize with Interpolation')
        self.setGeometry(100, 100, 1200, 900)

        # 创建垂直布局
        vertical_layout = QVBoxLayout()

        # 创建按钮用于打开文件对话框
        self.open_button = QPushButton('Open Image', self)
        self.open_button.clicked.connect(self.loadImage)
        vertical_layout.addWidget(self.open_button)

        # 创建中心部件
        central_widget = QWidget()
        central_widget.setLayout(vertical_layout)
        self.setCentralWidget(central_widget)

    def loadImage(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_name, _ = QFileDialog.getOpenFileName(self, "Open Image", "",
                                                   "All Files (*);;;PNG Files (*.png);;;JPG Files (*.jpg)",
                                                   options=options)
        if file_name:
            # 读取图片
            self.original_image = cv2.imread(file_name)
            # 将图片转换为Qt可以显示的格式
            qt_image = QImage(self.original_image.data, self.original_image.shape[1], self.original_image.shape[0],
                              QImage.Format_RGB888).rgbSwapped()
            self.original_pixmap = QPixmap.fromImage(qt_image)

            # 创建水平布局来放置所有图片
            horizontal_layout = QHBoxLayout()

            # 添加原图
            self.original_label = QLabel(self)
            self.original_label.setPixmap(self.original_pixmap)
            horizontal_layout.addWidget(self.original_label)

            # 创建2x2的网格布局来放置插值图片
            grid_layout = QGridLayout()
            self.interpolation_labels = {}
            interpolations = ['Nearest', 'Linear', 'Cubic', 'Lanczos']
            for i, interpolation in enumerate(interpolations):
                resized_image = self.resizeImage(interpolation)
                qt_resized_image = QImage(resized_image.data, resized_image.shape[1], resized_image.shape[0],
                                          QImage.Format_RGB888).rgbSwapped()
                resized_pixmap = QPixmap.fromImage(qt_resized_image)

                # 创建一个垂直布局,将图片和名字标签放入其中
                vertical_layout = QVBoxLayout()

                label = QLabel(self)
                label.setPixmap(resized_pixmap)
                vertical_layout.addWidget(label)

                name_label = QLabel(interpolation, self)
                #name_label.setAlignment(Qt.AlignVCenter)  # 设置名字标签垂直居中对齐
                vertical_layout.addWidget(name_label)
                vertical_layout.setAlignment(Qt.AlignCenter)
                # 将垂直布局添加到网格布局中
                grid_layout.addLayout(vertical_layout, i // 2, i % 2)

                self.interpolation_labels[interpolation] = (label, name_label)

                # 将网格布局放入一个QWidget中,以便可以添加到水平布局中
            grid_widget = QWidget()
            grid_widget.setLayout(grid_layout)
            horizontal_layout.addWidget(grid_widget)

            # 将水平布局添加到垂直布局中
            vertical_layout = self.centralWidget().layout()
            vertical_layout.addLayout(horizontal_layout)

    def resizeImage(self, interpolation):
        # 原始图片的尺寸
        original_height, original_width = self.original_image.shape[:2]
        new_size = (int(original_width * 2), int(original_height * 2))

        # 使用指定的插值方法进行缩放
        resized_image = cv2.resize(self.original_image, new_size,
                                   interpolation=cv2.INTER_CUBIC if interpolation == 'Cubic' else
                                   cv2.INTER_LANCZOS4 if interpolation == 'Lanczos' else
                                   getattr(cv2, f'INTER_{interpolation.upper()}'))
        return resized_image


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ImageResizeWindow()
    ex.show()
    sys.exit(app.exec_())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

立秋6789

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值