Python的图像缩放(resize)方法

双线性差值方法的详细过程,

推荐博客:三十分钟理解:线性插值,双线性插值Bilinear Interpolation算法

 

接下来,展示的是基于Python、cv2和skimage实现双线性差值的图像缩放。

#! python
#
import os
import sys
import time

# Matplotlib.
import matplotlib.pyplot as plt
# PIL.
from PIL import Image
# Numpy.
import numpy as np
# OpenCV.
import cv2
# Skimage.
import skimage
from skimage import transform


# TODO: Resize.
dst_width, dst_height = 192, 108


# py_Resize.
def py_Resize(src, shape):
    # Shape.
    height, width, channels = src.shape
    dst_width, dst_height = shape
    if ((dst_height == height) and (dst_width == width)):
        return src
    # Object.
    dst_Image = np.zeros((dst_height, dst_width, channels), np.uint8)
    # Resize.
    # Scale for resize.
    scale_x = float(width)/dst_width
    scale_y = float(height)/dst_height
    # tmp
    for k in range(channels):
        for dst_y in range(dst_height):
            for dst_x in range(dst_width):
                # Original coords.
                src_x = (dst_x + 0.5) * scale_x - 0.5
                src_y = (dst_y + 0.5) * scale_y - 0.5
                # INTER_LINEAR: 
                # 2*2 neighbors.
                src_x_0 = int(np.floor(src_x))
                src_y_0 = int(np.floor(src_y))
                src_x_1 = min(src_x_0 + 1, width - 1)
                src_y_1 = min(src_y_0 + 1, height - 1)
                # 
                value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, k] + (src_x - src_x_0) * src[src_y_0, src_x_1, k]
                value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, k] + (src_x - src_x_0) * src[src_y_1, src_x_1, k]
                # 
                dst_Image[dst_y, dst_x, k] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)
    return dst_Image


# Read the image.
# PIL.
im = Image.open('show.jpg')
print (im.size)
#(width, height): (1920, 1080)

# Numpy.
im_org = np.array(im)
print (im_org.shape)
#(height, width, channel): (1080, 1920, 3)

# 1. python.
_start = time.time()
imResize_py = py_Resize(im_org, (dst_width, dst_height)) # in 1
time1 = time.time() - _start

# 2. opencv.
_start = time.time()
imResize_cv = cv2.resize(im_org, (dst_width, dst_height))
time2 = time.time() - _start

# 3. skimage.
_start = time.time()
imResize_ski = transform.resize(im_org, (dst_height, dst_width))
time3 = time.time() - _start

# Show ALL.
plt.subplot(2,2,1); plt.title('ORG'); plt.imshow(im_org)
plt.subplot(2,2,2); plt.title('PY_resize: %fs' %(time1)); plt.imshow(imResize_py)
plt.subplot(2,2,3); plt.title('CV_resize: %fs' %(time2)); plt.imshow(imResize_cv)
plt.subplot(2,2,4); plt.title('SKI_resize: %fs' %(time3)); plt.imshow(imResize_ski)
plt.show()

结果展示:

 

详细的源码如下:

1. Python代码实现

# 1. python.
imResize_py = py_Resize(im_org, (dst_width, dst_height))

# Numpy.
import numpy as np

# py_Resize.
def py_Resize(src, shape):
	# Shape.
	height, width, channels = src.shape
	dst_width, dst_height = shape
	if ((dst_height == height) and (dst_width == width)):
		return src
	# Object.
	dst_Image = np.zeros((dst_height, dst_width, channels), np.uint8)
	# Resize.
	# Scale for resize.
	scale_x = float(width)/dst_width
	scale_y = float(height)/dst_height
	# tmp
	for k in range(channels):
		for dst_y in range(dst_height):
			for dst_x in range(dst_width):
				# Original coords.
				src_x = (dst_x + 0.5) * scale_x - 0.5
				src_y = (dst_y + 0.5) * scale_y - 0.5
				# INTER_LINEAR: 
				# 2*2 neighbors.
				src_x_0 = int(np.floor(src_x))
				src_y_0 = int(np.floor(src_y))
				src_x_1 = min(src_x_0 + 1, width - 1)
				src_y_1 = min(src_y_0 + 1, height - 1)
				# 
				value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, k] + (src_x - src_x_0) * src[src_y_0, src_x_1, k]
				value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, k] + (src_x - src_x_0) * src[src_y_1, src_x_1, k]
				# 
				dst_Image[dst_y, dst_x, k] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)
	return dst_Image

2.OpenCV实现

# 2. opencv.
import cv2

#
imResize_cv = cv2.resize(im_org, (dst_width, dst_height))

3. Skimage实现

# 3. skimage.
import skimage
from skimage import transform

#
imResize_ski = transform.resize(im_org, (dst_height, dst_width))

 

总结:

             OpenCV处理速度最快,Skimage次之,自写Python函数速率太渣。

             实际应用中,OpenCV安装太复杂,自写效率太低,建议采用Skimage。

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