目录
两个多边形 贴图
两个多边形粘贴
两个多边形 贴图
import cv2
import numpy as np
from PIL import Image, ImageDraw
# 给矩形裁剪区域加上圆角
def add_round_corners(image, radius):
mask = Image.new('L', image.size, 0)
draw = ImageDraw.Draw(mask)
draw.rounded_rectangle((0, 0) + image.size, radius=radius, fill=255)
# 将裁剪后的图像添加alpha通道
result = image.copy()
result.putalpha(mask)
return result
# 裁剪旋转矩形
def crop_rotated_rectangle(image, rect_points):
# 获取矩形的宽高
rect_width = int(np.linalg.norm(rect_points[0] - rect_points[1]))
rect_height = int(np.linalg.norm(rect_points[1] - rect_points[2]))
# 定义矩形的目标位置
src_pts = rect_points.astype("float32")
dst_pts = np.array([[0, rect_height - 1], [0, 0], [rect_width - 1, 0], [rect_width - 1, rect_height - 1]], dtype="float32")
# 计算透视变换矩阵并应用变换
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
cropped = cv2.warpPerspective(image, M, (rect_width, rect_height))
return cropped
# 将图像A中的旋转矩形裁剪圆角,并粘贴到图像B的旋转矩形中
def crop_and_paste_rounded_image(image_a, image_b, poly_a, poly_b, radius):
# 多边形A的顶点 (最小外接矩形顶点)
rect_points_a = np.array(poly_a)
# 多边形B的顶点 (最小外接矩形顶点)
rect_points_b = np.array(poly_b)
for point in rect_points_a:
cv2.circle(image_b, point, 5, (0, 0, 255), -1) # 画顶点
for point in rect_points_b:
cv2.circle(image_b, point, 5, (0, 255, 0), -1) # 画顶点
# 裁剪图像A的旋转矩形
cropped_a = crop_rotated_rectangle(image_a, rect_points_a)
# 将裁剪后的图像转换为Pillow格式,并加上圆角
cropped_a_pil = Image.fromarray(cv2.cvtColor(cropped_a, cv2.COLOR_BGR2RGBA))
rounded_a = add_round_corners(cropped_a_pil, radius)
# 将图像A的圆角部分转换为OpenCV图像
rounded_a_cv = cv2.cvtColor(np.array(rounded_a), cv2.COLOR_RGBA2BGRA)
# 获取图像B的旋转矩形的宽高
rect_width_b = int(np.linalg.norm(rect_points_b[0] - rect_points_b[1]))
rect_height_b = int(np.linalg.norm(rect_points_b[1] - rect_points_b[2]))
# 定义图像A的裁剪区域和图像B的目标区域的顶点
src_pts_a = np.array([[0, rect_height_b - 1], [0, 0], [rect_width_b - 1, 0], [rect_width_b - 1, rect_height_b - 1]], dtype="float32")
dst_pts_b = rect_points_b.astype("float32")
# 计算透视变换矩阵并应用
M_b = cv2.getPerspectiveTransform(src_pts_a, dst_pts_b)
transformed_a = cv2.warpPerspective(rounded_a_cv, M_b, (image_b.shape[1], image_b.shape[0]), None, cv2.INTER_LINEAR, borderMode=cv2.BORDER_TRANSPARENT)
# 将变换后的图像A粘贴到图像B
mask = transformed_a[:, :, 3] # alpha通道作为mask
mask_inv = cv2.bitwise_not(mask)
img_b_bg = cv2.bitwise_and(image_b, image_b, mask=mask_inv)
img_a_fg = cv2.bitwise_and(transformed_a, transformed_a, mask=mask)
result = cv2.add(img_b_bg, img_a_fg[:, :, :3])
return result
# 示例使用
image_a_path = r"000.jpg"
image_b_path = r"007.jpg"# 图像B的路径
# 给定的两个多边形顶点 (最小外接矩形)
poly_a = [[590, 268], [581, 331], [712, 365], [744, 263]]
poly_b = [[760, 267], [748, 359], [929, 409], [954, 273]]
radius = 20 # 圆角半径
image_a = cv2.imread(image_a_path)
image_b = cv2.imread(image_b_path)
# 执行裁剪并粘贴操作
result=crop_and_paste_rounded_image(image_a, image_b, poly_a, poly_b, radius)
cv2.imshow('result', result)
cv2.waitKey(0)
两个多边形粘贴
import cv2
import numpy as np
from PIL import Image, ImageDraw
# 给矩形裁剪区域加上圆角
def add_round_corners(image, radius):
mask = Image.new('L', image.size, 0)
draw = ImageDraw.Draw(mask)
draw.rounded_rectangle((0, 0) + image.size, radius=radius, fill=255)
# 将裁剪后的图像添加alpha通道
result = image.copy()
result.putalpha(mask)
return result
# 裁剪旋转矩形
def crop_rotated_rectangle(image, rect_points):
# 获取矩形的宽高
rect_width = int(np.linalg.norm(rect_points[0] - rect_points[1]))
rect_height = int(np.linalg.norm(rect_points[1] - rect_points[2]))
# 定义矩形的目标位置
src_pts = rect_points.astype("float32")
dst_pts = np.array([[0, rect_height - 1], [0, 0], [rect_width - 1, 0], [rect_width - 1, rect_height - 1]],
dtype="float32")
# 计算透视变换矩阵并应用变换
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
cropped = cv2.warpPerspective(image, M, (rect_width, rect_height))
return cropped
# 确保多边形点顺序按顺时针排列
def order_points(pts):
rect = np.zeros((4, 2), dtype="float32")
s = pts.sum(axis=1)
diff = np.diff(pts, axis=1)
# 顺时针:左上 -> 右上 -> 右下 -> 左下
rect[0] = pts[np.argmin(s)] # 左上
rect[2] = pts[np.argmax(s)] # 右下
rect[1] = pts[np.argmin(diff)] # 右上
rect[3] = pts[np.argmax(diff)] # 左下
return rect
# 将图像A中的旋转矩形裁剪圆角,并粘贴到图像B的旋转矩形中
def crop_and_paste_rounded_image(image_a, image_b, poly_a, poly_b, radius):
# 多边形A的顶点 (最小外接矩形顶点),按顺时针排列
rect_points_a = order_points(np.array(poly_a))
# 多边形B的顶点 (最小外接矩形顶点),按顺时针排列
rect_points_b = order_points(np.array(poly_b))
# 裁剪图像A的旋转矩形
cropped_a = crop_rotated_rectangle(image_a, rect_points_a)
# 将裁剪后的图像转换为Pillow格式,并加上圆角
cropped_a_pil = Image.fromarray(cv2.cvtColor(cropped_a, cv2.COLOR_BGR2RGBA))
rounded_a = add_round_corners(cropped_a_pil, radius)
# 将图像A的圆角部分转换为OpenCV图像
rounded_a_cv = cv2.cvtColor(np.array(rounded_a), cv2.COLOR_RGBA2BGRA)
# 定义图像A的裁剪区域的四个顶点 (src_pts_a) 和目标区域 (dst_pts_b) 的顶点
rect_width_a = rounded_a_cv.shape[1]
rect_height_a = rounded_a_cv.shape[0]
# 源点 (从图像A裁剪后的矩形)
src_pts_a = np.array([[0, 0], [rect_width_a - 1, 0], [rect_width_a - 1, rect_height_a - 1], [0, rect_height_a - 1]],
dtype="float32")
# 目标点 (图像B的目标多边形)
dst_pts_b = rect_points_b.astype("float32")
# 计算透视变换矩阵并应用
M_b = cv2.getPerspectiveTransform(src_pts_a, dst_pts_b)
transformed_a = cv2.warpPerspective(rounded_a_cv, M_b, (image_b.shape[1], image_b.shape[0]), None, cv2.INTER_LINEAR,
borderMode=cv2.BORDER_TRANSPARENT)
# 将变换后的图像A粘贴到图像B
mask = transformed_a[:, :, 3] # alpha通道作为mask
mask_inv = cv2.bitwise_not(mask)
img_b_bg = cv2.bitwise_and(image_b, image_b, mask=mask_inv)
img_a_fg = cv2.bitwise_and(transformed_a, transformed_a, mask=mask)
result = cv2.add(img_b_bg, img_a_fg[:, :, :3])
return result
# 示例使用
image_a_path = r"000.jpg"
image_b_path = r"007.jpg" # 图像B的路径
# 给定的两个多边形顶点 (最小外接矩形)
poly_a = [[590, 268], [581, 331], [712, 365], [744, 263]] # 图像A的最小外接矩形顶点
poly_b = [[760, 267], [748, 359], [929, 409], [954, 273]] # 图像B的最小外接矩形顶点
radius = 20 # 圆角半径
image_a = cv2.imread(image_a_path)
image_b = cv2.imread(image_b_path)
# 执行裁剪并粘贴操作
result = crop_and_paste_rounded_image(image_a, image_b, poly_a, poly_b, radius)
cv2.imshow('result', result)
cv2.waitKey(0)