当前位置: 首页 > news >正文

两个多边形 贴图

目录

两个多边形 贴图

两个多边形粘贴


两个多边形 贴图

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粘贴到图像Bmask = transformed_a[:, :, 3]  # alpha通道作为maskmask_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 math
import randomimport cv2
import numpy as np
from PIL import Image, ImageDrawdef 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 rotateddef mask_polygon(image, poly_a):debug=Falsebox1_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_2def 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_sorteddef 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_newreturn 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)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 开源 AI 智能名片 S2B2C 商城小程序与正能量融入对社群归属感的影响
  • Python “函数” ——Python面试100道实战题目练习,巩固知识、检查技术、成功就业
  • 飞睿智能实时雷达活体探测传感器模块,智能家居静止检测实时感知人员有无
  • PHP 面向对象编程
  • 揭秘高效编程工具的选择与使用
  • 揭秘“隐形杀手”:谐波对医院电网的隐形危害
  • STMCubeMx——C8T6的串口调试、接收与发送
  • android和ios双端应用性能的测试工具
  • 丹摩智算平台体验:AI开发从未如此简单
  • 免费制作证件照的小程序源码
  • Python | Leetcode Python题解之第435题无重叠区间
  • 初识C#(一)
  • node-rtsp-stream、jsmpeg.min.js实现rtsp视频在web端播放
  • vue3 通过 axios + jsonp 实现根据公网 ip, 查询天气信息
  • 0基础学习HTML(十七)字符字体
  • 分享的文章《人生如棋》
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • ES6简单总结(搭配简单的讲解和小案例)
  • export和import的用法总结
  • go语言学习初探(一)
  • input实现文字超出省略号功能
  • js ES6 求数组的交集,并集,还有差集
  • JS变量作用域
  • JS函数式编程 数组部分风格 ES6版
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • spring-boot List转Page
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • vue-cli在webpack的配置文件探究
  • 第十八天-企业应用架构模式-基本模式
  • 简单易用的leetcode开发测试工具(npm)
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 聊一聊前端的监控
  • 前端面试题总结
  • 如何编写一个可升级的智能合约
  • 三栏布局总结
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 原生 js 实现移动端 Touch 滑动反弹
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • FaaS 的简单实践
  • 函数计算新功能-----支持C#函数
  • 数据可视化之下发图实践
  • ​Python 3 新特性:类型注解
  • # dbt source dbt source freshness命令详解
  • (04)odoo视图操作
  • (20050108)又读《平凡的世界》
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (a /b)*c的值
  • (java)关于Thread的挂起和恢复
  • (PADS学习)第二章:原理图绘制 第一部分
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (一)基于IDEA的JAVA基础10