OpenCV Python实现矩形图像转曲线并保留透明度的技术求助
保持透明度的图像曲线变形解决方案
要实现带透明度的曲线变形,核心是将RGB通道与Alpha通道同步处理,避免变形过程中丢失透明信息。以下是针对你的场景的完整实现:
关键思路
- 将带Alpha通道的叠加图拆分为RGB通道和单独的Alpha通道
- 对RGB通道和Alpha通道应用相同的曲线变形变换
- 合并变形后的RGB与Alpha通道,再与背景图叠加
完整代码
import cv2 import numpy as np def rotate_image_with_alpha(image, angle): """带Alpha通道的图像旋转""" h, w = image.shape[:2] center = (w // 2, h // 2) rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0) cos = np.abs(rotation_matrix[0, 0]) sin = np.abs(rotation_matrix[0, 1]) new_w = int((h * sin) + (w * cos)) new_h = int((h * cos) + (w * sin)) rotation_matrix[0, 2] += (new_w / 2) - center[0] rotation_matrix[1, 2] += (new_h / 2) - center[1] # 对RGB和Alpha通道分别旋转 rgb = cv2.warpAffine(image[:, :, :3], rotation_matrix, (new_w, new_h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0,0,0)) alpha = cv2.warpAffine(image[:, :, 3], rotation_matrix, (new_w, new_h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0) return cv2.merge((rgb, alpha)) def curve_distort_with_alpha(image, curve_strength=0.05): """带Alpha通道的曲线变形(适配背景海报的弧形区域)""" h, w = image.shape[:2] # 创建目标坐标映射 map_x = np.zeros((h, w), dtype=np.float32) map_y = np.zeros((h, w), dtype=np.float32) for y in range(h): # 计算横向偏移,模拟上凸弧形 offset = int(curve_strength * w * np.sin((y / h) * np.pi)) for x in range(w): map_x[y, x] = x + offset map_y[y, x] = y # 对RGB和Alpha通道分别应用变形 rgb = cv2.remap(image[:, :, :3], map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0,0,0)) alpha = cv2.remap(image[:, :, 3], map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0) return cv2.merge((rgb, alpha)) def merge_image(bg, overlay, x, y): """带Alpha通道的图像叠加""" h, w = overlay.shape[:2] # 确保叠加区域在背景范围内 if x + w > bg.shape[1] or y + h > bg.shape[0]: raise ValueError("Overlay exceeds background bounds") # 提取Alpha通道并归一化 alpha = overlay[:, :, 3] / 255.0 alpha_inv = 1.0 - alpha # 逐通道混合 for c in range(3): bg[y:y+h, x:x+w, c] = (alpha * overlay[:, :, c] + alpha_inv * bg[y:y+h, x:x+w, c]).astype(np.uint8) return bg # 主流程 bg = cv2.imread("bg_layer.webp", cv2.IMREAD_UNCHANGED) poster = cv2.imread("7.jpeg", cv2.IMREAD_UNCHANGED) # 1. 调整尺寸 poster = cv2.resize(poster, (500, 700)) # 2. 曲线变形(保持透明度) poster = curve_distort_with_alpha(poster, curve_strength=0.08) # 3. 旋转 poster = rotate_image_with_alpha(poster, -30) # 4. 叠加并显示 result = merge_image(bg, poster, 450, 450) cv2.imshow("Result", result) cv2.waitKey(0) cv2.destroyAllWindows() # 保存结果 cv2.imwrite("final_result.png", result)
代码说明
curve_distort_with_alpha函数:通过创建坐标映射实现弧形变形,分别处理RGB和Alpha通道,确保透明度信息不丢失rotate_image_with_alpha函数:优化了带Alpha通道的旋转逻辑,避免透明区域出现黑边merge_image函数:基于Alpha通道的逐通道混合,保证叠加效果自然
你可以根据背景海报的实际弧度调整curve_strength参数,数值越大弧度越明显。
内容的提问来源于stack exchange,提问作者Rishabh
相关产品推荐
相关产品推荐

