python 图像处理之插值 最近邻、双线性、双三次

时间:2024-04-12 09:39:52

        python 图像处理之插值 最近邻、双线性、双三次

1.最近邻:

import cv2
import numpy as np
def function(img):
    height,width,channels =img.shape
    emptyImage=np.zeros((2048,2048,channels),np.uint8)
    sh=2048/height
    sw=2048/width
    for i in range(2048):
        for j in range(2048):
            x=int(i/sh)
            y=int(j/sw)
            emptyImage[i,j]=img[x,y]
    return emptyImage
 
img=cv2.imread("e:\\lena.bmp")
zoom=function(img)
cv2.imshow("nearest neighbor",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)

2.双线性:

import cv2
import numpy as np
import math
def function(img,m,n):
    height,width,channels =img.shape
    emptyImage=np.zeros((m,n,channels),np.uint8)
    value=[0,0,0]
    sh=m/height
    sw=n/width
    for i in range(m):
        for j in range(n):
            x = i/sh
            y = j/sw
            p=(i+0.0)/sh-x
            q=(j+0.0)/sw-y
            x=int(x)-1
            y=int(y)-1
            for k in range(3):
                if x+1<m and y+1<n:
                    value[k]=int(img[x,y][k]*(1-p)*(1-q)+img[x,y+1][k]*q*(1-p)+img[x+1,y][k]*(1-q)*p+img[x+1,y+1][k]*p*q)
            emptyImage[i, j] = (value[0], value[1], value[2])
    return emptyImage
 
img=cv2.imread("e:\\lena.bmp")
zoom=function(img,2048,2048)
cv2.imshow("Bilinear Interpolation",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)

3.双三次:

import cv2
import numpy as np
import math
 
 
def S(x):
    x = np.abs(x)
    if 0 <= x < 1:
        return 1 - 2 * x * x + x * x * x
    if 1 <= x < 2:
        return 4 - 8 * x + 5 * x * x - x * x * x
    else:
        return 0
def function(img,m,n):
    height,width,channels =img.shape
    emptyImage=np.zeros((m,n,channels),np.uint8)
    sh=m/height
    sw=n/width
    for i in range(m):
        for j in range(n):
            x = i/sh
            y = j/sw
            p=(i+0.0)/sh-x
            q=(j+0.0)/sw-y
            x=int(x)-2
            y=int(y)-2
            A = np.array([
                [S(1 + p), S(p), S(1 - p), S(2 - p)]
            ])
            if x>=m-3:
                m-1
            if y>=n-3:
                n-1
            if x>=1 and x<=(m-3) and y>=1 and y<=(n-3):
                B = np.array([
                    [img[x-1, y-1], img[x-1, y],
                     img[x-1, y+1],
                     img[x-1, y+1]],
                    [img[x, y-1], img[x, y],
                     img[x, y+1], img[x, y+2]],
                    [img[x+1, y-1], img[x+1, y],
                     img[x+1, y+1], img[x+1, y+2]],
                    [img[x+2, y-1], img[x+2, y],
                     img[x+2, y+1], img[x+2, y+1]],
 
                    ])
                C = np.array([
                    [S(1 + q)],
                    [S(q)],
                    [S(1 - q)],
                    [S(2 - q)]
                ])
                blue = np.dot(np.dot(A, B[:, :, 0]), C)[0, 0]
                green = np.dot(np.dot(A, B[:, :, 1]), C)[0, 0]
                red = np.dot(np.dot(A, B[:, :, 2]), C)[0, 0]
 
                # ajust the value to be in [0,255]
                def adjust(value):
                    if value > 255:
                        value = 255
                    elif value < 0:
                        value = 0
                    return value
 
                blue = adjust(blue)
                green = adjust(green)
                red = adjust(red)
                emptyImage[i, j] = np.array([blue, green, red], dtype=np.uint8)
 
 
    return emptyImage
 
img=cv2.imread("e:\\lena.bmp")
zoom=function(img,1024,1024)
cv2.imshow("cubic",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)

使用库函数

# -*- coding: utf-8 -*- 
import cv2

fn="test2.jpg"
img=cv2.imread(fn)
w=img.shape[1]  
h=img.shape[0]  

#放大,双立方插值
newimg1=cv2.resize(img,(w*2,h*2),interpolation=cv2.INTER_CUBIC)
#放大, 最近邻插值
newimg2=cv2.resize(img,(w*2,h*2),interpolation=cv2.INTER_NEAREST)
#放大, 象素关系重采样
newimg3=cv2.resize(img,(w*2,h*2),interpolation=cv2.INTER_AREA)
#缩小, 象素关系重采样
newimg4=cv2.resize(img,(300,200),interpolation=cv2.INTER_AREA)


cv2.imshow('preview1',newimg1)
cv2.imshow('preview2',newimg2)
cv2.imshow('preview3',newimg3)
cv2.imshow('preview4',newimg4)
cv2.waitKey()
cv2.destroyAllWindows()

图像的形变与缩放,使用的是skimage的transform模块,函数比较多,功能齐全。 
1、改变图片尺寸 
函数格式为: 
skimage.transform.resize(image,output_shape) 
image:需要改变尺寸的图片 
output_shape:新的图片尺寸

