图像几何变换

实现了平移、旋转、缩放,其中缩放和旋转时采用双线性映射。
废话不多说,直接上代码

导入库

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from math import *

双线性映射

def bilinear_interpolation(img,x,y):
    # 图像像素点的双线性插值,用周围最近的四个像素进行插值
    try:
        l_x,l_y = floor(x),floor(y)
        h_x,h_y = ceil(x),ceil(y)
        x_rate,_ = modf(x)
        y_rate,_ = modf(y)
        p1 = (1-x_rate)*img[l_x,l_y]+x_rate*img[h_x,l_y]
        p2 = (1-x_rate)*img[l_x,h_y]+x_rate*img[h_x,h_y]
        p = (1-y_rate)*p1+y_rate*p2
        return p
    except:
        return img[int(x),int(y)]

平移

def translate(img,dx,dy):
    dx,dy = int(dx),int(dy)
    h,w = img.shape
    new_h,new_w = h+abs(int(dx)),w+abs(int(dy))
    r_img = np.zeros(shape=(new_h,new_w))
    xs = 0 if dx<0 else dx
    ys = 0 if dy<0 else dy
    r_img[xs:xs+h,ys:ys+w] = img
    return r_img

旋转

def rotate(img, angle):
    # 后向映射+双线性插值
    angle = angle/180*pi
    r_mat = np.array([
        [cos(angle),-sin(angle)],
        [sin(angle),cos(angle)]
    ])
    rt_mat = np.array([
        [cos(angle),sin(angle)],
        [-sin(angle),cos(angle)]
    ])
    h,w = img.shape
    max_min = np.array([
        np.array([0,0]),
        np.matmul(r_mat,np.array([0,w])),
        np.matmul(r_mat,np.array([h,w])),
        np.matmul(r_mat,np.array([h,0]))
    ])
    x_l = int(max_min[:,0].min())
    x_h = ceil(max_min[:,0].max())
    y_l = int(max_min[:,1].min())
    y_h = ceil(max_min[:,1].max())
    r_img = np.zeros(shape=(x_h-x_l,y_h-y_l))
    for i in range(x_h-x_l):
        for j in range(y_h-y_l):
            coord = np.array([i+x_l,j+y_l])
            coord = np.matmul(rt_mat,coord)
            x,y = coord[0],coord[1]
            if 0<x<=h-1 and 0<y<=w-1:
                # 能映射回才算
                r_img[i,j] = bilinear_interpolation(img,x,y)
    return r_img

缩放

def scale(img,rate):
    # 缩放
    h,w = img.shape
    new_h,new_w = int(rate*h),int(rate*w)
    r_img = np.zeros(shape=(new_h,new_w))
    for i in range(new_h):
        for j in range(new_w):
            r_img[i][j] = bilinear_interpolation(img,i/rate,j/rate)
    return r_img

测试

img = Image.open('lena_512.tif')
img = img.convert('L')
img = np.array(img)
img = img/255.0
r_img = rotate_1(img,30)
plt.imsave('rotate_30.jpg',r_img,cmap='gray')
r_img = scale(img,1.5)
plt.imsave('scale_1.5.jpg',r_img,cmap='gray')
r_img = translate(img, 20,20)
plt.imsave('translate_20_20.jpg',r_img,cmap='gray')

平移
逆时针旋转30度
放大1.5倍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值