import numpy as np
from PIL import Image
import cv2
from utils.face import face_keypoints, draw_points
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
初始化方法
__init__
:def __init__(self, center, mouse, radius):
这个方法初始化
SimpleWarpEffect
类的实例,接受三个参数:center
: 定义扭曲效果的中心点,通常是鼠标按下的点。mouse
: 鼠标释放时的位置,用于确定扭曲的方向和程度。radius
: 扭曲效果的作用半径,定义了扭曲影响范围。
扭曲方法
warp
:def warp(self, x, y, center, mouse, radius):
这是一个辅助方法,用于计算图像中每个点
(x, y)
扭曲后的新位置u, v
。它考虑了点到中心点的距离,并根据这个距离来计算扭曲的程度:- 首先计算点
(x, y)
到中心点(cx, cy)
的距离dis_x_c
。 - 如果这个距离大于作用半径
radius
,则点不会被扭曲,直接返回原始坐标。 - 否则,计算扭曲因子
factor
,这个因子随着距离中心点的距离增加而增加,从而实现越靠近中心点扭曲越大的效果。 - 根据扭曲因子和鼠标点与中心点的相对位置,计算新坐标
u
和v
。
- 首先计算点
魔术方法
__call__
:def __call__(self, img):
这个方法允许类的实例表现得像一个函数,可以通过调用实例来应用扭曲效果。它接受一个参数
img
,即要扭曲的图像:- 获取图像的尺寸
width
和height
。 - 创建图像的一个副本
new_img
,以避免修改原始图像。 - 使用
load
方法加载图像的像素数据,以便可以直接访问和修改。 - 遍历图像的每个像素点,使用
warp
方法计算扭曲后的新坐标。 - 将每个像素点的颜色值从原始图像中取出,并设置到新图像的相应位置。
- 获取图像的尺寸
图像扭曲过程:
- 对于图像中的每个像素点,如果它在扭曲作用的半径内,就根据
warp
方法计算出新位置。 - 如果像素点的新坐标仍然在图像范围内,就从原始图像中取出该位置的像素值,并将其设置到新图像的当前位置。
- 最后返回扭曲后的图像。
- 对于图像中的每个像素点,如果它在扭曲作用的半径内,就根据
这个类实现了一个简单的图像扭曲效果,通过局部地移动像素点来模拟一种向中心点“吸引”的效果。这种效果可以用于图像编辑或特殊视觉效果的创建。使用时,你只需要创建 SimpleWarpEffect
的实例,并传入适当的参数,然后使用这个实例调用要扭曲的图像即可。例如:
# 假设 image 是一个 PIL Image 对象
warp_effect = SimpleWarpEffect(center=(width//2, height//2), mouse=(mouse_x, mouse_y), radius=50)
warped_image = warp_effect(image) # 应用扭曲效果