两个多边形 贴图

目录

[两个多边形 贴图](#两个多边形 贴图)

两个多边形粘贴


两个多边形 贴图

python 复制代码
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)

两个多边形粘贴

python 复制代码
import math
import random

import cv2
import numpy as np
from PIL import Image, ImageDraw

def rotate_image(image, angle):
    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0))
    return rotated

def mask_polygon(image, poly_a):

    debug=False
    box1_x, box1_y, box1_w, box1_h = cv2.boundingRect(np.asarray(poly_a))

    mask = np.zeros(image.shape[:2], dtype=np.uint8)

    # 填充多边形区域为白色 (255),其余区域为黑色 (0)
    cv2.fillPoly(mask, [np.asarray(poly_a)], 255)

    masked_image = np.zeros_like(image)

    masked_image[mask == 255] = image[mask == 255]
    result = masked_image[box1_y:box1_y+box1_h, box1_x:box1_x+box1_w]
    if debug:
        cv2.imshow("debug",result)
        cv2.waitKey(0)
    angle = random.uniform(-15, 15)
    result_2 = rotate_image(result, angle)

    return result_2

def clip_polygon_to_image(poly_a, image_shape):
    h, w = image_shape[:2]  # 获取图像的宽度和高度

    clipped_polygon = []
    for point in poly_a:
        # 限制x和y坐标在图像范围内
        x = min(max(point[0], 0), w - 1)
        y = min(max(point[1], 0), h - 1)
        clipped_polygon.append([x, y])

    return clipped_polygon


# 顺时针排序多边形顶点
def sort_polygon_clockwise(poly_a):
    # 计算多边形的中心点
    center_x = sum([point[0] for point in poly_a]) / len(poly_a)
    center_y = sum([point[1] for point in poly_a]) / len(poly_a)

    # 计算每个点相对于中心点的角度,并按顺时针顺序排序
    def angle_from_center(point):
        return math.atan2(point[1] - center_y, point[0] - center_x)

    # 根据角度进行排序,顺时针排列
    poly_a_sorted = sorted(poly_a, key=angle_from_center, reverse=True)

    return poly_a_sorted

def crop_and_paste_rounded_image(image_a, image_b, poly_a, poly_b):

    poly_a = sort_polygon_clockwise(np.asarray(poly_a))
    # 裁剪多边形到图像范围内
    poly_a = clip_polygon_to_image(poly_a, image_a.shape)

    poly_b = sort_polygon_clockwise(np.asarray(poly_b))
    # 裁剪多边形到图像范围内
    poly_b = clip_polygon_to_image(poly_b, image_a.shape)

    box1_x, box1_y, box1_w, box1_h = cv2.boundingRect(np.asarray(poly_a))
    # 裁剪图像A的旋转矩形
    # cropped_a = image_a[box1_y:box1_y + box1_h, box1_x:box1_x + box1_w].copy()

    rounded_a_cv = mask_polygon(image_a, poly_a)

    # 定义图像A的裁剪区域的四个顶点 (src_pts_a) 和目标区域 (dst_pts_b) 的顶点

    box2_x, box2_y, box2_w, box2_h = cv2.boundingRect(np.asarray(poly_b))

    scale=min(box2_w/box1_w, box2_h/box1_h)

    img_new = cv2.resize(rounded_a_cv, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)

    image_b[box2_y:box2_y+img_new.shape[0], box2_x:box2_x+img_new.shape[1]] = img_new
    return image_b

# 示例使用
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的最小外接矩形顶点

while True:
    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)

    cv2.imshow('image_a', image_a)
    cv2.imshow('result', result)
    cv2.waitKey(0)
相关推荐
一招定胜负15 小时前
基于dlib和OpenCV的人脸替换技术详解
opencv·计算机视觉
历程里程碑15 小时前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
weixin_3954489115 小时前
mult_yolov5_post_copy.c_cursor_0205
c语言·python·yolo
执风挽^15 小时前
Python基础编程题2
开发语言·python·算法·visual studio code
纤纡.15 小时前
PyTorch 入门精讲:从框架选择到 MNIST 手写数字识别实战
人工智能·pytorch·python
kjkdd16 小时前
6.1 核心组件(Agent)
python·ai·语言模型·langchain·ai编程
小镇敲码人16 小时前
剖析CANN框架中Samples仓库:从示例到实战的AI开发指南
c++·人工智能·python·华为·acl·cann
萧鼎16 小时前
Python 包管理的“超音速”革命:全面上手 uv 工具链
开发语言·python·uv
alvin_200516 小时前
python之OpenGL应用(二)Hello Triangle
python·opengl
铁蛋AI编程实战17 小时前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python