from skimage import transform,data
import matplotlib.pyplot as plt
img = data.camera()
dst=transform.resize(img, (80, 60))
plt.figure('resize')

plt.subplot(121)
plt.title('before resize')
plt.imshow(img,plt.cm.gray)

plt.subplot(122)
plt.title('before resize')
plt.imshow(dst,plt.cm.gray)

plt.show()

可以看到简爱嗯图片由原来512×512,变成来80×60。 
python 图像处理之插值 最近邻、双线性、双三次

2 按比例缩放 
函数格式为: 
skimage.transform.resize(image,scale[…..]) 
scale参数可以是单个floate数,表示缩放的倍数,也可是floate型tuple,如[0.2,0.5]表示将行列分开进行缩放。

from skimage import transform,data
img = data.camera()
print(img.shape)  #图片原始大小 
print(transform.rescale(img, 0.1).shape)  #缩小为原来图片大小的0.1倍
print(transform.rescale(img, [0.5,0.25]).shape)  #缩小为原来图片行数一半,列数四分之一
print(transform.rescale(img, 2).shape)   #放大为原来图片大小的2倍

3、旋转rotate 
skimage.transform.rotate(image,angle[,…],resize=False) 
angle参数是一个float类型,表示旋转度数 
resize用于控制在旋转时,是否改变大小,默认为False

from skimage import transform,data
import matplotlib.pyplot as plt
img = data.camera()
print(img.shape)  #图片原始大小
img1=transform.rotate(img, 60) #旋转90度,不改变大小 
print(img1.shape)
img2=transform.rotate(img, 30,resize=True)  #旋转30度,同时改变大小
print(img2.shape)   

plt.figure('resize')

plt.subplot(121)
plt.title('rotate 60')
plt.imshow(img1,plt.cm.gray)

plt.subplot(122)
plt.title('rotate  30')
plt.imshow(img2,plt.cm.gray)

plt.show()

4、图像金字塔 
以多分辨率来解释图像的一种有效但概念简单的结构就是图像金字塔。图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低的图像集合。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。当向金字塔的上层移动时,尺寸和分辨率就降低。

在此,我们举一个高斯金字塔的应用实例,函数原型为:

skimage.transform.pyramid_gaussian(image, downscale=2)

import numpy as np
import matplotlib.pyplot as plt
from skimage import data,transform

image = data.astronaut()  #载入宇航员图片
rows, cols, dim = image.shape  #获取图片的行数,列数和通道数
pyramid = tuple(transform.pyramid_gaussian(image, downscale=2))  #产生高斯金字塔图像
#共生成了log(512)=9幅金字塔图像,加上原始图像共10幅,pyramid[0]-pyramid[1]

composite_image = np.ones((rows, cols + cols / 2, 3), dtype=np.double)  #生成背景

composite_image[:rows, :cols, :] = pyramid[0]  #融合原始图像

i_row = 0
for p in pyramid[1:]:
    n_rows, n_cols = p.shape[:2]
    composite_image[i_row:i_row + n_rows, cols:cols + n_cols] = p  #循环融合9幅金字塔图像
    i_row += n_rows

plt.imshow(composite_image)
plt.show()

python 图像处理之插值 最近邻、双线性、双三次

5.保存图像 
保存图像很简单,直接用cv2.imwrite即可。

cv2.imwrite("D:\\cat2.jpg", img)

第一个参数是保存的路径及文件名,第二个是图像矩阵。其中,imwrite()有个可选的第三个参数,如下:

cv2.imwrite("D:\\cat2.jpg", img,[int(cv2.IMWRITE_JPEG_QUALITY), 5])

第三个参数针对特定的格式: 对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。 注意,cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int。下面是以不同质量存储的两幅图:
python 图像处理之插值 最近邻、双线性、双三次

对于PNG,第三个参数表示的是压缩级别。cv2.IMWRITE_PNG_COMPRESSION,从0到9,压缩级别越高,图像尺寸越小。默认级别为3:

cv2.imwrite("./cat.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])   
cv2.imwrite("./cat2.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9]) 


保存的图像尺寸如下:

python 图像处理之插值 最近邻、双线性、双三次

import cv2  
import numpy as np  
  
img = cv2.imread("./cat.jpg")  
emptyImage = np.zeros(img.shape, np.uint8)  
  
emptyImage2 = img.copy()  
  
emptyImage3=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  
#emptyImage3[...]=0  
  
cv2.imshow("EmptyImage", emptyImage)  
cv2.imshow("Image", img)  
cv2.imshow("EmptyImage2", emptyImage2)  
cv2.imshow("EmptyImage3", emptyImage3)  
cv2.imwrite("./cat2.jpg", img, [int(cv2.IMWRITE_JPEG_QUALITY), 5])  
cv2.imwrite("./cat3.jpg", img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])  
cv2.imwrite("./cat.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])  
cv2.imwrite("./cat2.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])  
cv2.waitKey (0)  
cv2.destroyAllWindows()  

【转载】:https://blog.csdn.net/u010096025/article/details/53780623

                  https://blog.csdn.net/gufeng_1992/article/details/72880795?utm_source=blogxgwz6

                  https://blog.csdn.net/m0_37338590/article/details/78864665