比如原图是:
红圈内就是文字水印,经过inpaint后得到图和原图混合,如何处理边界呢,这个代码可以干这事:
越是中心就直接用inpaint图,否则就用原图,这样进行alpha混合。
import numpy as np
import cv2
import pyclipper
from shapely.geometry import Polygon
def expand_polygon_pyclipper(polygon, expand_ratio):
polygon_shape = Polygon(polygon)
distance = (
polygon_shape.area * (np.power(expand_ratio, 2) - 1) / polygon_shape.length
)
subject = [tuple(l) for l in polygon]
padding = pyclipper.PyclipperOffset()
padding.AddPath(subject, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
expanded = padding.Execute(distance)
if expanded == []:
expanded = np.array(expanded)
else:
expanded = np.array(expanded[0]).reshape(-1, 2)
return expanded
def shrink_polygon_pyclipper(polygon, expand_ratio):
polygon_shape = Polygon(polygon)
distance = (
polygon_shape.area * (np.power(expand_ratio, 2) - 1) / polygon_shape.length
)
subject = [tuple(l) for l in polygon]
padding = pyclipper.PyclipperOffset()
padding.AddPath(subject, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
expanded = padding.Execute(-distance)
if expanded == []:
expanded = np.array(expanded)
else:
expanded = np.array(expanded[0]).reshape(-1, 2)
return expanded
# 定义函数
def func(x):
return 0.25 * (np.sin(x - np.pi / 2) + 1)
# 生成0到pi的10个均匀分布的点
x_values = np.linspace(0, np.pi, 11)[1:][::-1]
y_values = func(x_values) + 1
print(f"面积{len(y_values)}", y_values)
x_values = np.linspace(0, np.pi, 13)[1:]
weight_inpaint = func(x_values) * 2
print(f"权重{len(weight_inpaint)}", weight_inpaint)
def draw_heatmap(image, polygons, num_levels=10, initial_color=(255, 0, 0)):
# 计算函数值并加上1
# 搞个和image一样大的二维矩阵
inpaint_image_weights = np.zeros(image.shape[:2], dtype=np.float32)
for i in range(num_levels):
for polygon in polygons:
expanded_polygon = expand_polygon_pyclipper(polygon, y_values[i])
if expanded_polygon.size > 0:
cv2.fillPoly(inpaint_image_weights, [expanded_polygon.astype(np.int32)], weight_inpaint[i])
# 收缩0.95区域用白色填充
for polygon in polygons:
for indx, shk in enumerate([0.99, 0.98]):
expanded_polygon = shrink_polygon_pyclipper(polygon, shk)
if expanded_polygon.size > 0:
cv2.fillPoly(inpaint_image_weights, [expanded_polygon.astype(np.int32)], weight_inpaint[10 + indx])
return inpaint_image_weights
if __name__ == "__main__":
# 示例图像
image = np.ones((200, 200, 3), dtype=np.uint8) * 255
# 示例文本框多边形
text_polys = [
np.array([[50, 50], [150, 50], [150, 100], [50, 100]]),
np.array([[60, 120], [140, 120], [140, 160], [60, 160]])
]
# 生成热力等高线图
inpaint_image_weights = draw_heatmap(image, text_polys, num_levels=10, initial_color=(255, 0, 0))
print(inpaint_image_weights.shape)
# plt显示图
import matplotlib.pyplot as plt
plt.imshow(inpaint_image_weights, cmap='hot', interpolation='nearest')
plt.colorbar()
plt.show()