import cv2
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
class SimpleWarpEffect:
def init(self, center, mouse, radius):
self.center = center
self.mouse = mouse
self.radius = radius
def warp(self, x, y, center, mouse, radius):
cx, cy = center
mx, my = mouse
dis_x_c = np.sqrt((x - cx) ** 2 + (y - cy) ** 2)
if dis_x_c > radius:
return x, y
factor = ((radius - dis_x_c) / radius) ** 2
u = x - factor * (mx - cx)
v = y - factor * (my - cy)
return u, v
def __call__(self, img):
width, height = img.size
new_img = img.copy()
pixels = new_img.load()
for x in range(width):
for y in range(height):
u, v = self.warp(x, y, self.center, self.mouse, self.radius)
u, v = int(round(u)), int(round(v))
if 0 <= u < width and 0 <= v < height:
pixels[x, y] = img.getpixel((u, v))
return new_img
读取彩色图像
image_path = './img_data/sgirl.png'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
将图像转换为 PIL 图像
pil_image = Image.fromarray(image)
定义扭曲参数
center = (150, 150)
mouse = (200, 150)
radius = 50
应用扭曲效果
effect = SimpleWarpEffect(center, mouse, radius)
warped_image = effect(pil_image)
将结果转换回 NumPy 数组并显示
warped_image_np = np.asarray(warped_image)
显示原始图像和扭曲后的图像
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(image)
plt.subplot(1, 2, 2)
plt.title('Warped Image')
plt.imshow(warped_image_np)
plt.show()
扭曲算法的基本原理:
定义变换区域:确定图像中需要进行扭曲的区域,这通常由用户交互定义,例如通过鼠标点击和拖动来选择。
定义变换中心和控制点:选择一个或多个点作为变换的中心或控制点,这些点的移动将影响周围像素的变形方式。
计算新坐标:对于变换区域内的每个像素点,根据其与变换中心或控制点的相对位置,使用数学公式计算其新坐标。
插值和重采样:由于像素点的新坐标可能是非整数,需要使用插值技术(如最近邻插值、双线性插值等)来确定新位置的像素值。
更新图像:将计算得到的新像素值写回图像,从而实现扭曲效果。
实现扭曲的步骤:
用户定义变换区域:用户通过鼠标操作选择图像的某个区域作为变换区域。
确定变换参数:根据用户的操作,确定变换的中心点、控制点、半径等参数。
遍历像素点:对变换区域内的每个像素点进行遍历。
计算新坐标:使用扭曲算法的数学公式计算每个像素点的新坐标。
应用插值:对于非整数坐标,使用插值技术确定像素值。
更新图像数据:将计算得到的新像素值写回图像。