opencv的resize方法4种插值方法效果对比器
resize方法
opencv中的resize方法是一种用于调整图像尺寸的函数。它可以将图像缩放到指定的尺寸,或者按比例放大或缩小图像。
参数说明:
- 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_())
发表评论